Unlock a User Without Admin Access
If an Admin or User admin can still sign in, clear the lock from Settings > Users instead; see Unlock a user. Use the steps on this page only when every Admin and User admin account has a lockout, or no one has those credentials, so nobody can reach the Users tab at all.
This procedure talks directly to Zitadel, the identity provider behind Access Analyzer sign-in, with kubectl and curl instead of through the product API. It needs kubectl access to the cluster running Access Analyzer, but not a working Access Analyzer session.
There's no bulk unlock. Repeat the lookup and unlock steps once per locked account.
Before You Start
You need the installed hostname to reach Zitadel. Zitadel checks the request's Host header against the hostname you chose at install and rejects anything else with "Instance not found," even when the connection succeeds. Read it from the install host:
grep hostname /etc/dspm/installer.yaml
Unlock the Account
-
Get the Zitadel admin token and open a tunnel to Zitadel in the background. Run both in the same terminal session, and run the remaining steps in that session too.
PAT=$(kubectl get secret iam-admin-pat -n access-analyzer -o jsonpath='{.data.pat}' | base64 -d)kubectl port-forward svc/zitadel 8085:8080 -n access-analyzer &The tunnel answers only on
localhoston the machine that opened it. To close it when you finish, runkill %1. -
Look up the locked account by login name. Substitute your hostname for
<hostname>and the account's login name for<login-name>. The login name is what the user types at sign-in. For user accounts, it's the full email address, such asjsmith@example.com.curl -s -X POST http://localhost:8085/v2/users \-H "Host: <hostname>" \-H "Authorization: Bearer $PAT" \-H "Content-Type: application/json" \-d '{"query": {"offset": "0", "limit": 100}, "queries": [{"loginNameQuery": {"loginName": "<login-name>"}}]}'If this returns no results, the login name doesn't match what Zitadel has on record. Drop the
queriesfilter to list every account instead, and find the one you need in the output:curl -s -X POST http://localhost:8085/v2/users \-H "Host: <hostname>" \-H "Authorization: Bearer $PAT" \-H "Content-Type: application/json" \-d '{"query": {"offset": "0", "limit": 100}}'Note the account's
userId, and confirm itsstatereadsUSER_STATE_LOCKED. -
Unlock it.
curl -s -X POST http://localhost:8085/v2/users/<userId>/unlock \-H "Host: <hostname>" \-H "Authorization: Bearer $PAT" \-H "Content-Type: application/json" \-d '{}'A successful unlock returns
{}. If the user wasn't locked, Zitadel returnsUser is not locked, which is harmless. -
Repeat step 2's lookup. The account's
stateshould now readUSER_STATE_ACTIVE. Have the user sign in again.
This clears the lockout only. It doesn't reset the password. If the user has also forgotten their password, an Admin or User admin still needs to run Actions > Reset password from the Users tab once someone can sign in. See Reset a password.
Remove a Lost Authenticator App
A user stuck on the two-factor verification step because they lost their authenticator app isn't locked out, but the Users tab has no action to remove another user's authenticator app either. Remove it the same way, using the userId from step 2:
curl -s -X DELETE http://localhost:8085/v2/users/<userId>/totp \
-H "Host: <hostname>" \
-H "Authorization: Bearer $PAT"
The user can then sign in with their password alone and set up a new authenticator app from Security settings; see Set up an authenticator app.