Revoke & delete¶
What happens
Tokens can be revoked one at a time, for everything an application issued, or for everything a user holds. Because most 4.x tokens are self-contained JWTs, the Gateway can't simply "look them up". Instead APIM records what was revoked, and from when, and pushes that to every gateway. This page also explains what the database removes automatically when you delete an API, an application or a subscription.
Who: Developer, admin or the Key Manager · Tables written: AM_REVOKED_JWT, IDN_INVALID_TOKENS, AM_APP_REVOKED_EVENT, AM_SUBJECT_ENTITY_REVOKED_EVENT, IDN_OAUTH2_ACCESS_TOKEN (opaque tokens only), IDN_APP_REVOKED_EVENT, IDN_SUBJECT_ENTITY_REVOKED_EVENT
The three kinds of revocation¶
Each kind is stored in a different table.
flowchart LR
T[One token revoked] --> RJ[AM_REVOKED_JWT]
A[All tokens of an app revoked] --> AE[AM_APP_REVOKED_EVENT]
U[All tokens of a user revoked] --> SE[AM_SUBJECT_ENTITY_REVOKED_EVENT]
RJ --> GW[Gateways reject matching tokens]
AE --> GW
SE --> GW
- A single revocation is matched on the token's identity.
- An app or user revocation stores a time. Any token issued before that time is rejected.
The flow at a glance¶
This diagram shows a developer regenerating an application's consumer secret, which revokes every token the application has issued.
sequenceDiagram
actor Dev as Developer
participant KM as Key Manager
participant DB as Database
participant GW as Gateway
Dev->>KM: Regenerate secret (or delete app) for PizzaApp
KM->>DB: insert IDN_APP_REVOKED_EVENT
KM->>DB: insert AM_APP_REVOKED_EVENT (async)
KM-->>GW: event "app tokens revoked at T"
GW->>GW: reject tokens with iat < T
Step by step¶
-
One token (via
/oauth2/revoke, or a user logging out):- For a JWT (the 4.7.0 default, not stored), the Key Manager inserts the token's identifier into
IDN_INVALID_TOKENS(TOKEN_IDENTIFIER= the JWT'sjti,CONSUMER_KEY,EXPIRY_TIMESTAMP). For a stored opaque token, it changes theIDN_OAUTH2_ACCESS_TOKENrow instead. - APIM adds the JWT to
AM_REVOKED_JWT(UUID,SIGNATURE,EXPIRY_TIMESTAMP,TENANT_ID,TOKEN_TYPE,TIME_CREATED). Despite its name,SIGNATUREheld the token'sjti, the same value asIDN_INVALID_TOKENS.TOKEN_IDENTIFIER. Gateways load this list at startup and receive new entries as events.
AM_REVOKED_JWT.UUID SIGNATURE EXPIRY_TIMESTAMP TENANT_ID TOKEN_TYPE c26f…2d4d…(jti)1790403509794 -1234 JWT IDN_INVALID_TOKENS.UUID TOKEN_IDENTIFIER CONSUMER_KEY 2bc4…2d4d…(jti)rfjt… - For a JWT (the 4.7.0 default, not stored), the Key Manager inserts the token's identifier into
-
All tokens of an application (the secret is regenerated, or the app is revoked or deleted):
- Key Manager side:
IDN_APP_REVOKED_EVENT. - APIM side:
AM_APP_REVOKED_EVENT, withCONSUMER_KEY,TIME_REVOKEDandORGANIZATION. There's one row per consumer key, which is updated each time. - Deleting an application such as
PizzaAppproduces both rows for its consumer key. The APIM-side row is written a few seconds after the Key Manager-side row.
- Key Manager side:
-
All tokens of a user (the user is deleted or locked, their password changes, or a role changes):
- Key Manager side:
IDN_SUBJECT_ENTITY_REVOKED_EVENT. - APIM side:
AM_SUBJECT_ENTITY_REVOKED_EVENT, withENTITY_ID,ENTITY_TYPE(e.g. a user id or client id) andTIME_REVOKED.
Logical link (no foreign key)
The revoked-event tables link to applications and users only by value: a consumer key or a user id. Nothing is enforced, and the rows are kept even after the application is deleted.
- Key Manager side:
-
Cleanup. Once a revoked JWT's
EXPIRY_TIMESTAMPhas passed, APIM deletes its row. The token would be rejected as expired anyway.
What gets cleaned up when you delete things¶
This table shows what the database does by itself (the ON DELETE rules). Anything marked "code" is handled by APIM's Java code.
APIM's code adds its own guard rails
Even where an FK would cascade, APIM refuses to delete an API that still has subscriptions (HTTP 409). Remove the subscriptions first, then delete the API.
| You delete… | Removed automatically (CASCADE) | Blocks the delete (RESTRICT / no rule) | Removed by code |
|---|---|---|---|
API (AM_API) |
AM_SUBSCRIPTION, AM_REVISION → deployments, AM_API_ENDPOINTS, AM_API_LC_EVENT, comments, ratings, labels, API policies, client certs, GraphQL complexity, AM_GW_REVISION_DEPLOYMENT |
AM_EXTERNAL_STORES, AM_API_METADATA, AM_API_AI_CONFIGURATION, AM_API_KEY_API_MAPPING, AM_BACKEND |
AM_API_URL_MAPPING (no FK), and then its scope and policy mappings by cascade. Also the registry artifact, UM_PERMISSION rows, gateway artifacts, AM_API_DEFAULT_VERSION, and the API's GOV_ARTIFACT and governance results. A scope still used by another version stays |
Application (AM_APPLICATION) |
AM_SUBSCRIPTION, AM_APPLICATION_KEY_MAPPING, AM_APPLICATION_REGISTRATION, attributes, group mappings |
AM_API_KEY_APPLICATION_MAPPING (APIM's code removed it first) |
The OAuth clients in the Key Manager (IDN_OAUTH_CONSUMER_APPS, IDN_OAUTH_CONSUMER_SECRETS, IDN_OIDC_PROPERTY, SP_APP, SP_INBOUND_AUTH, SP_METADATA), plus an app-revoked event. Also the pending AM_WORKFLOWS rows |
Subscription (AM_SUBSCRIPTION) |
— | — | Gateway event, pending workflows (only the row itself is deleted) |
Subscriber (AM_SUBSCRIBER) |
— | AM_APPLICATION, AM_APPLICATION_REGISTRATION, AM_API_RATINGS |
— |
OAuth client (IDN_OAUTH_CONSUMER_APPS) |
IDN_OAUTH2_ACCESS_TOKEN → token scopes, IDN_OAUTH_CONSUMER_SECRETS |
— | The AM_APPLICATION_KEY_MAPPING row, which is a logical link |
Try it¶
This query shows revocations that are still in force.
SELECT 'app' AS KIND, CONSUMER_KEY AS WHO, TIME_REVOKED FROM AM_APP_REVOKED_EVENT
UNION ALL
SELECT ENTITY_TYPE, ENTITY_ID, TIME_REVOKED FROM AM_SUBJECT_ENTITY_REVOKED_EVENT
ORDER BY TIME_REVOKED DESC;
SELECT UUID, TOKEN_TYPE, EXPIRY_TIMESTAMP FROM AM_REVOKED_JWT;
Different in 3.x
3.x only has AM_REVOKED_JWT. The app- and user-level revoked-event tables and IDN_INVALID_TOKENS don't exist. Its FKs on subscriptions and key mappings are RESTRICT, so APIM's code deletes the children before the parent. See 3.x: Revoke & delete.
Related domains: Revocation · Keys & tokens