Make Audience ingest keys revealable instead of show-once - #54
Merged
Merged
Conversation
Store the cpk_ plaintext AES-256-GCM-encrypted (lib/sp/vault.ts, SOCIAL_VAULT_KEY) alongside the verification hash, add a revealProjectApiKey server action (project access required, viewers excluded, revoked keys refused), and give each key a Reveal/Hide + Copy control in the Audience UI. Keys minted before the migration have no ciphertext and simply don't get a Reveal button. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
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
The Audience server API keys were show-once ("Copy now — it won't be shown again"), which is hostile UX: lose the value and your only option is revoke + re-mint + redeploy.
What
20260612160000_project_api_keys_ciphertext.sql: addskey_ciphertexttoproject_api_keys.lib/audience/projectKeys.ts): alongside the existing peppered-SHA-256 verification hash, the plaintext is now also stored AES-256-GCM-encrypted under the existing vault key (lib/sp/vault.ts/SOCIAL_VAULT_KEY) — same scheme already used for OAuth tokens. Verification on/api/eventsis unchanged (still hash lookup).revealProjectApiKey: decrypts on demand. Gated onrequireProjectAccess, viewers excluded, revoked keys refused.can_revealboolean server-side.Security notes
SOCIAL_VAULT_KEY(Railway env), hash requiresSP_TOKEN_PEPPER.Test plan
vitest run— 345 passed (new test: minted ciphertext round-trips throughdecryptSecret, and doesn't contain the plaintext)tsc --noEmitclean, oxlint clean🤖 Generated with Claude Code