n4nAI

Bearer tokens explained: authenticating LLM API requests

Bearer tokens explained LLM API auth: definition of the scheme, token flow over HTTP, a real request example, and common mistakes to avoid.

n4n Team5 min read1,112 words

Audio narration

Coming soon — every post will get a voice note here.

A bearer token is an opaque credential string that, when presented in the Authorization header, grants the holder access to a protected HTTP resource without further proof of identity. For LLM APIs, this token is the sole authenticator on every inference call, chat completion, or embedding request. This bearer tokens explained llm api reference breaks down the scheme, shows the exact wire format, and corrects mistakes that leak credentials or cause 401s in production.

What a bearer token is

A bearer token carries no cryptographic binding to the caller. Whoever holds it—“bears” it—gets access until the token expires or is revoked. The OAuth 2.0 framework formalized this in RFC 6750, but the pattern predates OAuth: it is essentially a capability URL reduced to a header value.

In LLM platforms, the token is usually a high-entropy random string (e.g., 32 bytes base64url) issued by the model provider or an inference gateway. It is not a JSON Web Token by default, though some enterprise gateways issue JWTs as bearer tokens. The key property: the server validates the string against its own store or signature, then associates the request with a tenant, rate limit, and billing meter.

Opaque tokens vs JWTs

An opaque token is a random lookup key. The server keeps a table mapping sk-abc123 to a tenant ID and quota. A JWT encodes claims (sub, exp, scope) and is signed so the server can verify without a database round-trip. LLM providers typically use opaque tokens for simplicity; internal gateways may use JWTs to embed routing scope.

How bearer authentication works on the wire

The client sends the token in the Authorization header with the Bearer scheme:

GET /v1/models HTTP/1.1
Host: api.example.com
Authorization: Bearer sk-9f8a7b6c5d4e3f2a1b0c

No other auth fields are required. The server rejects requests missing the header with 401 Unauthorized and a WWW-Authenticate: Bearer challenge.

A minimal curl call to an LLM endpoint looks like:

curl https://api.example.com/v1/chat/completions \
  -H "Authorization: Bearer $LLM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"hi"}]}'

In Python, using requests:

import os
import requests

resp = requests.post(
    "https://api.example.com/v1/chat/completions",
    headers={"Authorization": f"Bearer {os.environ['LLM_TOKEN']}"},
    json={"model": "gpt-4o", "messages": [{"role": "user", "content": "hi"}]},
)
print(resp.json())

And in TypeScript with fetch:

const res = await fetch("https://api.example.com/v1/chat/completions", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.LLM_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ model: "gpt-4o", messages: [{ role: "user", content: "hi" }] }),
});

The token must travel over TLS. Any proxy, log file, or browser history that captures the header can replay it.

Why LLM APIs standardize on bearer tokens

Statelessness is the first reason. The server does not need a session store; it validates the token per request. At the scale of inference fan-out—where a single request may trigger fallback to multiple providers—this matters.

Second, bearer tokens map cleanly to metering. A gateway can attribute per-token usage to the credential without parsing a body. When a provider is rate-limited, the gateway can apply automatic fallback using the same token context.

For example, n4n.ai exposes one OpenAI-compatible endpoint covering 240+ models; it honors client routing directives and forwards provider cache-control hints only after validating the bearer token, tying each call to per-token usage metering. That coupling of auth and routing is impossible with IP allowlists.

Third, rotation is trivial. Issue a new token, revoke the old, done. No coordinated downtime.

Why not Basic Auth?

Basic auth sends base64(user:pass) on every request. The server must store the password (or a hash) and cannot issue a sub-credential with limited scope. Bearer tokens are delegated capabilities: a token can be locked to specific models or spend limits without exposing primary credentials.

A concrete example: authenticating to an OpenAI-compatible gateway

Assume you run a local gateway at http://localhost:4000 that proxies multiple backends. Your token is sk-local-123.

import requests

URL = "http://localhost:4000/v1/chat/completions"
HEADERS = {"Authorization": "Bearer sk-local-123"}

