Encrypt OAuth2 tokens and PATs at rest in Firestore#130
Merged
jadeddelta merged 3 commits intoosf-entry-point-integrationfrom Feb 26, 2026
Merged
Encrypt OAuth2 tokens and PATs at rest in Firestore#130jadeddelta merged 3 commits intoosf-entry-point-integrationfrom
jadeddelta merged 3 commits intoosf-entry-point-integrationfrom
Conversation
Add AES-256-GCM encryption for osfToken, authToken, and refreshToken fields stored in Firestore. Tokens are encrypted on write and decrypted on read by Cloud Functions, protecting against database compromise. - Add crypto-utils.ts with encrypt/decrypt using v1:<iv>:<ct>:<tag> format - Add /api/saveosftoken endpoint (validates PAT, encrypts, writes to Firestore) - Add /api/getosftoken endpoint (decrypts and returns token to authenticated owner) - Encrypt tokens in oauth2-callback.ts and refresh-token.ts on write - Decrypt tokens in api-data.ts, api-base64.ts, metadata-block.ts, oauth2-regenerate.ts, and scheduled-token-refresh.ts on read - Move frontend PAT writes from direct Firestore to /api/saveosftoken - Move frontend token reads from direct Firestore to /api/getosftoken - Tighten Firestore rules: remove client OAuth token write permissions - Add migration script for encrypting existing plaintext tokens - Add TOKEN_ENCRYPTION_KEY to CI/CD workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
osfToken,authToken, andrefreshTokenfields stored in Firestore user documents/api/saveosftoken,/api/getosftoken) replace direct Firestore reads/writes from the frontend, keeping the encryption key server-side onlydecrypt()has a plaintext fallback — values not starting withv1:are returned as-is, so existing tokens continue working before migrationPre-deployment checklist
These steps must be completed before merging/deploying:
Generate encryption keys (one per environment):
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Add GitHub Actions secrets:
PROD_TOKEN_ENCRYPTION_KEY— for production deploymentsTEST_TOKEN_ENCRYPTION_KEY— for test deploymentsUpdate local
functions/.env— replace the placeholder000...key with a real 64-char hex key for local developmentDeployment sequence
Order matters — deploy in this sequence:
decrypt()plaintext fallback means existing unencrypted tokens keep working. New writes will be encrypted./api/saveosftokenand/api/getosftokenendpoints are live.isUpdateRefreshToken()andisUpdateAuthToken()client write permissions.Test plan
/api/saveosftoken, create experiment, submit data — full flow worksdecrypt()plaintext fallback — pre-existing plaintext tokens still work before migrationv1:v1:...ciphertext, not plaintext🤖 Generated with Claude Code