← Blog

How to Secure Claude API Endpoints With OAuth

2026-10-28 · 5 min read · SubToAPI Team

If you're searching for "how to secure Claude API endpoints with OAuth," you're almost certainly not trying to add OAuth to Anthropic's own API — Claude's API authenticates with a static API key in the x-api-key header, and that isn't going to change per-request. What you actually need to secure is the layer you build on top of Claude: the backend endpoints your web app, mobile app, or partner integrations call before your server talks to Claude. That's where OAuth belongs, and that's what this guide covers.

The short answer: put an OAuth 2.0-protected gateway in front of your Claude integration. Your users or client apps authenticate with OAuth (authorization code + PKCE for user-facing apps, client credentials for service-to-service), your server validates the access token, checks scopes and rate limits, and only then forwards a request to Claude using a server-side key that the client never sees. The rest of this article shows how to build that correctly.

Why OAuth sits on top of, not inside, the Claude API

Anthropic's API has no OAuth endpoints, no token exchange, no refresh tokens. It's a straightforward bearer-key model. That's fine for server-to-server calls, but it's dangerous to expose directly to browsers, mobile clients, or third-party partners, because anyone with the key can run unlimited requests on your account.

OAuth solves a different problem than Claude's API key does:

Confusing these two layers is the most common mistake teams make. Never hand out your Anthropic (or SubToAPI) key to a frontend, mobile app, or external partner. Issue OAuth tokens instead, and keep the model key server-side only.

The architecture pattern

Client (web/mobile/partner)
   → OAuth access token
Your API Gateway / BFF
   → validates token, checks scope, applies rate limits
   → calls Claude (or SubToAPI) with server-side key
Claude API / SubToAPI

Your gateway is the trust boundary. It's the only thing holding the real model-provider key, whether that's Anthropic's raw API or a managed layer like SubToAPI that exposes Claude as a clean HTTPS API with its own sub_live_... application keys. Either way, OAuth governs who's allowed to reach your gateway — not who's allowed to reach Claude directly.

Choosing the right OAuth flow

Most teams wrapping Claude in a product end up running both: authorization code for their own app's users, client credentials for API partners.

Validating tokens on your Claude-facing endpoints

Every endpoint that triggers a Claude call should validate the OAuth token before doing anything else. A minimal middleware pattern:

async function requireOAuth(req, res, next) {
  const token = (req.headers.authorization || '').replace('Bearer ', '');
  if (!token) return res.status(401).json({ error: 'missing_token' });

  const claims = await verifyAccessToken(token); // JWT verify or introspection call
  if (!claims) return res.status(401).json({ error: 'invalid_token' });

  if (!claims.scope?.includes('claude:invoke')) {
    return res.status(403).json({ error: 'insufficient_scope' });
  }

  req.client = claims.sub;
  next();
}

app.post('/chat', requireOAuth, async (req, res) => {
  const response = await callClaude(req.body.messages, req.client);
  res.json(response);
});

Two details matter here:

  1. Scope your tokens narrowly. A claude:invoke scope that only allows calling your chat endpoint is safer than a generic api:all scope.
  2. Short-lived access tokens with refresh tokens. 15–60 minute access tokens limit the damage if one leaks, since the refresh token (which should be stored more securely) is needed to get a new one.

Rate limiting and per-client quotas

OAuth gives you an identity (client_id or sub) to key your rate limits on. Enforce limits per client, not just globally — one noisy or compromised client shouldn't be able to exhaust your Claude quota for everyone else:

const limiter = rateLimit({
  keyGenerator: (req) => req.client,
  windowMs: 60_000,
  max: 30, // requests per client per minute
});

If you're routing Claude traffic through a managed API layer like SubToAPI, you get usage metadata per application key out of the box, which pairs well with OAuth-scoped client identities — your OAuth layer controls who can call the endpoint, and the underlying key's dashboard tells you how much they're actually using. See /docs for how usage and streaming are exposed.

Protecting the key behind the gateway

OAuth protects the front door; you still need to protect the Claude key itself:

Putting it together

A secure setup looks like: OAuth 2.0 authorization code or client credentials flow issuing short-lived, narrowly scoped access tokens → middleware validating those tokens and enforcing per-client rate limits → a server-side call to Claude (directly or via a managed layer) using a key that never leaves your infrastructure. Each layer does one job. Mixing them — for example, trying to use an Anthropic API key as if it were an OAuth token, or skipping scopes because "it's just internal" — is where most incidents start.

If you want the Claude-calling layer itself handled for you — streaming, tool use, and per-application keys with a dashboard — start with /signup and sit your own OAuth gateway in front of it; see /docs/quickstart for the request format.

Questions

Does Anthropic's Claude API support OAuth natively? No. Claude's API authenticates with a static API key sent in a header. OAuth is something you add in your own backend layer to control which users or client apps can reach the endpoints that call Claude.

Where should I store the Claude API key if I'm using OAuth for my endpoints? Server-side only, in a secrets manager, never exposed to any client. OAuth tokens authenticate callers to your gateway; the gateway alone holds the Claude key and makes the outbound call.

Should every client get the same OAuth scope? No. Scope tokens to the minimum action needed, such as claude:invoke, and tie rate limits to the client identity in the token so one integration can't consume another's quota.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →