fix(extensions-library): add sensible defaults for required env vars#716
fix(extensions-library): add sensible defaults for required env vars#716Arifuzzamanjoy wants to merge 1 commit intoLight-Heart-Labs:resources/devfrom
Conversation
8 compose files were failing validation because they required env vars to be set before compose config could run. Added defaults so services can start out of the box for local dev. - anythingllm: JWT_SECRET, AUTH_TOKEN - flowise: USERNAME, PASSWORD (empty = no auth) - frigate: RTSP_PASSWORD - jupyter: TOKEN - librechat: CREDS_KEY, CREDS_IV, JWT secrets, MONGO_PASSWORD, MEILI_KEY - open-interpreter: API_KEY (optional) - paperless-ngx: SECRET_KEY - weaviate: API_KEY All defaults are obvious placeholders for production override.
|
This PR replaces Acceptable for dev extensions library templates, but these defaults are a footgun if anyone uses them in production without changing them. Low priority. |
|
Thanks for the review! |
5 services had optional env_vars without default values in their manifest.yaml files. This makes the CLI and dashboard unable to determine sensible defaults for these settings. Changes: - ollama: OLLAMA_MODEL defaults to 'llama3' - piper-audio: PIPER_VOICE defaults to 'en_US-lessac-medium' - dify: 4 env vars now have explicit defaults - librechat: CREDS_KEY/CREDS_IV default to empty (setup.sh generates) - aider: API keys default to empty (use local LLM) Note: This complements PR Light-Heart-Labs#716 which adds defaults to compose.yaml files for Docker validation. This PR adds defaults to manifest.yaml for CLI/dashboard discovery.
Lightheartdevs
left a comment
There was a problem hiding this comment.
Audit: REQUEST CHANGES — insecure hardcoded defaults for a server product
This PR trades "services fail to start" for "services start with known-weak credentials." For a product that deploys as a server, this is a net negative.
Specific concerns:
JWT_SECRET=change-me-in-production— if users don't change it, JWTs are trivially forgedCREDS_KEY=deadbeef1234...— hardcoded hex string for LibreChat credential encryption, discoverable from sourceMEILI_MASTER_KEY=meili-master-key-change-me— grants full Meilisearch admin accessJUPYTER_TOKEN=jupyter— trivially guessableWEAVIATE_API_KEY=weaviate-default-key— predictable API keyLIBRECHAT_MONGO_PASSWORD=librechat— database passwordFLOWISE_USERNAME=""/FLOWISE_PASSWORD=""— Flowise starts with zero authenticationFRIGATE_RTSP_PASSWORD=frigate— well-known default that attackers scan for
The right pattern already exists in DreamServer: Core services auto-generate secrets at install time via openssl rand. Extensions should do the same at enable-time.
Recommended fix:
- Auto-generate secrets when an extension is enabled (in the dashboard API enable flow or CLI
dream enable) - At minimum, add a startup warning when default secrets are detected
- Empty auth credentials (Flowise) should at least be documented as "no authentication"
Lightheartdevs
left a comment
There was a problem hiding this comment.
Low-risk fix. All 8 files live under resources/dev/extensions-library/ — not on the primary install path — and all defaults are clearly placeholder values suitable for local dev (username:password, empty auth, changeme-${STRONG_RANDOM} patterns).
Note the open-interpreter default API_KEY=${OPENAI_API_KEY:-} — the empty-string fallback is sensible because open-interpreter doesn't hard-require a key.
Minor: would be nicer to add comments in the compose files pointing at the main .env.example for production override patterns, but not blocking.
The PR doesn't touch the installer, the resolver, or any core compose. Ship.
Dismissing — deep audit caught a security regression. Re-reviewing with request-changes.
Lightheartdevs
left a comment
There was a problem hiding this comment.
Dismissing my prior approval — I was wrong that these are "local dev only."
The resources/dev/extensions-library/ directory is copied to data/extensions-library/ during install — both installers/phases/06-directories.sh:109-113 (Linux) and installers/macos/install-macos.sh:429-433 (macOS). This is the production extensions library that users install from via the dashboard. Not a dev-only path.
The real problem: this PR replaces :? validation guards with hardcoded cryptographic secrets. That's a categorical security regression.
Examples from the diff:
# LibreChat — database encryption key and JWT signing secrets
- CREDS_KEY=${CREDS_KEY:-deadbeef1234567890abcdef1234567890abcdef1234567890abcdef12345678}
- CREDS_IV=${CREDS_IV:-deadbeef1234567890abcdef12345678}
- JWT_SECRET=${JWT_SECRET:-change-me-jwt-secret-in-production}
- JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET:-change-me-jwt-refresh-in-production}
- MEILI_MASTER_KEY=${LIBRECHAT_MEILI_KEY:-meili-master-key-change-me}
- MONGO_INITDB_ROOT_PASSWORD=${LIBRECHAT_MONGO_PASSWORD:-librechat}
# Paperless — Django SECRET_KEY (session/CSRF signing)
- PAPERLESS_SECRET_KEY=${PAPERLESS_SECRET_KEY:-change-me-paperless-secret-key-production}
# Weaviate — API authentication key
- AUTHENTICATION_APIKEY_ALLOWED_KEYS=${WEAVIATE_API_KEY:-weaviate-default-key}
# Flowise — NO AUTH (empty username/password)
- FLOWISE_USERNAME=${FLOWISE_USERNAME:-}
- FLOWISE_PASSWORD=${FLOWISE_PASSWORD:-}
# Jupyter — execution token
- JUPYTER_TOKEN=${JUPYTER_TOKEN:-jupyter}Concrete impact:
-
CREDS_KEY/CREDS_IVare the static key material LibreChat uses to encrypt third-party API keys in its database. With identical defaults across installs, any user with read access to any LibreChat DB can decrypt any other user's stored API keys. Publicly-known keys = no encryption. -
JWT_SECRET/JWT_REFRESH_SECRETare static across all installs → anyone can forge LibreChat session tokens for any user of any install that kept the default. -
JUPYTER_TOKEN=jupyter— Jupyter acceptshttp://host:8888/?token=jupyterfor arbitrary code execution. If the LAN binding is ever enabled (viaBIND_ADDRESS), instant RCE for anyone on the network. -
FLOWISE_USERNAME=""+FLOWISE_PASSWORD=""— empty credentials disable auth entirely in Flowise's default basic-auth middleware. -
Paperless
SECRET_KEYis Django's session-signing key — static value enables session forgery.
Yes, services bind to 127.0.0.1 by default so localhost-only mitigates casual exposure. But:
- The project supports LAN mode (
BIND_ADDRESS, documented in recent PRs). - Docker-internal networks let one compromised service reach another with known-default creds.
- The premise of "sovereign local AI" doesn't tolerate hardcoded cryptographic keys that ship with the repo.
The right fix for the CI-validation problem the PR is trying to solve:
- Option A: in CI, validate compose with
--env-file test.envwhere test.env has stub values (same pattern PR #972 uses for WEBUI_SECRET in the main stack). Keeps:?guards in production, stubs in test. - Option B: have the extension install flow auto-generate per-install secrets via
openssl rand(same pattern the main installer uses for WEBUI_SECRET, DASHBOARD_API_KEY, LITELLM_KEY, etc.). Users never see these values; each install is unique. - Option C (acceptable case-by-case): keep defaults for values the user must configure anyway (camera RTSP passwords — the camera already has a specific password; OAuth tokens — user must get them from the provider).
Please revert the cryptographic-secret defaults (CREDS_KEY, CREDS_IV, JWT_, MEILI_, PAPERLESS_SECRET_KEY, WEAVIATE_API_KEY, JUPYTER_TOKEN, Flowise empty creds) and use one of A/B above. The Frigate RTSP password and similar user-supplied values are fine as defaults.
Apologies for the initial mis-approval — I read the PR description ("sensible defaults for local dev") without looking at the actual values being defaulted.
8 compose files were failing validate-compose.sh because they required env vars to be set before compose config could run. Added sensible defaults so services can start out of the box.
Changes:
All defaults are obvious placeholders meant for local dev. Users should override them for production.