ci(staging): wire missing env vars into staging deploy#136
Conversation
…staging Without SIWE_DOMAIN, wallet logins fail on staging (defaults to localhost). Without IDENTITY_JWT_PRIVATE_KEY, the API crashes on startup since staging runs with NODE_ENV=production which requires a persistent signing key. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WalkthroughThe staging deployment workflow is updated to include two new environment variables: SIWE_DOMAIN and IDENTITY_JWT_PRIVATE_KEY, which are sourced from GitHub Actions variables and secrets respectively and written to the .env.staging file for Docker Compose consumption. Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 @.github/workflows/deploy-staging.yml:
- Line 165: The CI currently inserts IDENTITY_JWT_PRIVATE_KEY directly into the
heredoc which assumes the secret is base64-encoded; confirm with your VPS admin
that the GitHub Secret for IDENTITY_JWT_PRIVATE_KEY is stored base64 (see
apps/api/.env.example and jwt-issuer.service.ts which call Buffer.from(pemKey,
'base64').toString('utf8')), or if the secret is intentionally a raw PEM, change
the workflow to append the secret outside the heredoc with proper
quoting/escaping (rather than inline) so the resulting .env.staging keeps
literal newlines intact; update the deploy-staging.yml handling of
IDENTITY_JWT_PRIVATE_KEY accordingly.
| SENDGRID_FROM_EMAIL=${{ vars.SENDGRID_FROM_EMAIL }} | ||
| GOOGLE_CLIENT_ID=${{ vars.GOOGLE_CLIENT_ID }} | ||
| SIWE_DOMAIN=${{ vars.SIWE_DOMAIN }} | ||
| IDENTITY_JWT_PRIVATE_KEY=${{ secrets.IDENTITY_JWT_PRIVATE_KEY }} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
wc -l .github/workflows/deploy-staging.ymlRepository: FSM1/cipher-box
Length of output: 99
🏁 Script executed:
sed -n '150,180p' .github/workflows/deploy-staging.ymlRepository: FSM1/cipher-box
Length of output: 1609
🏁 Script executed:
sed -n '130,170p' .github/workflows/deploy-staging.ymlRepository: FSM1/cipher-box
Length of output: 1911
🏁 Script executed:
rg -i "IDENTITY_JWT_PRIVATE_KEY" --type-list | head -20Repository: FSM1/cipher-box
Length of output: 448
🏁 Script executed:
rg "IDENTITY_JWT_PRIVATE_KEY" -A 2 -B 2Repository: FSM1/cipher-box
Length of output: 4079
🏁 Script executed:
fd -e md -e txt -e yml | xargs grep -l "IDENTITY_JWT" 2>/dev/null | head -10Repository: FSM1/cipher-box
Length of output: 41
🏁 Script executed:
fd README -o SETUP -o "\.env" -o docker-compose | head -5Repository: FSM1/cipher-box
Length of output: 188
🏁 Script executed:
cat README.md 2>/dev/null | grep -A 10 -i "IDENTITY_JWT\|jwt.*key\|secret" | head -30Repository: FSM1/cipher-box
Length of output: 677
🏁 Script executed:
cat README.md 2>/dev/null | head -100Repository: FSM1/cipher-box
Length of output: 3559
🏁 Script executed:
find . -maxdepth 2 -name "*.md" -type f | head -10Repository: FSM1/cipher-box
Length of output: 532
🏁 Script executed:
find . -name ".env*" -o -name "env.example" | head -10Repository: FSM1/cipher-box
Length of output: 195
🏁 Script executed:
rg "base64\|base64.*encode" -A 2 -B 2 --type yml | head -40Repository: FSM1/cipher-box
Length of output: 86
🏁 Script executed:
cat apps/api/src/auth/services/jwt-issuer.service.ts | head -50Repository: FSM1/cipher-box
Length of output: 2203
🏁 Script executed:
cat apps/api/.env.exampleRepository: FSM1/cipher-box
Length of output: 1940
🏁 Script executed:
rg "base64\|decode" apps/api/src/auth --type ts -A 2 -B 2 | head -50Repository: FSM1/cipher-box
Length of output: 41
🏁 Script executed:
find . -name "DEPLOY*" -o -name "setup*" -o -name "install*" | grep -i docRepository: FSM1/cipher-box
Length of output: 41
🏁 Script executed:
cat .github/copilot-instructions.md | grep -A 10 -i "identity\|jwt\|secret" | head -30Repository: FSM1/cipher-box
Length of output: 1311
🏁 Script executed:
find . -path "*/docs/*" -name "*.md" | head -10Repository: FSM1/cipher-box
Length of output: 88
🏁 Script executed:
cat docs/VAULT_EXPORT_FORMAT.md | head -50Repository: FSM1/cipher-box
Length of output: 2460
🏁 Script executed:
find . -type f \( -name "*.yml" -o -name "*.yaml" \) -exec grep -l "IDENTITY_JWT\|base64.*secret" {} \; | head -10Repository: FSM1/cipher-box
Length of output: 97
🏁 Script executed:
git log --oneline --all -S "IDENTITY_JWT_PRIVATE_KEY" | head -20Repository: FSM1/cipher-box
Length of output: 145
Ensure IDENTITY_JWT_PRIVATE_KEY is base64-encoded per documented specification.
The codebase expects this secret to be base64-encoded (see apps/api/.env.example and jwt-issuer.service.ts). The code decodes it with Buffer.from(pemKey, 'base64').toString('utf8').
However, the workflow writes the secret inline within the heredoc without validating the format. If the secret is mistakenly stored as raw PEM with literal newlines instead of base64, the .env.staging file will be malformed. Verify with your VPS admin that the GitHub Secret is stored as base64-encoded per the documented approach — not raw PEM.
If raw PEM encoding is intentional, use Option 2 from the original suggestion (append separately with quoting after the heredoc).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/deploy-staging.yml at line 165, The CI currently inserts
IDENTITY_JWT_PRIVATE_KEY directly into the heredoc which assumes the secret is
base64-encoded; confirm with your VPS admin that the GitHub Secret for
IDENTITY_JWT_PRIVATE_KEY is stored base64 (see apps/api/.env.example and
jwt-issuer.service.ts which call Buffer.from(pemKey,
'base64').toString('utf8')), or if the secret is intentionally a raw PEM, change
the workflow to append the secret outside the heredoc with proper
quoting/escaping (rather than inline) so the resulting .env.staging keeps
literal newlines intact; update the deploy-staging.yml handling of
IDENTITY_JWT_PRIVATE_KEY accordingly.
Summary
SIWE_DOMAINandIDENTITY_JWT_PRIVATE_KEYto the.env.stagingheredoc indeploy-staging.ymlSIWE_DOMAIN, wallet logins fail on staging (defaults tolocalhost)IDENTITY_JWT_PRIVATE_KEY, the API crashes on startup — staging runsNODE_ENV=productionwhich requires a persistent RS256 signing keyBoth GitHub secrets/variables are already set in the
stagingenvironment.Test plan
tag-stagingworkflowIdentity JWKS ready)app-staging.cipherbox.cc🤖 Generated with Claude Code
Summary by CodeRabbit