API Keys, Tokens, and Credentials - Secure Authentication
Full article
1) Why all this: the threat model for iGaming
Money and PII: key compromise → fraud, leaks, fines.
Network integrations: dozens of external providers, different regions/licenses.
High SLA rates: simple or double payment - reputational and legal risks.
Conclusion: authentication and authorization should be "safe by default," with minimal privileges and strict observability.
2) Tools: What we have in our arsenal
API keys: static client IDs. Easy integration, high risk of leaks.
OAuth2 (Client Credentials): short-lived Bearer tokens with scope/audience.
mTLS: mutual TLS check, strong binding of the client to the channel.
HMAC/EdDSA signatures: cryptographic integrity of the request body and protection against replays (timestamp + nonce).
Proof-of-Possession: MTLS-bound tokens or DPoP (signing HTTP request with client key).
JWT/PASETO: self-describing tokens (preferably with a short TTL).
RBAC/ABAC: role/attribute-basis authorization (OPA/policy decisions).
Delegation/STS: Time and purpose-limited tickets issued for a specific scenario.
3) Basic principles ("stop signs")
1. Least Privilege: each key/token has the lowest possible rights.
2. Short-lived by default: TTL minutes, not days. Rotation is automatic.
3. Bind to channel: binding tokens to mTLS/DPoP is → useless when leaked.
4. Per-brand/region: keys/certificates and permissions - for the brand/license/region.
5. No shared secrets in code: secrets only through Vault/HSM/KMS, nor in Git/logs.
6. WORM audit: unchanging logs of all operations/issues/rotations.
7. Idempotence on write-puts: any repetition with the same key does not change money a second time.
4) When to use what (iGaming context)
5) Design of access tickets (scopes, audience, conditions)
Scope (examples):- `bets:write`, `settlements:write`, `wallet:credit`, `wallet:debit`, `rg:read`, `rg:enforce`, `jackpot:trigger`.
Audience: to whom the token is addressed (for example, 'aud: wallet. api`).
Constraints (fine-grained):- `brand_id`, `region`, `ip/cidr`, `time_of_day`, `rate_limit`, `max_amount`.
- Stored in a token (JWT claims) or in a written "mandate" in Vault/STS.
6) Reference flow
6. 1 RGS ⇄ Platform: RPC Money
1. mTLS handshake (per brand/region certificates).
2. OAuth2 CC: RGS gets' access _ token '(TTL 2-5 min,' aud = wallet. api`, `scope=bets:write settlements:write`).
3. Request'POST/v1/bets/authorize'with headers:- `Authorization: Bearer
`, `X-Idempotency-Key`, `X-Trace-Id`. - 4. Answer + write to WORM audit (who/what/when/where).
- 5. The rotation of the token is seamless, after expiration - CC repeat.
6. 2 Webhooks platform → provider
Heading 'X-Signature: eddsa =
Provider checks: validity window (± 5 min), nonce, body signature.
If unavailable - retray with backoff, dedup by 'event _ id'.
6. 3 Delegation (jackpot service → wallet)
JP calls STS: "give a temporary token on 'wallet: credit' for 'player _ id = p _...', sum ≤ X, TTL 2 min."
STS checks the policy/limits → issues a ticket (narrow token).
JP credits a wallet with this token. It is pointless to compromise such a token: short TTL, narrow rights, binding to mTLS.
7) Query constructs
7. 1 Idempotency (required)
POST /v1/bets/settle
Authorization: Bearer <MTLS-bound>
X-Idempotency-Key: settle_r_8c12_1
X-Trace-Id: tr_a1b2
{
"bet_id":"b_001", "round_id":"r_8c12", "win":{"amount":1460,"currency":"EUR"}
}
→ 200 { "status":"credited", "settlement_id":"st_77" }
(repeat with same key → same answer)
7. 2 Webhook Signature (HMAC)
X-Signature: sha256=BASE64(HMAC(secret, timestamp + "." + nonce + "." + body))
X-Timestamp: 1730000000
X-Nonce: 1f7a...
8) Manage secrets and keys
Vault/HSM/KMS: generation, storage, rotation, recall.
Per-environment: sandbox/prod - different roots of trust.
Per-brand/region: individual keys and certificates.
Auto-rotation: cron/alerts; overlap periods for seamless replacements.
Prohibition in the code/logs: secrets are not written to stdout, they do not get into crash reports.
Device/Workload identity: SPIFFE/SPIRE, K8s ServiceAccount → mTLS without manual secrets.
9) Authorization Policies (RBAC/ABAC) and OPA
RBAC: роли «rgs», «wallet», «jackpot», «reporting».
ABAC: "if'region = EU'and'brand = A' rules → allow'wallet: credit '≤ 10k."
OPA/REGO or analogues: centralized decision-making, policy versioning, dry tests.
10) Observability and audit
End-to-end trace _ id and client _ id in each request/event.
Metrics: p50/p95/p99 latency by endpoints, error-rate by codes ('AUTH _ FAILED', 'SCOPE _ DENIED', 'IDEMPOTENCY _ MISMATCH'), rotation rate, share of expired tokens.
WORM log: token issues/recalls, key changes, policy changes.
Alerts: 'AUTH _ FAILED' spike, geo/ASN anomalies, 'overdue/withdrawn' growth> threshold.
11) Regional residency and segmentation
Tokens/certificates are region-specific (EU/UK/BR/...).
In brands - 'region', platform gateways prohibit cross-regional calls.
Separate KMS and Vault clusters per region; keys do not "drive" between regions.
12) Incidents and Recalls
Compromise playbook: instant key/token revoke, network block/ASN, scope closure.
Kill-switch at gateway level: "no new sessions/funds."
Postmortem: "as it got into the logs/repository," "why the DLP/secret scanner did not work."
13) Checklists
A. For platform
- All write paths: mTLS + OAuth2 CC (TTL ≤ 5 min), 'X-Idempotency-Key', 'X-Trace-Id'.
- Webhooks: HMAC/EdDSA + timestamp + nonce, dedup by 'event _ id'.
- Keistor: Vault/HSM/KMS, rotation and recall, split per brand/region.
- OPA/policies: RBAC/ABAC, change logs, tests.
- WORM audit and SLO dashboards (latency, error, revoke/rotate).
- DR/xaoc teachings: expired tokens, signature spoofing, MITM without mTLS.
B. For provider (RGS/live/JP)
- I do not keep secrets in the code; using Vault/substitution through environment variables.
- Auto-rotation of tokens; handle 401/403 with update.
- Sign webhooks/check validity windows and disposability.
- Audit key activities and respond to Deprecation/Sunset headlines.
- Idempotency on all write calls, dedup by'Idempotency-Key '.
14) Anti-patterns (red flags)
Static API keys without expiry date in sales.
Bearer tokens without binding to the channel (no MTLS/DPoP).
Storing secrets in the Git/CI log/frontend config.
Shared key/certificate for multiple brands/regions.
Webhooks without a signature and a time window → replay.
Lack of centralized feedback and WORM log.
Lack of idempotency → duplicate debits/credits.
15) Mini policy templates (example, human readable)
Ticket 'rgs→wallet' (EU, brand A):- `aud=wallet. api`, `scope=["bets:write","settlements:write"]`
- `constraints: region=EU, brand=A, ip in {asn:…}, max_amount=5000 EUR, ttl=300s`
- `binding: mTLS(cert_hash=sha256:…)`
- 'alg = Ed25519 ', window' ± 30s', 'nonce' unique, grandfather 'event _ id' 24 hours.
Secure authentication in iGaming is a combination of practices: short-lived mandates, channel binding (mTLS/DPoP), narrow scope/audience, strict idempotency, Vault/HSM and WORM auditing, regional segmentation, and observability. Such a stack does not interfere with the speed of integrations, but radically reduces the risk of leaks and financial incidents - money and data remain under control, upgrades are predictable, and compliance is performed out of the box.