Blocking Developer Portal Access in WSO2 API Manager 4.2.0 Without Modifying User Roles
How to use the account locking mechanism to reliably block portal access during employee termination, even when an external IDP re-provisions roles on every login.
When an employee leaves your organisation, the first instinct is usually to remove their Internal/subscriber role in WSO2 API Manager to revoke Developer Portal access. In many environments that works fine. But if you use an external Identity Provider with Just-In-Time (JIT) provisioning, that approach breaks down quickly.
The IDP re-provisions the default role on every successful login. So even after you remove the role, the next login restores it automatically. You are back to square one.
In this article, I’ll walk you through a more reliable alternative: locking the user account programmatically using the UserIdentityManagementAdminService SOAP API, so that access is blocked at the identity layer before role provisioning ever runs.
Why Account Locking Works Where Role Removal Does Not
Account locking operates at a different layer than role assignment. When an account is locked, WSO2 blocks authentication entirely before the IDP’s role-mapping logic runs. The sequence looks like this:
Because the lock is enforced before the IDP has any involvement, the IDP’s role re-provisioning logic never gets a chance to override it.
- WSO2 API Manager 4.2.0 installed and running
- Super admin credentials for the Carbon Management Console
- SSH or file access to
<APIM_HOME>/repository/conf/deployment.toml curl, Postman, or SoapUI for making SOAP requests
Part 1 — One-Time Configuration
Before you can lock accounts programmatically, two one-time configuration steps are needed. You only need to do this once per environment.
Step 1 — Enable the Account Locked Claim
By default, the Account Locked claim is not flagged as active in the claim dialect. You need to enable it so WSO2 evaluates it during authentication.
- Sign in to the Carbon Management Console:
https://<API-M_HOST>:<API-M_PORT>/carbon
- In the left menu, go to Claims > List.
- Click the
http://wso2.org/claimsclaim dialect. - Find Account Locked in the list and click Edit.
This step is critical. Without it, the lock claim may be written to the store but not evaluated at login time.
Leave all other settings on this page at their default values.
Step 2 — Enable Identity Management Listeners
Stop the APIM server. Open <APIM_HOME>/repository/conf/deployment.toml and add the following block:
[event.default_listener.identity_mgt]
enable = true
[event.default_listener.governance_identity_store]
data_store = "org.wso2.carbon.identity.governance.store.UserStoreBasedIdentityDataStore"The identity_mgt listener handles account locking and unlocking events. The governance_identity_store entry tells WSO2 where to persist identity attributes like accountLocked. Without these, a lock call may appear to succeed but the lock will not survive a server restart.
Part 2 — Locking and Unlocking User Accounts
With the one-time setup complete, you can now lock and unlock accounts on demand using a SOAP call. No further configuration changes or server restarts are needed after this point.
The WSDL for the service is available at:
https://<APIM_HOST>:<APIM_PORT>/services/UserIdentityManagementAdminService?wsdlStep 3 — Lock a User Account
Use the following command. Replace <USERNAME_TO_BE_LOCKED> with the actual username and update the Authorization header with your Base64-encoded admin credentials.
Get Dumuindu Lakal Nagasinghe’s stories in your inbox
Join Medium for free to get updates from this writer.
Template:
curl --location 'https://<APIM_HOST>:<APIM_PORT>/services/UserIdentityManagementAdminService' --header 'Content-Type: text/xml;charset=UTF-8' --header 'SOAPAction: urn:lockUserAccount' --header 'Authorization: Basic <Base64_encoded_admin_credentials>' --data '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.mgt.identity.carbon.wso2.org"> <soapenv:Header/> <soapenv:Body> <ser:lockUserAccount> <ser:userName><USERNAME_TO_BE_LOCKED></ser:userName> </ser:lockUserAccount> </soapenv:Body> </soapenv:Envelope>'Working example against a local instance:
curl --location 'https://localhost:9443/services/UserIdentityManagementAdminService' --header 'Content-Type: text/xml;charset=UTF-8' --header 'SOAPAction: urn:lockUserAccount' --header 'Authorization: Basic YWRtaW46YWRtaW4=' --data '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.mgt.identity.carbon.wso2.org"> <soapenv:Header/> <soapenv:Body> <ser:lockUserAccount> <ser:userName>john.doe</ser:userName> </ser:lockUserAccount> </soapenv:Body> </soapenv:Envelope>'To generate the Base64-encoded credentials for the Authorization header:
echo -n "admin:admin" | base64 # Result: YWRtaW46YWRtaW4=Use the -n flag. Without it, echo appends a newline character that silently corrupts the encoded value.
A successful call returns HTTP 200 with an empty SOAP body. That response confirms the lock was applied.
Step 4 — Unlock a User Account
To reverse the lock, use the same structure with the unlockUserAccount operation:
curl --location 'https://<APIM_HOST>:<APIM_PORT>/services/UserIdentityManagementAdminService' --header 'Content-Type: text/xml;charset=UTF-8' --header 'SOAPAction: urn:unlockUserAccount' --header 'Authorization: Basic <Base64_encoded_admin_credentials>' --data '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.mgt.identity.carbon.wso2.org"> <soapenv:Header/> <soapenv:Body> <ser:unlockUserAccount> <ser:userName><USERNAME_TO_BE_UNLOCKED></ser:userName> </ser:unlockUserAccount> </soapenv:Body> </soapenv:Envelope>'Verification
After locking an account, verify the result using either of these methods.
Check via the Management Console
- Sign in to
https://<APIM_HOST>:<APIM_PORT>/carbon - Go to Users and Roles > List > Users
- Click User Profile for the locked user
- Confirm the Account Locked checkbox is ticked
Test Login Directly
- Open the Developer Portal:
https://<APIM_HOST>:<APIM_PORT>/devportal - Attempt to sign in as the locked user
- The login should fail with an account locked error. The IDP’s JIT provisioning does not run.
Troubleshooting
HTTP 401 Unauthorized on the SOAP call
The Base64 value in the Authorization header is likely incorrect. Regenerate it with echo -n "username:password" | base64 and make sure the -n flag is present.
Call returns 200 but the user can still log in
The identity management listener was probably not active when the lock was applied, or the server was not restarted after the deployment.toml change. Confirm both listeners are in place, restart the server, and retry the lock call.
User is locked but regains access after the next IDP login
The IDP’s JIT provisioning configuration is overwriting the accountLocked claim. In the Management Console, go to Identity Providers > [Your IDP] > Claim Configuration and check whether http://wso2.org/claims/identity/accountLocked is mapped from an IDP attribute. If it is, remove that mapping.
WSDL endpoint returns 404 or is not accessible
Admin service WSDLs may be hidden in production. Open <APIM_HOME>/repository/conf/deployment.toml and confirm:
[admin_service.wsdl]
enable = trueReferences
- WSO2 APIM 4.2.0 — User Account Management
- WSO2 IS 5.10.0 — Locking a Specific User Account
- UserIdentityManagementAdminService WSDL:
https://<host>:9443/services/UserIdentityManagementAdminService?wsdl
Account locking gives you a clean, role-independent way to block Developer Portal access in WSO2 API Manager 4.2.0. Once the one-time listener and claim configuration is in place, locking or unlocking any account is a single SOAP call that takes effect immediately at the authentication layer.




