The security scheme is how your API documentation tells clients — and every code generator that reads it — how to authenticate. Getting it right means the generated SDKs work; getting it wrong means every consumer writes their own auth handling.
Scheme by credential type
| Credential | Scheme | Notes |
|---|---|---|
| JWT or OAuth token | http / bearer with bearerFormat: JWT | The standard |
| Static API key | apiKey in header | Name the header explicitly |
| Key as username | http / basic | Common in payment APIs |
| Machine-to-machine | oauth2 / clientCredentials | Declare the token URL and scopes |
| Federated identity | openIdConnect | Points at the discovery document |
Note that apiKey also permits in: query. Do not use it. A key in a query string is recorded in access logs, proxy logs and browser history — the cURL generator flags the same problem.
Declare it once at the document level
Setting security at the root applies it to every operation, so a new endpoint is authenticated by default rather than by remembering. Override per-operation only where an endpoint is genuinely public:
security:
- BearerAuth: []
paths:
/health:
get:
security: [] # explicitly publicDefaulting to secure and opting out deliberately is safer than the reverse.
Document 401 and 403 separately
They mean different things, and clients must handle them differently:
- 401 — not authenticated. The client should obtain or refresh a credential and may retry.
- 403 — authenticated but not permitted. Retrying with the same credential will never work.
An API that returns 403 for an invalid key is also leaking information: it tells an attacker the key was recognised. Return 401 for anything credential-related.
Postman variable hygiene
Postman collections get shared, exported and committed. Two rules:
- Put the key in an environment variable, not a collection variable. Collection variables are exported with the collection.
- Mark it as a secret type so Postman masks it in the UI and excludes it from exports.
Also worth knowing: Postman syncs to its cloud by default. Anything pasted into a shared workspace has left your machine.
Frequently asked questions
Should I document scopes for a static API key?
Not in the security scheme — the apiKey type has no scope concept. Document what each key type grants in your prose documentation instead, and use the scope builder to reason about the grants themselves.
What is the difference between bearerFormat JWT and openIdConnect?
bearerFormat: JWT is documentation only; it tells a reader the token is a JWT and has no functional effect. openIdConnect points at a discovery document, so tooling can discover endpoints and keys automatically.
Can I have several security schemes?
Yes. An array of alternatives means any one is sufficient; an object with multiple keys means all are required simultaneously — for an API needing both a key and a signature, for example.
Does OpenAPI 3.1 differ from 3.0 for security?
The security scheme objects are essentially unchanged. 3.1 aligns with JSON Schema 2020-12, which matters for request and response schemas rather than for authentication.