Skip to content

fix(config): require TLS credentials only when TLS_ENABLED is not false#257

Merged
jsugg merged 1 commit into
mainfrom
fix/conditional-tls-credential-validation
Jul 15, 2026
Merged

fix(config): require TLS credentials only when TLS_ENABLED is not false#257
jsugg merged 1 commit into
mainfrom
fix/conditional-tls-credential-validation

Conversation

@jsugg

@jsugg jsugg commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Problem

src/utils/validateEnvVars.js required TLS_KEY and TLS_CERT whenever
NODE_ENV=production, with no TLS_ENABLED condition. src/app.js:14 runs the
validator before startApplication, so it could not be bypassed.

Meanwhile src/server/startApplicationRuntime.js:87-101 already skips
certificate loading and the HTTPS listener entirely when TLS terminates at the
platform edge. The result: production carries two real certificates that are
never read, solely to satisfy a validator that should not be asking.

Reproduced on main before this change:

REJECTED: Config validation error: "TLS_KEY" is required   <- production, TLS_ENABLED=false, no certs
BOOTS                                                      <- production, TLS_ENABLED=false, GARBAGE certs

The second line is the tell: the validator only checks that the strings exist,
never that they are usable. It was buying no safety.

Change

Add TLS_ENABLED to the schema and gate the certificate requirement on it,
mirroring config/index.js:84 (process.env.TLS_ENABLED !== 'false'), so the
validator and the runtime finally agree. The runtime is unchanged — it was
already correct.

TLS_ENABLED is constrained to true/false, matching the existing
API_AUTH_ENABLED convention in the same schema, so a typo like
TLS_ENABLED=disabled fails fast at boot instead of silently enabling TLS.

Verification

NODE_ENV=production TLS_ENABLED=false REPLICATE_API_TOKEN=t ... -> OK
NODE_ENV=production REPLICATE_API_TOKEN=t ...                   -> OK rejected

Both contracts are pinned by unit tests. Six cases added: certs not required
when disabled; required when enabled; required when unset; TLS_CERT required
independently of TLS_KEY; invalid TLS_ENABLED rejected; non-production
unaffected.

Full unit lane 808/808, lint and typecheck clean.

Safety

Additive only. No environment variable is added, removed or changed on the
service by this PR — the live certificates stay exactly where they are and the
service keeps booting whether or not they are present. Retiring them is a
separate, later step that depends on this being live and healthy first.

Production required TLS_KEY and TLS_CERT whenever NODE_ENV=production, with
no TLS_ENABLED condition, even though startApplicationRuntime already skips
certificate loading and the HTTPS listener entirely when TLS terminates at
the platform edge. The service therefore had to carry two real certificates
that are never read, purely to satisfy a validator that should not have been
asking for them.

Add TLS_ENABLED to the schema and gate the certificate requirement on it,
mirroring config/index.js:84 semantics where any value other than 'false'
enables TLS. The runtime already implemented the intended behavior; only the
validator disagreed.

  before: NODE_ENV=production TLS_ENABLED=false, no certs
          -> Config validation error: "TLS_KEY" is required
  after:  -> boots

TLS enabled without certificates still rejects, in production and nowhere
else. Both contracts are pinned by unit tests so they cannot regress.
@jsugg jsugg merged commit b5fca35 into main Jul 15, 2026
18 checks passed
@jsugg jsugg deleted the fix/conditional-tls-credential-validation branch July 15, 2026 07:19
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.

1 participant