Stap 1 — Registreer uw public key (eenmalige setup)
Genereer een 4096-bits RSA-keypair en deel de public key met Zonos. Dit gebeurt eenmalig tijdens onboarding.
Genereer het keypair
# Generate private keyopenssl genrsa -out private_key.pem 4096 # Extract public keyopenssl rsa -in private_key.pem -pubout -out public_key.pemDeel public_key.pem met Zonos. Bewaar private_key.pem in een dedicated secrets manager (AWS Secrets Manager, HashiCorp Vault, enz.) — nooit in source control of environment variables.
Zonos registreert uw key en retourneert uw Organization ID, die de iss-claim wordt in alle JWT-asserties.
Stap 2 — Bouw een JWT-assertie
Teken een JWT met RS256 met uw private key. De assertie is geldig voor één token-uitwisseling — houd het expiry-venster kort (60–300 seconden).
Vereiste claims
| Claim↕ | Waarde↕ |
|---|---|
iss | Uw Zonos Organization ID (bijv. "org_abc123") |
sub | Identificeert de aanroepende service (bijv. "checkout-service") |
aud | Moet exact "zonos-auth" zijn |
exp | Unix-timestamp; 60–300 seconden na iat |
iat | Unix-timestamp van uitgifte |
jti | Unieke UUID per assertie (maakt replay-detectie mogelijk) |
De JWT-header moet "alg": "RS256" en "typ": "JWT" specificeren.
Codevoorbeelden
import jwt, uuid, time with open("private_key.pem") as f: private_key = f.read() now = int(time.time())assertion = jwt.encode( { "iss": "org_abc123", "sub": "checkout-service", "aud": "zonos-auth", "iat": now, "exp": now + 300, "jti": str(uuid.uuid4()), }, private_key, algorithm="RS256",)Stap 3 — Wissel de assertie in voor een access token
Stuur de getekende JWT naar het Zonos token-eindpunt om een kortlevende Bearer token te ontvangen.
Eindpunt
POST https://auth.zonos.com/oauth/token
Content-Type: application/json
application/x-www-form-urlencoded wordt ook geaccepteerd.
Requestvelden
| Veld↕ | Vereist↕ | Waarde↕ |
|---|---|---|
grant_type | Yes | "urn:ietf:params:oauth:grant-type:jwt-bearer" |
assertion | Yes | Uw getekende JWT (compact serialization) |
Request en response
{ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}| Responseveld↕ | Beschrijving↕ |
|---|---|
access_token | Bearer token voor alle volgende API-verzoeken |
token_type | Altijd "Bearer" |
expires_in | Seconden tot expiry (standaard: 300) |
scope | Spatie-gescheiden permissies voor deze token |
Volledige codevoorbeelden
import requests response = requests.post( "https://auth.zonos.com/oauth/token", json={ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": assertion, },)data = response.json()access_token = data["access_token"]expires_in = data["expires_in"]Stap 4 — Roep Zonos API's aan met de access token
Neem de access token op als Bearer token in de Authorization-header bij elk Zonos API-verzoek.
Voorbeeldrequest
curl -X POST https://api.zonos.com/graphql \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "query": "{ ... }" }'Tokenlevenscyclus en caching
Access tokens verlopen standaard na 5 minuten. Cache de token en vernieuw proactief — vraag niet bij elke API-aanroep een nieuwe token aan. Elke vernieuwing vereist een nieuw getekende JWT-assertie.
import time, requests _cache = {"access_token": None, "expires_at": 0} def get_access_token(): if time.time() < _cache["expires_at"] - 30: return _cache["access_token"] assertion = build_jwt_assertion() data = requests.post( "https://auth.zonos.com/oauth/token", json={ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": assertion, }, ).json() _cache["access_token"] = data["access_token"] _cache["expires_at"] = time.time() + data["expires_in"] return _cache["access_token"]Foutreferentie
Alle fouten volgen het OAuth 2.0 error response-formaat (RFC 6749 §5.2):
{ "error": "invalid_grant", "error_description": "JWT assertion has expired"}| HTTP-status↕ | error↕ | Oorzaak↕ |
|---|---|---|
400 | unsupported_grant_type | grant_type was not urn:ietf:params:oauth:grant-type:jwt-bearer |
400 | invalid_request | Ontbrekend of ongeldig veld |
401 | invalid_grant | Ongeldige handtekening, verlopen assertie, onbekende org of niet-geregistreerde key |
500 | server_error | Interne fout — neem contact op met Zonos support als het aanhoudt |
Veelvoorkomende invalid_grant-oorzaken:
expligt in het verleden — zorg dat uw systeemklok NTP-gesynchroniseerd isaudis niet exact"zonos-auth"isskomt niet overeen met uw geregistreerde Organization ID- Public key is geroteerd maar nog niet bijgewerkt bij Zonos
Security best practices
- Bescherm uw private key. Bewaar deze in een dedicated secrets manager — nooit in source control, environment variables of logs.
- Houd asserties kortlevend. 60–300 seconden is standaard; er is geen reden om langere uit te geven.
- Neem
jtiop. Een unieke waarde per assertie maakt server-side replay-detectie mogelijk. - Roteer keypairs periodiek. Registreer een nieuwe public key bij Zonos voordat u de oude intrekt om downtime te voorkomen.
- Log nooit
access_token- ofassertion-waarden. Behandel beide als credentials.
OAuth 2.0-authenticatie
Authenticeer uw backend-services bij Zonos met asymmetrische sleutelcryptografie — zonder gedeelde secrets.Zonos ondersteunt machine-to-machine-authenticatie via OAuth 2.0 JWT Bearer Token Grant (RFC 7523). Your service signs a short-lived JWT with your RSA private key; Zonos verifies it using your registered public key and returns a Bearer token scoped to your organization.
Flow-samenvatting:
Authorization: Bearer <token>bij elk API-verzoek.