You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[feature] Self-host: an API key should not be able to mint or revoke API keys #2157
The apiKey plugin runs with enableSessionForAPIKeys (better-auth.ts, L170). Its before-hook turns any request that carries a valid x-api-key header into its owner's session, on every Better Auth endpoint. /api/auth/* goes straight to Better Auth (app.ts), and the account provider hands the raw request headers to Better Auth (getSessionbetter-auth-account-provider.ts, createApiKeyL89-L91).
Reading the code, a request with a key in x-api-key to POST /api/account/api-keys (or POST /api/auth/api-key/create) gets a session and creates a new key for the same user. Listing and revoking keys work the same way. I traced this through the source on current main and @better-auth/api-key 1.6.x; I haven't reproduced it against a running instance.
The result: once a key leaks, revoking that key doesn't contain the leak, because the holder may already have minted others. The only safe response is to revoke every key on the account.
Cloud already draws this line. /account/* accepts only the browser session cookie, "NOT api-key Bearer" (account-api.ts). #2077 applies the same rule to its new /api/access/* routes and refuses any request carrying Authorization or x-api-key.
Proposed shape
On self-host, refuse key management when the caller authenticated with an API key (the x-api-key header, or a Bearer value that resolves only as an API key):
/api/account/api-keys list, create and revoke;
Better Auth's own /api/auth/api-key/* endpoints.
It's worth checking the other account-changing Better Auth endpoints too (password and profile changes, organization invites), since the same key-derived session reaches them.
Why it matters for security
An API key should be able to do what its owner allowed, and not make itself harder to revoke. Keys are handed to agent runtimes precisely because those runtimes are the likeliest place for a credential to leak.
Alternatives
Operators can watch the key list and revoke anything they didn't create, but that's detection after the fact, and it only works if nothing else creates keys on the account.
Activity
RhysSullivan commentedon Oct 8, 2026
We're clearing the backlog ahead of the v2 launch, so we're closing this. If it still applies to v2, please open a new issue or PR against v2.
Sent from my Claude