Skip to content

security: require secret env vars at startup, remove dev fallbacks - #41

Merged
aspiers merged 3 commits into
mainfrom
remove-dev-secret-fallbacks
Aug 5, 2026
Merged

security: require secret env vars at startup, remove dev fallbacks#41
aspiers merged 3 commits into
mainfrom
remove-dev-secret-fallbacks

Conversation

@aspiers

@aspiers aspiers commented Mar 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace hardcoded 'dev-*-change-me' fallbacks for AUTH_SESSION_SECRET and EPDS_CALLBACK_SECRET with a requireEnv() helper that throws at startup if the variable is missing
  • Remove the same fallback in pds-core/src/index.ts for EPDS_CALLBACK_SECRET
  • Remove the dead csrfSecret config field and unused _secret parameter in csrfProtection() — the middleware uses crypto.randomBytes and ignores it
  • Update all .env.example files with REQUIRED annotations and remove AUTH_CSRF_SECRET

Motivation

If these env vars are not set in production, services previously ran silently with well-known secrets, allowing an attacker to forge session cookies (AUTH_SESSION_SECRET) or HMAC callback signatures (EPDS_CALLBACK_SECRET).

Breaking Change

Services will now refuse to start without AUTH_SESSION_SECRET and EPDS_CALLBACK_SECRET set. Existing deployments that rely on the dev defaults must set these env vars before upgrading.

Generate values with: openssl rand -hex 32

Closes #37

Summary by CodeRabbit

  • Security
    • Required session and ePDS callback secrets are now enforced at startup, preventing services from running with missing or insecure defaults.
    • Removed the unused CSRF secret configuration.
  • Documentation
    • Updated configuration examples and setup guidance to identify required secrets and explain how to generate them.
    • Added clearer startup error guidance for missing environment variables.
  • Maintenance
    • Simplified CSRF protection configuration while preserving existing request validation behavior.

Summary by CodeRabbit

  • New Features
    • Added startup validation for required session and callback secrets.
    • Invalid, empty, or whitespace-only secret values now produce actionable errors.
  • Documentation
    • Updated configuration guidance and setup examples to identify required secrets and explain generation.
    • Removed references to the obsolete CSRF secret.
  • Refactor
    • Simplified CSRF protection configuration by removing the unused secret setting.
  • Tests
    • Added coverage for required environment variable validation and updated authentication tests.

@vercel

vercel Bot commented Mar 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
epds-demo Ready Ready Preview Aug 5, 2026 1:39pm

Request Review

@coderabbitai

coderabbitai Bot commented Mar 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

This change adds shared required-environment validation. Auth-service and pds-core now reject startup when required secrets are missing. The unused CSRF secret configuration is removed from code, setup scripts, examples, and documentation.

Required secret environment variables

Layer / File(s) Summary
Shared required-environment validation
packages/shared/src/require-env.ts, packages/shared/src/index.ts, packages/shared/src/__tests__/require-env.test.ts
Adds and exports requireEnv, with tests for valid, missing, and empty environment variables.
Service startup and CSRF configuration
packages/auth-service/src/..., packages/pds-core/src/index.ts, packages/shared/src/types.ts, packages/shared/src/__tests__/types.test.ts
Requires AUTH_SESSION_SECRET and EPDS_CALLBACK_SECRET at startup. Removes csrfSecret from configuration and the unused middleware parameter.
Configuration and setup alignment
.env.example, packages/auth-service/.env.example, packages/pds-core/.env.example, docs/configuration.md, scripts/setup.sh, .changeset/require-secret-env-vars.md
Documents required secrets and stops generating or documenting AUTH_CSRF_SECRET.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #37 by removing secret fallbacks, adding startup validation, removing unused CSRF configuration, and updating documentation.
Out of Scope Changes check ✅ Passed All code, tests, setup updates, documentation, and configuration changes support the requirements in issue #37.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main security changes: requiring secret environment variables at startup and removing development fallbacks.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch remove-dev-secret-fallbacks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@railway-app

railway-app Bot commented Mar 26, 2026

Copy link
Copy Markdown

🚅 Deployed to the pr-0127fa-41 environment in ePDS

