Admin REST API¶
The kit exposes a management API under /admin/api/v1. The companion
devslab-kit-admin-ui is
built directly on it; you can also call it from your own tooling.
| Resource | What it does |
|---|---|
auth |
Log in (returns a JWT) and change password. |
users |
CRUD users, reset password, lock/unlock, change status. |
roles |
CRUD roles and assign permissions. |
permissions |
CRUD permission definitions. |
groups |
CRUD subject groups and manage membership. |
menus |
Manage the menu tree (per-item required permission, ordering). |
tenants |
CRUD tenants and change tenant status. |
policies |
List the registered ABAC policies and dry-run a (subject, action, resource) tuple without persisting anything. |
audit-logs |
Search and filter the audit trail. |
diagnostics |
Read-only probes — login test, permission check, menu visibility — with no side effects. |
settings |
Live read-only view of the effective devslab.kit.* configuration (secrets masked). |
bootstrap/status |
Unauthenticated GET returning { initialized: boolean } — the branch point for a first-run / setup wizard. |
Authentication¶
All endpoints except bootstrap/status require a bearer token. Obtain one from
auth/login:
curl -s localhost:8080/admin/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"admin","password":"…"}'
# → { "token": "<jwt>", "mustChangePassword": false, ... }
Send it as Authorization: Bearer <jwt> on subsequent calls. The token carries the
tenant, roles, and the mustChangePassword flag (see Access).
Authorization¶
Authentication is not enough: every endpoint also requires the admin.* permission
it maps to. Read endpoints require the matching *.read, mutating endpoints *.write
— for example GET /users needs admin.user.read and POST /users needs
admin.user.write. auth/login and bootstrap/status are public; auth/change-password
only needs a valid token.
Enforcement happens in the kit's security chain, checked against the caller's
effective permissions — resolved per request from the roles and groups they hold
(the same grant resolution the PermissionChecker uses), not
read from the token. So granting or revoking a permission takes effect on the caller's
next request, and the JWT stays small. The first-admin bootstrap seeds every admin.*
permission onto PLATFORM_ADMIN, so the seeded admin can use the whole API at once.
Customising security
The security chain and the JWT filter are both @ConditionalOnMissingBean, so you
can supply your own SecurityFilterChain or JwtAuthenticationFilter to change how
the surface is protected. For authorization checks inside your own code, inject the
kit's PermissionChecker (see Access).
Errors¶
Every error response is an RFC 7807 ProblemDetail
(application/problem+json):
{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "Validation failed",
"errors": ["loginId: must not be blank"]
}
Read the human-readable message from detail (falling back to title). Validation
failures add an errors array of per-field messages. Common statuses: 401 (bad
credentials), 403 (missing the required admin.* permission), 400 (bad input),
409 (conflict).