Skip to content

fix: fail closed on insecure default secrets in cluster entrypoints - #161

Open
alessandro-bitetto wants to merge 1 commit into
Euro-Office:mainfrom
alessandro-bitetto:fix/cluster-entrypoint-secret-defaults
Open

fix: fail closed on insecure default secrets in cluster entrypoints#161
alessandro-bitetto wants to merge 1 commit into
Euro-Office:mainfrom
alessandro-bitetto:fix/cluster-entrypoint-secret-defaults

Conversation

@alessandro-bitetto

Copy link
Copy Markdown

Problem

The orchestrated (cluster/k8s) entrypoints fell back to known upstream placeholder secrets when none were supplied:

  • docker-entrypoint.sh defaulted JWT_SECRET to secret — while JWT is enabled by default (JWT_ENABLED:=true) — and the secure-link secret to verysecretstring.
  • proxy-docker-entrypoint.sh defaulted the same secure-link value, plus the /info basic-auth password to password.

A known JWT secret makes inbox tokens trivially forgeable (the auth boundary for the conversion/download path), and a known secure-link secret defeats the nginx signature protecting cached file URLs. The standalone image already generates and persists random secrets; the cluster entrypoints never got that treatment.

Change

Cluster pods are ephemeral and run as multiple replicas behind a shared proxy, so secrets can't be generated per-pod — they must be supplied explicitly (e.g. via a Kubernetes Secret). This makes the entrypoints fail closed:

  • docker-entrypoint.sh: errors out if JWT (browser/inbox/outbox) is enabled without a corresponding secret, or if SECURE_LINK_SECRET is unset. Also drops the insecure literal defaults from the generated NODE_CONFIG so a known secret can never reach the running config by any path.
  • proxy-docker-entrypoint.sh: same SECURE_LINK_SECRET guard (its value must match the Docs replicas, so a silent default would mismatch), and errors if INFO_ALLOWED_USER is set without INFO_ALLOWED_PASSWORD.

Compatibility impact

This is a deliberate breaking change. Clusters relying on the old defaults must now provide JWT_SECRET, SECURE_LINK_SECRET, and INFO_ALLOWED_PASSWORD (when INFO_ALLOWED_USER is set). Affected containers now fail fast with an actionable message instead of starting with a forgeable/known secret. The standalone image is unaffected.

Verification

  • bash -n passes on both scripts.
  • Guard logic simulated across scenarios: default-on with no secret → fail; JWT disabled → pass; inbox-only enabled with only the inbox secret → pass; all secrets set → pass.

The orchestrated (cluster/k8s) entrypoints fell back to known upstream
placeholder secrets when none were supplied: the Docs entrypoint defaulted
JWT_SECRET to "secret" (with JWT enabled by default) and the secure-link
secret to "verysecretstring", and the proxy entrypoint defaulted the same
secure-link value plus the /info basic-auth password to "password". A
known JWT secret makes inbox tokens trivially forgeable, and a known
secure-link secret defeats the nginx signature on cached file URLs.

Unlike the standalone image, cluster pods are ephemeral and run as multiple
replicas behind a shared proxy, so secrets cannot be generated per-pod and
must be supplied explicitly (e.g. via a Kubernetes Secret). Refuse to start
with the placeholder values when the corresponding feature is enabled, and
drop the insecure literal defaults from the generated config so a known
secret can never reach the running configuration.

This is a deliberate breaking change: clusters relying on the old defaults
must now provide JWT_SECRET, SECURE_LINK_SECRET, and INFO_ALLOWED_PASSWORD
(when INFO_ALLOWED_USER is set).

Signed-off-by: Alessandro Bitetto <alessandro.bitetto@qodesrl.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 📄 To do

Development

Successfully merging this pull request may close these issues.

1 participant