Service Status Web Updated (UTC)
@certified-app/demo untrusted ✅ Success (View Logs) Web Aug 5, 2026 at 2:31 pm
@certified-app/auth-service ✅ Success (View Logs) Web Aug 5, 2026 at 2:30 pm
@certified-app/pds-core ✅ Success (View Logs) Web Aug 5, 2026 at 2:29 pm
@certified-app/demo ✅ Success (View Logs) Web Aug 5, 2026 at 2:29 pm

@sonarqubecloud

Copy link
Copy Markdown

@aspiers
aspiers requested a review from Kzoeps March 26, 2026 21:24
@coveralls-official

coveralls-official Bot commented Mar 26, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 31015296732

Coverage increased (+0.1%) to 58.051%

Details

  • Coverage increased (+0.1%) from the base build.
  • Patch coverage: 2 uncovered changes across 2 files (4 of 6 lines covered, 66.67%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
packages/auth-service/src/index.ts 1 0 0.0%
packages/pds-core/src/index.ts 1 0 0.0%
Total (3 files) 6 4 66.67%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 3110
Covered Lines: 1793
Line Coverage: 57.65%
Relevant Branches: 1939
Covered Branches: 1138
Branch Coverage: 58.69%
Branches in Coverage %: Yes
Coverage Strength: 9.78 hits per line

💛 - Coveralls

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/auth-service/src/index.ts`:
- Around line 124-133: requireEnv currently accepts whitespace-only values
(e.g., "  ") as valid, so update the function requireEnv to reject values that
are empty after trimming: retrieve process.env[name], check if value is
undefined or value.trim().length === 0, and throw the existing Error if so; keep
the same error message but ensure values consisting only of whitespace are
treated as missing. Use the function name requireEnv to locate and modify the
check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: efd7433b-d33c-47c0-9248-b6fa2724a6f4

📥 Commits

Reviewing files that changed from the base of the PR and between b9eb33f and 67e41b4.

📒 Files selected for processing (11)
  • .env.example
  • packages/auth-service/.env.example
  • packages/auth-service/src/__tests__/consent.test.ts
  • packages/auth-service/src/__tests__/csrf.test.ts
  • packages/auth-service/src/context.ts
  • packages/auth-service/src/index.ts
  • packages/auth-service/src/middleware/csrf.ts
  • packages/pds-core/.env.example
  • packages/pds-core/src/index.ts
  • packages/shared/src/__tests__/types.test.ts
  • packages/shared/src/types.ts
💤 Files with no reviewable changes (4)
  • packages/auth-service/src/tests/consent.test.ts
  • packages/auth-service/src/context.ts
  • packages/shared/src/types.ts
  • packages/shared/src/tests/types.test.ts

Comment thread packages/auth-service/src/index.ts Outdated
Replace hardcoded development secret fallbacks with a requireEnv() helper
that throws immediately if AUTH_SESSION_SECRET or EPDS_CALLBACK_SECRET are
missing. This prevents services from silently running with well-known
secrets in production.

Also removes the unused csrfSecret config field and parameter — the CSRF
middleware already uses crypto.randomBytes and ignores it.

Closes #37
@aspiers
aspiers force-pushed the remove-dev-secret-fallbacks branch from 67e41b4 to d4256ea Compare August 4, 2026 22:15
Copilot AI lite review requested due to automatic review settings August 4, 2026 22:15
@changeset-bot

changeset-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 406421e

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens ePDS startup configuration by removing hardcoded development secret fallbacks and making required secrets fail-fast at process startup, while also cleaning up dead CSRF secret configuration.

Changes:

  • Introduces a shared requireEnv() helper and switches auth-service + pds-core to require AUTH_SESSION_SECRET / EPDS_CALLBACK_SECRET at startup (no more dev-*-change-me defaults).
  • Removes the unused CSRF secret config surface (AUTH_CSRF_SECRET, config field, and the unused middleware parameter).
  • Updates example env files, docs, setup script, and adds tests/changeset for the behavior change.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/setup.sh Stops generating / wiring AUTH_CSRF_SECRET in setup output.
packages/shared/src/types.ts Removes dead csrfSecret field from shared config type.
packages/shared/src/require-env.ts Adds requireEnv() helper for required env vars.
packages/shared/src/index.ts Exports requireEnv() from shared barrel.
packages/shared/src/tests/types.test.ts Updates type-shape compile-time test after removing csrfSecret.
packages/shared/src/tests/require-env.test.ts Adds unit tests for requireEnv().
packages/pds-core/src/index.ts Requires EPDS_CALLBACK_SECRET at startup via requireEnv().
packages/pds-core/.env.example Marks EPDS_CALLBACK_SECRET as required in example env.
packages/auth-service/src/middleware/csrf.ts Removes unused _secret parameter from csrfProtection().
packages/auth-service/src/index.ts Requires secrets via requireEnv(); updates CSRF middleware callsite.
packages/auth-service/src/context.ts Removes csrfSecret from auth-service config interface.
packages/auth-service/src/tests/login-page-prompt-login.test.ts Updates test app wiring for new csrfProtection() signature.
packages/auth-service/src/tests/csrf.test.ts Updates CSRF middleware tests for new signature.
packages/auth-service/.env.example Removes AUTH_CSRF_SECRET, clarifies required secrets.
docs/configuration.md Updates AUTH_SESSION_SECRET docs to reflect required startup behavior.
.env.example Removes AUTH_CSRF_SECRET and annotates required secrets.
.changeset/require-secret-env-vars.md Adds operator-facing release note for required secrets and CSRF-secret removal.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/configuration.md
Comment thread packages/shared/src/require-env.ts Outdated
@Kzoeps

Kzoeps commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai please review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

@Kzoeps: I will review pull request #41.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

requireEnv() treated whitespace-only values (e.g. '   ') as present, so
a secret set to blanks would boot with an effectively empty value rather
than failing loudly. Trim before the emptiness check, and mark
EPDS_CALLBACK_SECRET as required in docs/configuration.md — both
pds-core and auth-service call requireEnv() on it and refuse to start
when unset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up to the EPDS_CALLBACK_SECRET required-note change: prettier
re-pads the Shared variables table column after the cell length changed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/shared/src/tests/require-env.test.ts:28

  • The inline comment claims an empty secret would "produce unsigned cookies", but the service would still sign values — just with an empty/predictable secret. This is a misleading security description for why empty/whitespace values must fail fast.
  // An empty value is as dangerous as an absent one — it would silently
  // produce unsigned cookies rather than failing loudly.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

Suppressed comments (1)

.changeset/require-secret-env-vars.md:3

  • The changeset marks this as a patch release, but per docs/PUBLISHING.md's bump-type guide, removing/renaming env vars and changes that require operator action are breaking changes and should not be shipped as a patch. This PR makes AUTH_SESSION_SECRET/EPDS_CALLBACK_SECRET mandatory at startup and removes AUTH_CSRF_SECRET, so the bump should be at least minor (pre-1.0 guidance) rather than patch.
---
'ePDS': patch
---

@aspiers

aspiers commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Closing and immediately reopening to retrigger the Railway preview deploy — no code change intended.

Why

The run (e2e) check is red, but the test suite never executed. It failed in "Wait for all services":

##[group]Demo untrusted (https://certified-appdemo-untrusted-epds-pr-41.up.railway.app)
  attempt 1/30 failed, retrying in 10s...
  ...
  attempt 30/30 failed, retrying in 10s...
##[error]Demo untrusted (...) timed out after 5 minutes

PDS, Auth, and Demo were all reachable on attempt 1. Only demo untrusted never came up, and the job aborted before running a single scenario.

This looks like preview-environment drift rather than anything in this branch:

The branch has been open since March, so the preview environment has most likely been torn down or gone stale, and the deploy check never fired to recreate it. Reopening should provision it again and let the e2e suite actually run.

Reopening momentarily.

@aspiers aspiers closed this Aug 5, 2026
@aspiers aspiers reopened this Aug 5, 2026
@railway-app
railway-app Bot temporarily deployed to ePDS / ePDS-pr-41 August 5, 2026 14:27 Destroyed
@railway-app
railway-app Bot temporarily deployed to ePDS / pr-0127fa-41 August 5, 2026 14:27 Destroyed
@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

@aspiers
aspiers added this pull request to the merge queue Aug 5, 2026
@aspiers
aspiers removed this pull request from the merge queue due to a manual request Aug 5, 2026
@aspiers
aspiers merged commit 9781ef3 into main Aug 5, 2026
35 of 36 checks passed
@aspiers
aspiers deleted the remove-dev-secret-fallbacks branch August 5, 2026 16:57
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.

security: remove hardcoded dev secret fallbacks

3 participants