Revocation

How to permanently invalidate an API token.

Revocation permanently invalidates an API token by setting its valid field to 0 in the database. After that happens, the verification process rejects the key, and the token can no longer be used for machine-to-machine access.

The IAM service keeps revoked token rows instead of deleting them during the standard revoke flow. This gives you a stable way to disable leaked, rotated, or no longer needed tokens while preserving their metadata for later auditing.

The direct library function revokeApiKey is idempotent. If the provided token is already invalid, missing, or does not pass verification, it still returns a success payload. The route behaves differently, because it only looks up currently valid tokens before dispatching the revocation.

Revocation is permanent. Revoked tokens cannot be reactivated. Create a new token if you need replacement access.

You can revoke a token in 3 ways:

  • Directly calling revokeApiKey.
  • Using the privateActionManager to validate ownership before revoking.
  • Calling the POST /api/manage/revoke endpoint from an authenticated client.
Follow the Creating Tokens docs to create a token first before attempting to revoke it.

Revoking Tokens

You can revoke tokens either directly in the library or through the route. The direct helper focuses on the token itself, while the route adds ownership validation and authenticated client protections.

Using the library

To revoke a token directly, you call revokeApiKey. This function hashes the provided token when needed, verifies it against the stored privilege, and then marks the token as invalid.

example.ts
import { revokeApiKey } from '@riavzon/auth'

const token = 'api_1234'
const privilege = 'restricted'

const results = await revokeApiKey(token, privilege)

if (!results.ok) {
    console.error(results.reason)
}

On success you can get back one of two payloads. When the token is valid and the privilege matches, the response contains the revoked token id and user id:

{
    ok: true,
    date: new Date().toISOString(),
    data: {
        msg: 'Token invalided successfully',
        invalidedTokenId: 12,
        userId: 42
    }
}

If the token is already invalid, missing, or does not pass verification, the function still returns ok: true with a string payload:

{
    ok: true,
    date: new Date().toISOString(),
    data: 'Token invalided successfully'
}

On error, such as a database failure, you get:

{
    ok: false,
    date: new Date().toISOString(),
    reason: 'Error invalidating token'
}

Signature

The direct helper exposes the following signature:

export async function revokeApiKey(
    rawKey: string,
    providedPrivilege: 'demo' | 'restricted' | 'protected' | 'full' | 'custom',
): Promise<Results<{msg: string, invalidedTokenId: number, userId: number} | string>>

Parameters

FieldTypeDescription
rawKeystringThe token to be revoked. It can be hashed or Raw.
providedPrivilege'demo' | 'restricted' | 'protected' | 'full' | 'custom'The privilege assigned to the token you want to revoke.
This action should be performed by a fully authenticated client.
This function does not require the publicIdentifier, and it bypasses IP restriction checks and usage counter updates during its internal verification step. Only call it directly in trusted server-side code.

With the privateActionManager

The safest internal method is using the privateActionManager. This function checks the publicIdentifier, token id, token name, user id, and current valid status before dispatching the revocation.

example.ts
const revokeRes = await privateActionManager(userId, tokenId, publicIdentifier, tokenName, {
  action: 'revoke'
})

The privateActionManager returns the response of revokeApiKey directly. Learn more at the introduction page.

The manager only selects rows where valid = 1. Because of that, manager-based revocation does not behave like the direct revokeApiKey call when the token is already revoked.

Using the route

Let's say you want to revoke a token from your authenticated client or BFF.

POST /api/manage/revoke body:

{
    "tokenId": 12,
    "publicIdentifier": "public_identifier",
    "name": "the token name"
}

On success you will get the following response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "ok": true,
  "date": "current date",
  "data": { 
      "msg": "Token invalided successfully", 
      "invalidedTokenId": 12, 
      "userId": 42 
   }
}

Aside from the standard errors related to authentication, rate limits, and provided bad data, the route returns the same success object the library users get when it revokes an active token.

If the body does not match the schema, the route returns:

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "ok": false,
  "date": "current date",
  "reason": "Bad Request"
}

If the publicIdentifier checksum is invalid, the token does not belong to the current user, the token is already revoked, or the underlying revoke action fails, the route returns a 401 response with the reason provided by privateActionManager, such as Invalid identity, Bad Request, or Error invalidating token:

HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8

{
  "ok": false,
  "date": "current date",
    "reason": "reason from privateActionManager"
}
Check the introduction page to see the standard error response.

Rate Limits

The endpoint also enforces rate limits controlled under the following configuration options:

  • rate_limiters.apiTokensLimiters.operationRateLimits.revokeTokensLimiter - The main limiter for the revoke endpoint. The default allows 5 revocations in a window of 10 minutes and will trigger a block for 2 hours if this limit is met. Consecutive triggers in this period will block the client permanently.
  • rate_limiters.apiTokensLimiters.generalUnionLimiter - A burstLimiter and a slowLimiterunion limiter. It enforces no more than one request per second, and only 50 per minute. No consecutive triggers in this limiter are provided, and triggering it again will result in a permanent ban. The limiter is restarted on successful revocations.
    • burstLimiter - Will block the client for 15 minutes.
    • slowLimiter - Will block for 1 hour.

Configuration Reference

These configuration keys control revoke-specific throttling in the service.

Rate limiters

The revocation flow relies on the following limiter configuration:

LimiterDescription
rate_limiters.apiTokensLimiters.operationRateLimits.revokeTokensLimiterThe main rate limiter for the revoke endpoint
rate_limiters.apiTokensLimiters.generalUnionLimiterGeneral burst limiter
Logo