payload = {
    "model": "mistral-7b",
    "messages": [{"role": "user", "content": "Explain bearer auth in one line."}],
}

r = requests.post(URL, headers=HEADERS, json=payload)
if r.status_code == 401:
    raise SystemExit("Bad or missing bearer token")
print(r.json()["choices"][0]["message"]["content"])

If you omit the header, the gateway returns:

{
  "error": {
    "type": "authentication_error",
    "message": "Missing bearer token"
  }
}

This is the entire contract. No nonce, no signature, no timestamp. In this bearer tokens explained llm api context, the token is the only thing standing between a stranger and your GPU bill.

How the server validates the token

On receipt, the server splits the header on the first space. It expects scheme Bearer (case-insensitive) and a non-empty token. Validation steps:

  1. Constant-time compare against a stored hash for opaque tokens.
  2. Or verify signature and claims (exp, iss, aud) for JWTs.
  3. Load tenant policy: rate limit, model allowlist, routing rules.
  4. Reject with 401 before any model inference if any check fails.

Because validation happens before compute, a bad token costs almost nothing. A gateway that skips this order will burn expensive GPU cycles on unauthorized requests.

Common misconceptions

“Bearer tokens and API keys are identical”

They are functionally similar but spec-wise different. An API key might be accepted as a query param (?api_key=) or custom header (X-API-Key). A bearer token strictly uses the Authorization: Bearer header per RFC 6750. LLM providers increasingly reject query-string keys because they leak into logs.

“I can safely embed the token in a URL”

Never. URLs appear in server logs, browser history, and proxy caches. The HTTP spec and OAuth security BCP (RFC 9700) forbid bearer tokens in URLs. Use the header.

“The token expires like a web session”

Many LLM provider tokens are long-lived (months or never). Short-lived tokens require an OAuth2 client-credentials flow to mint new ones. Assuming expiry leads to silent 401s when the token is actually still valid—or worse, assuming permanence leads to a leaked permanent key.

“TLS is optional because the token is secret”

TLS protects the token in transit. Without it, any network observer captures the header. Bearer auth has no built-in replay protection; a captured token works until revoked.

“I should hash the token before sending”

No. The server needs the raw token to compare or verify signature. Hashing client-side breaks validation. Store a hash server-side for lookup, but the wire format is plaintext (over TLS).

“Bearer tokens are encryption”

They are not encrypted on the wire; they are secrets transmitted inside an encrypted channel. The token value itself is plaintext to the server. Treat it like a password.

Token lifecycle and rotation

Issuance: generate ≥256 bits of randomness. Encode as base64url or hex.

Storage: in secret managers (Vault, AWS Secrets Manager) or environment variables. Never in source code or client-side bundles.

Rotation: issue a second token, deploy it, then revoke the first after an overlap window. For OAuth2, use client_credentials to fetch short-lived tokens:

curl -X POST https://auth.example.com/oauth2/token \
  -d "grant_type=client_credentials" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET" \
  -d "scope=llm:inference"
# returns {"access_token":"eyJ...","expires_in":3600}

That access_token is your bearer token for the next hour.

Browser and SPA considerations

Calling an LLM API directly from a browser exposes the token in the JavaScript bundle. Use a backend proxy that injects the Authorization header server-side. If you must issue tokens to a client, use short-lived JWTs with PKCE and refresh rotation—not a permanent provider key.

Security checklist for engineers

  • Read tokens from env or secret store, not .env committed to git.
  • Redact Authorization headers in logging middleware.
  • Use short-lived tokens where the platform supports OAuth2.
  • Rotate on suspicion of leak; revoke immediately.
  • Send only over HTTPS; fail closed on cert errors.
  • Scope tokens to minimal models and spend limits.

Bearer tokens explained llm api auth is fundamentally simple: one header, one secret, per request. The complexity is in storage, rotation, and not leaking it—not in the protocol.

Tagsbearer-tokenauthenticationllm-apidefinition

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All oauth2 & bearer token auth for llm platforms posts →