Skip to content

feat(api-keys): reveal API keys behind the super password - #33

Merged
agentHits merged 1 commit into
AgentHits-Devfrom
feat/api-key-reveal
Oct 7, 2026
Merged

agentHits merged 1 commit into
AgentHits-Devfrom
feat/api-key-reveal

Conversation

@agentHits

Copy link
Copy Markdown
Collaborator

Summary

  • better-auth keeps only a hash of each API key, so a key not copied at creation could never be recovered. New keys now also get an encrypted copy (encryptedText, AES-256-GCM) in a new apikey_secret table (migration 0206), kept outside better-auth's apikey table.
  • New user.revealApiKey mutation returns the key to its owner. It requires a browser session and an open super session (even for users without a super password, like Traefik TLS files), is classified dangerous, checks the key's owner and organization, and writes a reveal entry to the audit log.
  • Settings → API/CLI Keys gets an eye button per key. Without an open super session the existing unlock dialog asks for the super password, then the key is shown with a copy button. Keys created before this change have no stored copy, so their button is disabled with an explanation.
  • user.get exposes a revealable flag per key; the new-key dialog text now mentions that the key can be revealed again.

Test plan

  • __test__/users/api-key-reveal.test.ts: reveal works inside a super session and is audited; denied without a super session, for API-key sessions, for other users' keys, for keys of another organization; old keys return a clear NOT_FOUND
  • super-session-procedure-access test lists user.revealApiKey as dangerous
  • tsc --noEmit for apps/dokploy and packages/server, biome check on changed files
  • Full vitest run: only Docker-dependent *.real.test.ts and the load-flaky Telegram alert test failed; the latter passes on its own
  • Manual check on dev after rollout: create a key, reveal it with the super password, confirm the audit entry

🤖 Generated with Claude Code

better-auth stores only a hash of each API key, so a key that was not
copied at creation is lost for good. New keys now also get an encrypted
copy (AES-256-GCM via encryptedText) in a separate apikey_secret table,
and user.revealApiKey returns it to the owner.

Revealing needs a browser session and an open super session, even for
users without a super password, and is never available to API keys.
Each reveal is written to the audit log. Keys created before this change
have no stored copy and show a disabled reveal button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@agentHits
agentHits merged commit 8d93f71 into AgentHits-Dev Oct 7, 2026
8 checks passed
@agentHits
agentHits deleted the feat/api-key-reveal branch October 7, 2026 10:33
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.

1 participant