Verifying a token
The signing keys, the claims inside a token, and why expiry is not the only thing that ends one.
You do not need any of this to call the API. You need it if you are writing something that accepts an Interlaken token and has to decide, on its own, whether to trust it.
Two signatures
The platform issues tokens signed two ways, and the header tells you which.
RS256 is used by the OAuth server: anything from /oauth/token, including every
API client token. The header carries a kid, and the matching public key is
published, so a third party can verify without holding a secret.
HS256 is used by the console's own session tokens, and is verified with a shared secret that only the platform has.
A verifier must choose its algorithm from the header and then refuse anything else.
Accepting whatever the token claims is the classic algorithm-confusion hole, and
alg: none is rejected outright.
Fetching the keys
curl -s https://api.eu-par-1.interlaken.ai/.well-known/jwks.jsonThe same key set is served at /api/v1/auth/jwks, which is the location the OpenID
Connect discovery document advertises. Match the token's kid against a key in the
set; cache the set and re-fetch when a kid you have not seen turns up, rather than
fetching per request.
The claims
Beyond the standard ones, the claims worth reading are:
| Claim | Meaning |
|---|---|
tenant_id | The workspace this token acts in. Every resource it can reach belongs here. |
scope | Space-separated permission keys. For an API client this is its permission set. |
role | The role the subject holds in that tenant. Absent for API clients. |
typ | What kind of principal this is. |
jti | Token id, used for revocation. |
typ is the one that surprises people. It distinguishes an api_client token from
an idp_session, from an instance token issued to a VM's metadata service, from a
machine token held by a platform component. A service that means to accept only
API clients should check it, not merely check the signature.
Clock skew is forgiven to 30 seconds on expiry.
Revocation
A valid signature and an unexpired exp are not enough. Every zone consults a
revocation list on each verification, keyed by jti and also by subject with a
cutoff time, which is how "sign out everywhere" can end tokens that were never
individually listed.
The practical consequence: a token can stop working before it expires, and it will do
so within one request rather than within an hour. Handle 401 by fetching a new
token, not by assuming your clock is wrong.
Discovery
/.well-known/oauth-authorization-server endpoints, grants, PKCE methods
/.well-known/openid-configuration the same, plus OIDC claims
/.well-known/oauth-protected-resource the resource and its authorization servers
/.well-known/jwks.json the signing keysEach availability zone publishes its own, under its own host. Point a client at the zone it will actually talk to, rather than hard-coding one zone's issuer and using it everywhere: the issuer and the signing keys differ per zone, so a token verified against the wrong zone's key set fails for a reason that looks nothing like the cause.