Skip to main content

Token Revocation

ChainIT implements OAuth 2.0 Token Revocation as defined by RFC 7009. The endpoint accepts both access tokens and refresh tokens and invalidates them immediately so they can no longer be used to access resources or mint new tokens.

When to use revocation vs logout
  • Revoke when you want to invalidate a single token (e.g. a compromised refresh token, an expiring CI token, a per-device session). - Logout when you want to end a user's interactive session — revoke their refresh token chain, blacklist their access token, and clear local state. Use RP-Initiated Logout for that flow.

Endpoint

POST https://staging-api.chainit.online/oauth/revoke

Content-Type: application/x-www-form-urlencoded or application/json.

The exact URL is advertised by the server metadata document as revocation_endpoint.


Request

ParameterRequiredDescription
tokenThe token to revoke. Can be an access token or a refresh token.
client_idOAuth client ID. Must own the token being revoked.
token_type_hintaccess_token or refresh_token. Optimisation only; the server will still locate the token if the hint is wrong.

Confidential clients must also authenticate using one of the methods advertised in revocation_endpoint_auth_methods_supported (typically client_secret_post — send client_secret in the body — or client_secret_basic — HTTP Basic auth). Public clients omit the secret.

Example

POST /oauth/revoke
Content-Type: application/json

{
"token": "eyJhbGciOiJSUzI1NiI...",
"client_id": "<<your_client_id>>",
"token_type_hint": "access_token"
}

Response

{
"success": true,
"message": "Token revoked successfully"
}
FieldTypeDescription
successbooleantrue when the token was successfully revoked (or already expired / unknown — see RFC).
messagestringHuman-readable status string suitable for logging.

Per RFC 7009, presenting an unknown, expired, or already-revoked token still returns 200 OK. This prevents enumeration attacks: clients cannot probe the server to learn which tokens are or were valid.


What actually happens server-side

Token typeEffect
Access token (JWT)Token jti (and its session group) is added to a Redis-backed blacklist until the token's natural expiry. Subsequent requests presenting it are rejected by the access guard.
Refresh token (opaque)The token row is marked revoked and its rotation chain (the original refresh token plus every rotation descendant) is invalidated. Re-use of any chain member triggers detection.

ID tokens carry no server-side state and cannot be "revoked" — they remain syntactically valid until exp. To force ID-token unusability, use RP-Initiated Logout which both revokes the session and blacklists the access token.


Sample integration

curl

curl -X POST "https://staging-api.chainit.online/oauth/revoke" \
-H "Content-Type: application/json" \
-d '{
"token": "<<your_refresh_token>>",
"client_id": "<<your_client_id>>",
"token_type_hint": "refresh_token"
}'

Node.js

import axios from "axios";

await axios.post("https://staging-api.chainit.online/oauth/revoke", {
token: refreshToken,
client_id: process.env.CLIENT_ID,
token_type_hint: "refresh_token",
});

Python

import requests

requests.post(
"https://staging-api.chainit.online/oauth/revoke",
json={
"token": refresh_token,
"client_id": CLIENT_ID,
"token_type_hint": "refresh_token",
},
auth=(CLIENT_ID, CLIENT_SECRET), # client_secret_basic
)

Errors

HTTPCodeReason
400invalid_requesttoken or client_id missing.
401invalid_clientConfidential client failed authentication.
401unauthorized_clientToken does not belong to the calling client_id.
200unsupported_token_type (in body)Server understood the request but cannot revoke that specific token type.

Security considerations

  • Always revoke refresh tokens on the server side — never trust a public-client front-end to do it on its own. Public clients can revoke as a best effort, but a confidential backend should also revoke when a session ends.
  • After revoking a refresh token, also call logout (or revoke the access token directly) if the user is on an interactive session — the access token remains usable until its natural expiry otherwise.
  • Reuse-detection: if a previously-rotated refresh token is presented again after revocation, the entire chain is blacklisted defensively. Clients must store only the most recently issued refresh token.

Next steps

Related references