Repository navigation
Activation 1/3: keyless Vercel→Firebase server credentials and health check - #28
Merged
Merged
Conversation
Vercel has no Application Default Credentials, so every identity-verified API (the six hardened utility/AI handlers and all /api/v2/*) fails closed with 503 in production. firebase-admin's Firestore accepts only certificate or ADC credentials, so federation is delivered through ADC: the per-request Vercel OIDC token is written to a private temp file referenced by an external_account config, and GOOGLE_APPLICATION_CREDENTIALS points at it. Google STS exchanges it and impersonates a least-privilege runtime service account. No key is stored; partial config fails closed. Also adds GET /api/health, disabled unless HEALTH_CHECK_SECRET is set, which probes Auth admin and Firestore and returns only booleans and sanitized codes. No rules, memberships, claims or feature flags are changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017SrzLVR7J3b9nCU177esz8
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Vercel has no Google Application Default Credentials, but
server/security/firebase.jscallsapplicationDefault(). So in production every identity-verified API fails closed with a 503:/api/ai, the five utility APIs, and all/api/v2/*. The redesigned workspace can't load until this is fixed.firebase-admin's Firestore only accepts a service-account certificate or ADC (
firestore-internal.js). A custom credential object would fix Auth but break Firestore. So federation is delivered through ADC.What
server/security/workload-identity.js: whenGCP_WORKLOAD_IDENTITY_PROVIDERandGCP_SERVICE_ACCOUNT_EMAILare set:/tmp/hubcys-wif(0600, atomic) and writes anexternal_accountconfig that references it;GOOGLE_APPLICATION_CREDENTIALSto that config;No key is stored. Partial or malformed config fails closed. It won't override a different operator credential file. With neither variable set, local ADC keeps working unchanged.
server/security/identity.js: refreshes the credential only after a syntactically valid bearer token. If credential preparation fails, the result is a 503, never a 401 and never authenticated.api/health.js:GET /api/healthfor operators.HEALTH_CHECK_SECRET(32+ characters) is set, and requires it in thex-hubcys-health-secretheader (timing-safe compare).docs/v2/vercel-credentials.md: exactgcloudcommands for the pool, provider (restricted toowner:mekado11s-projects:project:hubcys:environment:production), service account (datastore.user+firebaseauth.viewer) and binding; the Vercel OIDC and env settings; and how to verify.Not changed
Rules, indexes, memberships, custom claims and the V2 flags are untouched. No production config is changed by merging this PR.
Verification
npm run test:security: 52/52 (18 new: config parsing, fail-closed cases, file modes, token refresh and precedence, no token in config or output, verifier ordering, health auth/method/sanitization).npm run typecheck:v2,npm run test:v2(68/68), eslint on changed files,npm run build: pass.GoogleAuthloaded the generated config as anIdentityPoolClient, read the token file and reachedsts.googleapis.com. Google rejected it withinvalid_targetonly because the placeholder pool doesn't exist. The code path is proven up to the IAM setup.test:emulator: the rules tests before the browser test all passed. The browser test can't launch here because the Playwright version pinned by this repo needs a Chromium build that isn't installed in this environment. CI installs it and runs the full suite.After merge (owner)
Follow
docs/v2/vercel-credentials.md, redeploy, then confirm/api/healthreturns 200 withworkload_identity,auth_admin.okandfirestore.ok.🤖 Generated with Claude Code
https://claude.ai/code/session_017SrzLVR7J3b9nCU177esz8
Generated by Claude Code