Ban, delete, and restore user accounts
Since Agent Router 0.4.0, a user account can be suspended with a ban, removed with a reversible soft delete, and brought back with a restore, through the management API. Both a ban and a delete sign the user out everywhere and revoke every API key the user owns; what separates them is intent and reversal. A ban is a suspension that can carry an expiry and lift itself. A delete marks the account removed until an administrator restores it.
Persona: Platform operator scripting the management API with an interactive session.
Estimated time: A few minutes per action; the reading matters more than the typing, because every action here revokes credentials.
Ban or delete
The two actions overlap in effect and differ in meaning. Both are refused for an API key caller: they require an interactive session holding the admin scope or the users.edit permission on a platform-scope role, the same authority either way, because lifting or reversing one of these actions is as consequential as performing it.
| Ban | Delete | |
|---|---|---|
| Intent | Suspension, possibly temporary | Removal, reversible on request |
| Sessions | Ended everywhere, immediately | Ended everywhere, immediately |
| API keys | Revoked, never restored | Revoked, never restored |
| Sign-in | Refused while the ban stands | Refused until restored |
| Ends by | unban, or its own expiry | restore |
| Directory | Listed under banned users | Hidden from active lists, shown in history |
One rule carries across every path in this guide: revoked credentials stay revoked. Unbanning or restoring a user reopens sign-in; it never resurrects the sessions or keys that the ban or delete destroyed. The user signs in again and issues fresh keys.
Suspend a user with a ban
POST /v1/users/{user_id}/ban marks the account banned with a reason, ends every live session, and revokes every API key the user holds. An optional expiry makes the suspension temporary.
POST /v1/users/{user_id}/unban clears the ban, its reason, and its expiry. Nothing else is restored.
A ban with an expiry lifts itself: once the expiry passes, the user can sign in again with no administrator involved. Since 0.4.0 this also holds for a session that survived the suspension window unused, which stops working during the ban and works again after it expires. On earlier releases an expired ban still blocked sign-in until an administrator unbanned the account by hand.
The request and response shapes are in the API reference: BanUser and UnbanUser.
Delete a user
DELETE /v1/users/{user_id} soft-deletes the account. In one transaction, the delete:
- marks the account deleted, recording when and by whom,
- revokes every live API key the user owns and removes the role bindings those keys carried,
- ends every session the user holds.
Because the steps are one transaction, a failure part-way leaves the user unchanged rather than half-removed.
Two refusals are deliberate:
- The last active administrator cannot be deleted, whether of the platform or of any organization the user administers. The call fails with a precondition error, so a deployment cannot delete its way out of being administrable.
- An already-deleted user cannot be deleted again; the call reports the state instead of pretending to act.
The user's record is never removed from the directory, which is what makes the restore below possible and keeps history readable: usage, audit entries, and request logs attributed to the account keep resolving to a name instead of a dangling id.
Reference: DeleteUser.
Restore a deleted user
POST /v1/users/{user_id}/restore reverses the delete: the account is active again and sign-in works. Two boundaries hold:
- A separate suspension survives the restore. If the account also carried an operator ban, restoring the deletion does not lift the ban; unban it separately.
- Credentials are not resurrected. The keys and sessions the delete revoked stay revoked. The restored user signs in and issues new keys.
Restoring a user who is not deleted, or who does not exist, returns a not-found error shaped as "not deleted".
Reference: RestoreUser.
What the affected user sees
A deleted or banned user is refused on the sign-in path with a distinct reason code naming which of the two states applies, rather than a generic failure, and the refusal is written to the audit log with that reason. A session that already existed stops working on its next use: since 0.4.0 the session check applies the same rules as sign-in, so neither a delete nor a ban leaves a live session behind.
How fast a revoked credential stops working
- Customer API keys (the keys developers send AI traffic with) stop working immediately, whether revoked directly or as part of a ban or delete.
- Admin API keys and registry credentials stop authenticating within five minutes of revocation. Until 0.4.0 the management plane could trust a cached verification for up to an hour; anyone containing a leaked management credential should count on the five-minute bound, not on instant effect.
Deleted users in the directory
Directory listings default to the living: POST /v1/users/search and POST /v1/users/stats leave deleted users out unless the deleted status is asked for explicitly, so active lists and "total users" counts never include them. The Admin Console reads the same directory, shows deleted users in history views rather than active lists, and carries each account's status, ban reason, and deletion time. Reference: SearchUsers and GetUserStats.
Where to go next