OAuth vs API Keys: When Static Tokens Are the Right Answer
OAuth is treated as the default for any modern API. For developer tools where the integrator and the operator are the same person, the indirection layer pays back nothing and costs everything.
OAuth has won. Every cloud provider, every major SaaS, every blog post on API security treats OAuth 2.0 with PKCE as the default and anything else as legacy. This is correct for consumer-facing APIs where the user authorizing access and the application operating on their behalf are different parties. It is mostly wrong for developer tools where the integrator and the operator are the same person, and the elaborate consent ceremony pays back nothing while costing everything.
This post is the case for static API keys, when they are the right answer, and what tradeoffs you accept by choosing them. We use API keys across all four Anethoth products because the customer profile genuinely matches the model. If your profile does not match, OAuth wins for good reasons. The honest engineering question is which profile you have, not which industry trend to follow.
What OAuth is actually for
OAuth solves a specific problem: a third-party application wants to act on a user's behalf at a service the user has an account on, and the user wants to grant scoped access without sharing their password. The Slack-app-asks-for-channels-read-permission flow is the canonical case. The user (resource owner) authorizes the application (client) to access their data at the service (resource server) via a token whose scope and lifetime they can revoke independently of their primary credentials.
The architecture has three benefits in this scenario. Scoped permissions let the user grant only what the application needs — a calendar app can read events without seeing email. Independent revocation means revoking a misbehaving app does not require changing the user's password. And the absence of password sharing means the application's compromise does not directly compromise the user's account.
None of these benefits apply when the user installing the application is the developer who built it. If you are integrating CronPing into your own backend service, the elaborate three-party dance reduces to: you, the API client you wrote, and the API server. Scopes are still useful but can be implemented as a property of the API key. Independent revocation is still useful but can be implemented as multiple keys per account. Password sharing is not a concern because there is no third party to share with.
What API keys actually buy
An API key is a long random string the server stores hashed, the client sends as a Bearer token, and the server validates by hash comparison on every request. The simplicity is not an accident — it is the entire value proposition. The integration cost for a customer is one config variable. There is no consent flow, no callback URL, no PKCE state, no token expiration to handle, no refresh logic.
The honest tradeoffs are real. API keys are long-lived secrets, so leaks are more dangerous than short-lived OAuth tokens. The key has all the permissions of the account, so misuse from a compromised key is total. There is no built-in scoping mechanism, so you have to build one if you want it. And the customer has to handle the secret carefully — environment variables, secret managers, never logging it.
For developer tools where the customer is a competent engineering team, these tradeoffs are accepted in exchange for the integration simplicity. Stripe famously uses API keys despite OAuth being available, because the integrator-equals-operator profile matches and the friction reduction is worth the leak risk if customers handle the key correctly. We follow the same pattern across our four products.
The five honest comparison axes
The decision usually comes down to five axes, and OAuth wins on three while API keys win on two.
Token lifetime: OAuth wins. Short-lived access tokens with refresh tokens reduce the blast radius of a leak. API keys are long-lived and a leak compromises the account until revocation.
Scoping: OAuth wins by default. Scopes are first-class. API keys can have scopes but you have to build them, and most implementations ship scopes as an afterthought (or skip them entirely).
Third-party integration: OAuth wins decisively. There is no good way to do third-party integration with API keys without the third party storing customer secrets, which is exactly what OAuth was designed to avoid.
Integration cost for first-party use: API keys win decisively. Sign up, copy key from dashboard, paste into config, done. OAuth requires registering an app, configuring callback URLs, implementing the consent flow, handling token storage and refresh, dealing with grants expiring.
Operational simplicity: API keys win. Hashed storage, constant-time comparison, single auth check per request. OAuth requires JWT verification or token-introspection round trips, refresh-token rotation logic, scope-aware authorization, and the operational complexity of a token issuance service.
The hybrid that often wins
Most APIs that solve this well end up offering both. API keys for the first-party integration case where the customer is the developer, and OAuth for the third-party integration case where one customer's data is being accessed by another company's application.
Stripe does this. Linear does this. GitHub does this. The pattern is to make API keys the default for direct customer integration and OAuth the path for marketplace apps and third-party tools. The customer chooses based on their integration profile rather than being forced into the wrong shape.
We have not yet implemented OAuth at Anethoth because we have not yet seen the third-party integration use case at meaningful volume. Our customer profile is "engineering team integrating our API into their own backend," which is the API-key-wins case. When we see customers building public marketplace apps that other Anethoth customers want to install, we will add OAuth. Until then, the OAuth implementation cost is real engineering time we can spend on the features customers actually want.
The mitigations that make API keys safe enough
If you choose API keys, the mitigations that get them to acceptable security posture are: (1) hash on storage, never store plaintext; (2) prefix the key with an identifiable token (sk_live_) so leaks can be detected by secret scanners; (3) support multiple keys per account so rotation is a non-disruptive operation; (4) record last_used_at per key so you can audit and revoke unused ones; (5) expose key revocation in the dashboard with an immediate effect; (6) consider scope columns from the start even if you do not initially expose them — they are easy to add later if the column exists; (7) rate limit per key so a leaked key cannot be used to drain account quota in seconds.
All four of our products implement most of these. DocuMint, CronPing, FlagBit, and WebhookVault all use prefixed API keys with hashed storage, per-key rate limiting, and revocation in the dashboard. Scopes are a planned addition we have not needed yet. The point is not that API keys are easy — they require their own discipline — but that the discipline they require is smaller than the discipline OAuth requires, and the difference matters when the integration profile does not require OAuth's specific guarantees.
The decision framework
You probably want OAuth if: your customers are non-technical end users, the application installing the integration is a third party rather than the customer themselves, you need fine-grained scope-based permissions, or you operate in a regulatory environment that mandates short-lived tokens.
You probably want API keys if: your customers are engineering teams integrating your API into their own systems, the integration profile is server-to-server rather than user-to-app, the friction of the OAuth flow is a real adoption barrier, or you are a small enough team that the OAuth implementation cost outweighs the marginal security gain over well-implemented API keys.
The right answer is contextual. The wrong answer is to pick OAuth because it sounds modern when your customer profile does not benefit from it, or to pick API keys because they sound simple when your customer profile actually requires the security guarantees OAuth was designed for.