Admin API
Workers Auth includes a built-in admin API for user management. It ships as auth.admin — a standalone Hono app you mount wherever you want, protected however you see fit. List users, ban accounts, assign roles, and revoke sessions over HTTP without writing any of the plumbing yourself.
Mounting the Admin API
Section titled “Mounting the Admin API”auth.admin is a separate Hono app. Mount it on any path and layer your own auth middleware in front of it:
const auth = WorkersAuth({ ... })
const app = new Hono()
// Mount auth and admin as separate route treesapp.route('/auth', auth.handler)app.route('/admin', auth.admin)
// Protect admin routes — require a valid session and admin roleapp.use('/admin/*', auth.authenticate)app.use('/admin/*', auth.authorize('role', 'admin'))You control the path, and you control who gets in. There is no hidden access — if you don’t mount it, it doesn’t exist.
Endpoints
Section titled “Endpoints”All paths are relative to wherever you mount auth.admin.
| Method | Path | Description |
|---|---|---|
| GET | /users | List users (paginated) |
| GET | /users/:id | Get user with roles |
| POST | /users/:id/ban | Ban user, revoke sessions |
| POST | /users/:id/unban | Unban user |
| POST | /users/:id/roles | Assign role |
| DELETE | /users/:id/roles/:role | Remove role |
List users
Section titled “List users”GET /usersReturns a paginated list of all users.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 50 | Maximum number of users to return |
offset | number | 0 | Number of users to skip |
Request:
curl https://your-app.workers.dev/admin/users?limit=10&offset=0 \ -H "Cookie: session=<session_token>"Response:
{ "users": [ { "id": "usr_abc123", "email": "alice@example.com", "status": "active", "createdAt": 1706140800, "updatedAt": 1706140800 }, { "id": "usr_def456", "email": "bob@example.com", "status": "banned", "createdAt": 1706054400, "updatedAt": 1706227200 } ], "total": 42, "limit": 10, "offset": 0}Get user
Section titled “Get user”GET /users/:idReturns a single user along with their assigned roles.
Request:
curl https://your-app.workers.dev/admin/users/usr_abc123 \ -H "Cookie: session=<session_token>"Response:
{ "user": { "id": "usr_abc123", "email": "alice@example.com", "status": "active", "createdAt": 1706140800, "updatedAt": 1706140800 }, "roles": ["admin", "editor"]}Ban user
Section titled “Ban user”POST /users/:id/banSets the user’s status to banned and revokes all of their active sessions immediately. The user is logged out everywhere, with no grace period.
Request:
curl -X POST https://your-app.workers.dev/admin/users/usr_def456/ban \ -H "Cookie: session=<session_token>"Response:
{ "success": true}Unban user
Section titled “Unban user”POST /users/:id/unbanSets the user’s status back to active. The user can log in again, but previous sessions remain revoked — they will need to authenticate fresh.
Request:
curl -X POST https://your-app.workers.dev/admin/users/usr_def456/unban \ -H "Cookie: session=<session_token>"Response:
{ "success": true}Assign role
Section titled “Assign role”POST /users/:id/rolesAssigns a role to the user. The role must be defined in your RBAC policy.
Request:
curl -X POST https://your-app.workers.dev/admin/users/usr_abc123/roles \ -H "Cookie: session=<session_token>" \ -H "Content-Type: application/json" \ -d '{ "role": "admin" }'Response:
{ "success": true}Returns 400 if the role field is missing from the request body:
{ "error": "role is required"}Remove role
Section titled “Remove role”DELETE /users/:id/roles/:roleRemoves a role from the user.
Request:
curl -X DELETE https://your-app.workers.dev/admin/users/usr_abc123/roles/admin \ -H "Cookie: session=<session_token>"Response:
{ "success": true}Ban behavior
Section titled “Ban behavior”Banning a user does two things:
- Sets the user’s status to
bannedin the database. - Revokes all active sessions immediately. Every session token for that user is deleted from both D1 and KV. Any request carrying one of those tokens will fail authentication on the next call.
This is not eventual — the user is locked out the moment the ban endpoint returns.
The authenticate middleware also enforces bans at the edge. If a banned user makes a request with a stale session cookie that hasn’t been cleaned up yet, authenticate will check the user’s status, reject the request with a 403, and revoke the stale session on the spot. There is no window where a banned user can sneak through.