Skip to content

fix(extensions-library): add sensible defaults for required env vars#716

Open
Arifuzzamanjoy wants to merge 1 commit intoLight-Heart-Labs:resources/devfrom
Arifuzzamanjoy:fix/compose-env-defaults
Open

fix(extensions-library): add sensible defaults for required env vars#716
Arifuzzamanjoy wants to merge 1 commit intoLight-Heart-Labs:resources/devfrom
Arifuzzamanjoy:fix/compose-env-defaults

Conversation

@Arifuzzamanjoy
Copy link
Copy Markdown
Contributor

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:

  • anythingllm: JWT_SECRET, AUTH_TOKEN
  • flowise: USERNAME, PASSWORD (empty = no auth for local dev)
  • 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 meant for local dev. Users should override them for production.

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.
@Lightheartdevs
Copy link
Copy Markdown
Collaborator

This PR replaces :? fail-if-unset with :-default across 8 extension library compose files. Trades safety for convenience — JWT secrets, DB passwords, and API keys get well-known defaults like change-me-jwt-secret-in-production.

Acceptable for dev extensions library templates, but these defaults are a footgun if anyone uses them in production without changing them. Low priority.

@Arifuzzamanjoy
Copy link
Copy Markdown
Contributor Author

Thanks for the review!
I'm agreed on the tradeoff and happy to merge whenever convenient or batch with other cleanup.

Arifuzzamanjoy added a commit to Arifuzzamanjoy/DreamServer that referenced this pull request Apr 4, 2026
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.
Copy link
Copy Markdown
Collaborator

@Lightheartdevs Lightheartdevs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 forged
  • CREDS_KEY=deadbeef1234... — hardcoded hex string for LibreChat credential encryption, discoverable from source
  • MEILI_MASTER_KEY=meili-master-key-change-me — grants full Meilisearch admin access
  • JUPYTER_TOKEN=jupyter — trivially guessable
  • WEAVIATE_API_KEY=weaviate-default-key — predictable API key
  • LIBRECHAT_MONGO_PASSWORD=librechat — database password
  • FLOWISE_USERNAME="" / FLOWISE_PASSWORD="" — Flowise starts with zero authentication
  • FRIGATE_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:

  1. Auto-generate secrets when an extension is enabled (in the dashboard API enable flow or CLI dream enable)
  2. At minimum, add a startup warning when default secrets are detected
  3. Empty auth credentials (Flowise) should at least be documented as "no authentication"

Lightheartdevs
Lightheartdevs previously approved these changes Apr 18, 2026
Copy link
Copy Markdown
Collaborator

@Lightheartdevs Lightheartdevs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Lightheartdevs Lightheartdevs dismissed their stale review April 18, 2026 14:50

Dismissing — deep audit caught a security regression. Re-reviewing with request-changes.

Copy link
Copy Markdown
Collaborator

@Lightheartdevs Lightheartdevs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. CREDS_KEY / CREDS_IV are 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.

  2. JWT_SECRET / JWT_REFRESH_SECRET are static across all installs → anyone can forge LibreChat session tokens for any user of any install that kept the default.

  3. JUPYTER_TOKEN=jupyter — Jupyter accepts http://host:8888/?token=jupyter for arbitrary code execution. If the LAN binding is ever enabled (via BIND_ADDRESS), instant RCE for anyone on the network.

  4. FLOWISE_USERNAME="" + FLOWISE_PASSWORD="" — empty credentials disable auth entirely in Flowise's default basic-auth middleware.

  5. Paperless SECRET_KEY is 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.env where 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants