Approval workflows¶
What happens
APIM can put an approval step in front of actions such as creating an application or subscribing. When a workflow is on, APIM saves the action in a pending state and writes an AM_WORKFLOWS row. An approver then accepts or rejects the request in the Admin Portal. On a decision, APIM completes or rolls back the original action.
Who: Any portal (requester) + Admin Portal (approver) · Tables written: AM_WORKFLOWS, plus the pending entity's own table · Tables read: AM_WORKFLOWS
The flow at a glance¶
This diagram uses a subscription as the example. Other workflow types follow the same pattern.
sequenceDiagram
actor Dev as Developer
participant Portal as Dev Portal
participant DB as Database
actor Adm as Approver
Dev->>Portal: Subscribe (Gold)
Portal->>DB: insert AM_SUBSCRIPTION (ON_HOLD)
Portal->>DB: insert AM_WORKFLOWS (CREATED)
Adm->>Portal: Approve in Admin Portal
Portal->>DB: update AM_WORKFLOWS (APPROVED)
Portal->>DB: update AM_SUBSCRIPTION (UNBLOCKED)
- Which actions need approval is set per tenant in the registry (
/_system/governance/apimgt/applicationdata/workflow-extensions.xml), not in a table.
Step by step¶
-
Pending entity. The action is saved in its "waiting" state:
Workflow type ( WF_TYPE)Pending row Waiting state AM_APPLICATION_CREATIONAM_APPLICATIONAPPLICATION_STATUS = 'CREATED'AM_APPLICATION_DELETIONAM_APPLICATIONnone: 3.2.0 ships only an auto-approve executor for this type, so the app is deleted straight away AM_SUBSCRIPTION_CREATIONAM_SUBSCRIPTIONSUB_STATUS = 'ON_HOLD'AM_SUBSCRIPTION_UPDATEAM_SUBSCRIPTIONSUB_STATUS = 'TIER_UPDATE_PENDING',TIER_ID_PENDINGsetAM_SUBSCRIPTION_DELETIONAM_SUBSCRIPTIONSUBS_CREATE_STATE = 'UN_SUBSCRIBE'AM_APPLICATION_REGISTRATION_PRODUCTION/_SANDBOXAM_APPLICATION_REGISTRATIONrow exists until approved AM_API_STATEregistry lifecycle state change not applied yet AM_USER_SIGNUPuser store user added without roles -
Workflow row →
AM_WORKFLOWS.WF_IDWF_REFERENCEWF_TYPEWF_STATUSWF_EXTERNAL_REFERENCETENANT_DOMAINWF_CREATED_TIME1 3AM_APPLICATION_CREATIONCREATED2065…carbon.super2026-09-26 10:57 2 2AM_SUBSCRIPTION_CREATIONCREATED68eb…carbon.super2026-09-26 10:57 These rows show the state before approval.
WF_STATUS_DESCstarts as a human-readable request such as "Approve API PizzaShackAPI - 1.0.0 subscription creation request from subscriber - admin …".WF_TYPEis the type discriminator. It tells you whatWF_REFERENCEpoints at.WF_REFERENCEis the pending entity's ID: aSUBSCRIPTION_ID, anAPPLICATION_ID, the API ID, or a user name.WF_EXTERNAL_REFERENCEis a unique ID (a UUID) used by the approver (or an external BPS/BPMN engine) to call back. The Admin REST API'sworkflowReferenceIdparameter is this value.WF_STATUSisCREATED(pending),APPROVEDorREJECTED.WF_STATUS_DESCholds the request text while pending, and is replaced by the approver's note on decision.WF_METADATA/WF_PROPERTIEShold the details shown to the approver, such as the API name, the app name and the tier.
Logical link (no foreign key)
WF_REFERENCEis a polymorphic link. It points at different tables depending onWF_TYPE, so no foreign key is possible. -
Decision. The approver approves or rejects the request in the Admin Portal (Tasks). APIM updates
WF_STATUS, then either completes the entity (for exampleSUB_STATUS = 'UNBLOCKED',APPLICATION_STATUS = 'APPROVED', or generates the keys) or marks it rejected (REJECTED) and cleans up. -
External engine (optional) → the
WF_*tables in the APIM DB:WF_BPS_PROFILE,WF_WORKFLOW,WF_WORKFLOW_ASSOCIATION,WF_REQUESTand the others. These come from the embedded Identity Server's workflow engine, used when approvals run on an external WSO2 BPS. With the default built-in approval, onlyAM_WORKFLOWSis used.
What gets cleaned up¶
Rejected or completed rows stay in AM_WORKFLOWS as history. When the pending entity is deleted, for example when an application is removed, APIM's code removes its pending workflow rows.
Try it¶
This query lists pending approvals and resolves subscription requests to readable names.
SELECT w.WF_ID, w.WF_TYPE, w.WF_STATUS, w.WF_CREATED_TIME,
app.NAME AS application, api.API_NAME, sub.TIER_ID
FROM AM_WORKFLOWS w
LEFT JOIN AM_SUBSCRIPTION sub
ON w.WF_TYPE = 'AM_SUBSCRIPTION_CREATION'
AND sub.SUBSCRIPTION_ID = CAST(w.WF_REFERENCE AS UNSIGNED)
LEFT JOIN AM_APPLICATION app ON app.APPLICATION_ID = sub.APPLICATION_ID
LEFT JOIN AM_API api ON api.API_ID = sub.API_ID
WHERE w.WF_STATUS = 'CREATED';
Related domains: Workflows · Applications & subscriptions
Different in 4.x
4.x keeps the same AM_WORKFLOWS model and adds workflow types, for example for API product state changes and API revision deployment approval. See Approval workflows (4.x).