API security and tokens
Brief Summary
API security is a collection of authentication, authorization, cryptographic protection, anti-abuse, and observability mechanisms that ensures that a request executes an expected entity to an expected resource in an expected context. The key artifact is a token (or request signature) proving the right to call. A good architecture relies on short-lived tokens, clear scopes, minimal privileges, replay protection, rate limiting and operational procedures (rotations, audits, incidents).
API Authentication Models - When and What to Choose
API key (static secret)
Simple for B2B integrations and low-risk scenarios. Does not carry context, requires storage on the service side.
Use only with IP/ASN allow-list, fixed quotas, short TTL and rotations.
OAuth 2. 1 / OIDC
Standard for user and partner integrations: access token (short-term) + refresh token (rotation) + scopes.
Public clients - with PKCE; confidential clients - with client secret/mTLS.
Client Credentials (m2m)
Mashina→mashina: access token for services on strictly defined scopes and audience, often without refresh (get again).
mTLS (mutual TLS)
Binds the identity to the channel. Ideal for high-risk or payment integration (PoP over TLS).
Can be combined with OAuth (tokens only for mTLS clients).
Request Signatures (HMAC/EdDSA)
When you need a transport-independent PoP: signature header, timestamp and nonce. Convenient for webhooks and offline verification.
Token formats and types
JWT (JWS, signed)
Self-sufficient, checked locally; mandatory 'iss', 'sub', 'aud', 'exp', 'iat', 'jti', 'scope'.
Risk - recall more difficult: use short TTL (5-15 min) + list of recalled 'jti' in incidents.
JWE (encrypted JWT)
Needed if payload is sensitive (PII). Cost - higher complexity and overhead.
Reference tokens
Opaque identifiers, checked through introspection by Authorization Server - easier recall/centralization.
PoP/DPoP
Binding a token to a client key or to a TLS session reduces the value of the stolen token.
Token Content: Minimum Sufficient
Recommended stamps (JWT):- 'iss' (issuer), 'sub' (subject), 'aud' (target system/resource), 'exp' (term), 'iat', 'nbf' (optional), 'jti'.
- 'scope '/' permissions' (minimum required), 'tenant' (for multi-tenant), 'device _ compliant '/' amr' (authentication method), 'ip '/' asn' (if applicable to policy).
- Short TTL for access (5-15 min), refresh - 12-48 h (with rotating rotation).
- The audience ('aud') is a strictly specific resource, otherwise the token is "reusable."
- Scopes - action and object (for example, 'payments: withdraw. read`).
- Size - ≤ 2-4 KB for headers and proxies; otherwise there may be problems with gateways.
Authorization and Policies
RBAC + ABAC: role + context (organization, geo, risk, device status).
PEP/PDP Token Validation and Decision on API Gateway/Proxy (Envoy/OPA) prior to application.
Declarative rules: store in Git, pass policy-tests in CI.
rego package policy. withdraw
default allow = false
allow {
input. token. aud == "wallet-api"
input. token. scope[_] == "payments:withdraw. create"
input. device. compliant == true input. risk. score < 70
}
Request Signing (HMAC) and anti-replay
When needed: webhooks, integration without OAuth, double checking critical operations.
Header schema (example):
X-Client-Id: <id>
X-Timestamp: 2025-11-05T13:20:10Z
X-Nonce: 4d1f...a2
X-Signature: base64(HMAC_SHA256(secret, method + "\n" + path + "\n" + sha256(body) + "\n" + timestamp + "\n" + nonce))
Rules:
- Reject requests with time misalignment> ± 300 s.
- Nonce store for 5-15 minutes and do not accept replays (replay cache).
- Sign a canonized query view (method, path, query, body hash).
Identity and transactional protection
Idempotency-Key for write-off/pay-out/create operations: the same key → the same effect.
The key lifetime is the ≥ business timeout time (usually 24-72 hours).
Server-side logic - Compare query parameters to those previously committed for this key.
Browser and mobile clients
PKCE is mandatory (public clients).
Refresh token in the browser - avoid; if necessary - ROTATION + replay response (replay-detection).
Storage: session storage> local storage; better - backend for frontend (BFF) is responsible for tokens.
SameSite, Secure, HttpOnly для cookie; CORS - explicit allow-lists, headers and methods; preflight caching is safe.
m2m and high-risk integrations
mTLS + OAuth2 Client Credentials with scopes and'aud '.
IP/ASN allow-list on the gateway.
PoP/DPoP or HMAC signatures over TLS for critical operations.
Quotas and rate limits per organization/client/key.
Rotations, recalls and incident response
Secret and signature key rotation (JWKS): scheduled + enforced on incident.
Dual-key rollout: publish a new key pair in advance (kid2), sign the tokens for it, keep the old one (kid1) for validation until the TTL is exhausted.
Refresh-rotation: every refresh exchange → a new token, the old one immediately becomes invalid; repeat - compromise signal.
Revocation: for JWT - lists of recalled 'jti' for a short time; for reference tokens - immediate blocking on AS.
Break-glass scripts: temporary static credits with minimal rights and hard TTL, record in the log.
Rate limiting, bot protection and brute force protection
Three-layer limits: per-key/per-IP/per-organization.
Burst + sustained: token-tank/sliding window.
Complex checks: device fingerprint, behavioral signals, geo/ASN anomalies, CAPTCHA only for UI.
Lockout/slowdown when renegotiating signature/NMAC and authentication attempts fail.
Logging, metrics and SLO
The minimum set of logs: 'request _ id', 'client _ id', 'sub', 'aud', 'scope', 'decision', 'reason', 'jti', 'ip', 'asn', 'latency', 'quota _ state'.
Metrics:- Token validation success (%), p95 verification time.
- Frequency of replay deviations, duplicates of Idempotency-Key.
- Percentage of requests with PoP/DPoP/mTLS.
- 'aud/scope'errors, expired'exp', time shifts (NTP).
- Auth/AS ≥ 99 availability. 95 %/month; p95 introspection ≤ 50 мс.
- Zero tokens with TTL <60 s in prod (guard metric).
- Less than 0. 1% of'aud/scope'errors per day (quality of integrations).
Configuration examples
Envoy: JWT and audience check
yaml http_filters:
- name: envoy. filters. http. jwt_authn typed_config:
providers:
as:
issuer: https://auth. example. com/
audiences: ["wallet-api"]
remote_jwks:
http_uri:
uri: https://auth. example. com/.well-known/jwks. json cluster: jwks_cluster cache_duration: 600s rules:
- match: { prefix: "/v1/withdraw" }
requires:
provider_and_audiences:
provider_name: as audiences: ["wallet-api"]
NGINX: mTLS к backend
nginx proxy_ssl_server_name on;
proxy_ssl_name wallet. internal;
proxy_ssl_certificate /etc/nginx/mtls/client. crt;
proxy_ssl_certificate_key /etc/nginx/mtls/client. key;
proxy_ssl_trusted_certificate /etc/nginx/mtls/ca. crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
Example of signature header (webhooks)
X-Signature: t=1730803210,n=ac12...,s=base64(HMAC_SHA256(secret, "POST\n/webhook\nsha256(body)\n1730803210\nac12..."))
The server rejects if 't' is older than 300 c, 'n' has already met, or's' does not beat.
Data protection and privacy
Minimize hallmarks (especially PII) and lifetimes.
Encrypt sensitive stamps (JWEs) for third-party integrations.
Mask/DLP in logs: do not log bodies with PAN/PII, tokens - only 'kid '/flags, not the secret itself.
Common errors
Long-lived access tokens and "eternal" refresh.
Absence of'aud '/' scope '→ tokens are multipurpose.
Signature of webhooks without 'timestamp '/' nonce'.
Checking JWT only in the application, not on the gateway (PEP).
No rotations and dual-key rollout.
"CORS" and allowed insecure methods without header control.
Storing tokens in 'localStorage' without BFF.
Implementation Roadmap
1. API inventory and classification (public/partner/internal, sensitivity).
2. AuthN model selection: OAuth2/OIDC for custom, mTLS + Client Credentials/HMAC for m2m.
3. Tokens: short TTL, strict 'aud', scopes, DPoP/PoP for critical operations.
4. PEP on gateways: JWT validation, signatures and rate limits to the app.
5. Anti-replay and idempotency: timestamp/nonce/Idempotency-Key.
6. Rotations and JWKS: dual-key, automation and alerting.
7. Observability: metrics/SLO, access logs, UEBA signals.
8. Exercises: signature key, refresh leak, quota overload.
Specificity for iGaming/fintech
Payments/payouts: mTLS + PoP/HMAC only, strict scopes ('withdraw. create '), idempotency is required.
Partners (PSP/content providers): per-partner keys/certificates, IP/ASN allow-list, individual quotas and dashboards.
GDPR/PCI DSS: minimizing stamps, prohibiting PII in third-party tokens, logging access to sensitive resources, regular access review.
Anti-abuse: behavioral limits, geo-control, protection against bonus abuse at the API level.
FAQ
JWT or reference token?
JWT - performance and autonomy; reference - centralized feedback and simplicity of incident-response. Often a hybrid: external - JWT, internal - reference.
Is JWE needed?
Only if payload contains PII/secrets. Otherwise - JWS with minimal hallmarks.
Can I live on API keys?
Yes, but only with a short TTL, strict quotas, IP-allow-list and request signing. For users, OAuth/OIDC is preferred.
DPoP/PoP mandatory?
Not always. But for high-risk operations (payments, conclusions) is highly desirable.
Total
Reliable API security is built on short-lived tokens, accurate scopes and audiences, secure channels (TLS/mTLS), request signing and strict anti-replay protection, enhanced by limits and observability. Add automated rotations, dual-key rollout and political control on gateways - and your API will be resistant to leaks, replays and abuse, while maintaining high performance and manageability.