Revoke & delete¶
What happens
Revoking a token marks it as unusable. For JWTs, which gateways check without the database, APIM also records the revoked token in AM_REVOKED_JWT and tells every gateway. Deleting an API, application or subscription removes rows in a set order. In 3.2 most child tables block the delete (ON DELETE RESTRICT), so APIM's code must remove the children first.
Who: Dev Portal, Publisher, Admin Portal, Key Manager · Tables written: IDN_OAUTH2_ACCESS_TOKEN, IDN_OAUTH2_ACCESS_TOKEN_AUDIT, AM_REVOKED_JWT, plus deletes across AM_*, IDN_*, SP_*, UM_* and REG_* · Tables read: the same
The flow at a glance¶
This diagram shows how revoking a JWT reaches every gateway.
sequenceDiagram
participant App as Client app
participant KM as Key Manager
participant DB as Database
participant GW as Gateways
App->>KM: POST /revoke (token)
KM->>DB: move token row to IDN_OAUTH2_ACCESS_TOKEN_AUDIT
KM->>DB: insert AM_REVOKED_JWT (token id, expiry)
KM-->>GW: event: token revoked
GW->>GW: add to in-memory revoked list
- A gateway that starts up later loads the still-unexpired rows of
AM_REVOKED_JWT, so it doesn't accept a revoked token it missed the event for.
Part 1: Revoking tokens¶
-
Token row →
IDN_OAUTH2_ACCESS_TOKENandIDN_OAUTH2_ACCESS_TOKEN_AUDIT. There are two different cases:- Explicit revoke (
POST /oauth2/revoke): the row is deleted fromIDN_OAUTH2_ACCESS_TOKENand a copy is inserted intoIDN_OAUTH2_ACCESS_TOKEN_AUDIT. Its scope rows inIDN_OAUTH2_ACCESS_TOKEN_SCOPEare deleted. - Superseded (the app gets a new token): the old row stays in place with
TOKEN_STATE = 'REVOKED'and a uniqueTOKEN_STATE_ID, so it doesn't clash with the new active token. Changing a user's password has the same effect.
- Explicit revoke (
-
Revoked JWT list →
AM_REVOKED_JWT.UUIDSIGNATUREEXPIRY_TIMESTAMPTENANT_IDTOKEN_TYPETIME_CREATED51d3…3427…1790403942044 -1234 JWT2026-09-26 10:57 - The
SIGNATUREcolumn holds the same short value as the token'sACCESS_TOKENcolumn (the JWT ID), not a long signature string. EXPIRY_TIMESTAMPtells the gateway when it can forget the entry, because an expired token is rejected anyway.TOKEN_TYPEdistinguishes OAuth JWTs from API keys. Revoking an API key only ever writes here, because API keys aren't stored anywhere else.
- The
Part 2: Deleting things¶
Delete a subscription¶
- Delete the
AM_SUBSCRIPTIONrow. Nothing else changes. Its only child, the legacyAM_SUBSCRIPTION_KEY_MAPPING, hasRESTRICT, so any rows there have to be removed first. APIM 3.2.0 doesn't write to that table, so it's normally empty. - With the Subscription Deletion workflow on, the row is first set to
SUBS_CREATE_STATE = 'UN_SUBSCRIBE'and waits for approval.
Delete an application¶
This diagram shows the order APIM follows, because the database would otherwise refuse.
flowchart LR
A[OAuth clients in Key Manager] --> B[Key mappings and registrations]
B --> C[Subscriptions]
C --> D[AM_APPLICATION]
D --> E[Attributes and groups cascade]
- Deleting the OAuth client (
IDN_OAUTH_CONSUMER_APPS) cascades to its tokens, authorization codes and scopes in theIDN_*tables, and removes itsIDN_OIDC_PROPERTYrows. The Key Manager also removes the matchingSP_APPservice provider (withSP_INBOUND_AUTHandSP_METADATA) and theApplication/<owner>_<app>_<keytype>hybrid role. AM_APPLICATION_KEY_MAPPING,AM_APPLICATION_REGISTRATIONandAM_SUBSCRIPTIONall useRESTRICTonAM_APPLICATION, so they're deleted by code first.AM_APPLICATION_ATTRIBUTESandAM_APPLICATION_GROUP_MAPPINGcascade automatically.- Any pending
AM_WORKFLOWSrows for the app are cleaned up by code, becauseWF_REFERENCEis a logical link.
Delete an API¶
| Child table | Link to AM_API |
What happens |
|---|---|---|
AM_SUBSCRIPTION |
FK, RESTRICT |
APIM refuses the delete with HTTP 409 while active subscriptions exist. Remove them first |
AM_API_LC_EVENT |
FK, RESTRICT |
Code deletes first |
AM_API_COMMENTS, AM_API_RATINGS |
FK, RESTRICT |
Code deletes first |
AM_EXTERNAL_STORES, AM_SECURITY_AUDIT_UUID_MAPPING |
FK, RESTRICT |
Code deletes first |
AM_API_URL_MAPPING |
logical (no FK) | Code deletes. Then AM_API_RESOURCE_SCOPE_MAPPING cascades from it |
AM_API_PRODUCT_MAPPING, AM_GRAPHQL_COMPLEXITY, AM_API_CLIENT_CERTIFICATE |
FK, CASCADE |
Removed automatically |
AM_API_DEFAULT_VERSION |
logical (name + provider) | Code updates or deletes |
AM_GW_API_ARTIFACTS → AM_GW_PUBLISHED_API_DETAILS |
logical (API UUID) | Code removes the artifacts, then the details |
Registry artifact (REG_*) |
logical | Code deletes the artifact, docs and definition |
Local scopes of the API live in IDN_OAUTH2_SCOPE in 3.2 (not AM_SCOPE), and code deletes them when no other version uses them. For example, deleting 2.0.0 keeps order:write if 1.0.0 still uses it. Shared scopes (AM_SHARED_SCOPE) survive.
Try it¶
This query lists the revoked JWTs that gateways still need to remember, because they haven't expired yet.
SELECT UUID, TOKEN_TYPE, TENANT_ID, TIME_CREATED, EXPIRY_TIMESTAMP
FROM AM_REVOKED_JWT
WHERE EXPIRY_TIMESTAMP > UNIX_TIMESTAMP() * 1000
ORDER BY TIME_CREATED DESC;
This query checks what still blocks deleting an application (id 2).
SELECT 'subscriptions' AS blocker, COUNT(*) FROM AM_SUBSCRIPTION WHERE APPLICATION_ID = 2
UNION ALL
SELECT 'key mappings', COUNT(*) FROM AM_APPLICATION_KEY_MAPPING WHERE APPLICATION_ID = 2
UNION ALL
SELECT 'registrations', COUNT(*) FROM AM_APPLICATION_REGISTRATION WHERE APP_ID = 2;
Related domains: Revocation · Keys & tokens · Applications & subscriptions
Different in 4.x
4.x changes several RESTRICT rules to CASCADE, for example subscriptions and key mappings when an app or API is deleted. It also adds revocation event tables: AM_APP_REVOKED_EVENT, AM_SUBJECT_ENTITY_REVOKED_EVENT, their IDN_* twins, and IDN_INVALID_TOKENS. These revoke all tokens of an app or user at once. See Revoke & delete (4.x).