Applies to: API v1
Client APIs manage machine identities and policy documents.
- API surface:
/v1/clients* - Server expectation: Secrets server with auth and authorization middleware enabled
- OpenAPI baseline:
docs/openapi.yaml
POST /v1/clientsGET /v1/clientsGET /v1/clients/:idPUT /v1/clients/:idDELETE /v1/clients/:idPOST /v1/clients/:id/unlock
All endpoints require Bearer authentication.
Capability mapping:
POST /v1/clients->writeGET /v1/clients->readGET /v1/clients/:id->readPUT /v1/clients/:id->writeDELETE /v1/clients/:id->deletePOST /v1/clients/:id/unlock->write
| Endpoint | Success | Common error statuses |
|---|---|---|
POST /v1/clients |
201 |
401, 403, 409, 422, 429 |
GET /v1/clients |
200 |
401, 403, 422, 429 |
GET /v1/clients/:id |
200 |
401, 403, 404, 422, 429 |
PUT /v1/clients/:id |
200 |
401, 403, 404, 409, 422, 429 |
DELETE /v1/clients/:id |
204 |
401, 403, 404, 422, 429 |
POST /v1/clients/:id/unlock |
200 |
401, 403, 404, 422, 429 |
curl -X POST http://localhost:8080/v1/clients \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{
"name": "payments-api",
"is_active": true,
"policies": [
{"path":"/v1/secrets/*","capabilities":["decrypt"]},
{"path":"/v1/transit/keys/payment/encrypt","capabilities":["encrypt"]}
]
}'Response includes id and one-time secret.
Example response (201 Created):
{
"id": "0194f4a6-7ec7-78e6-9fe7-5ca35fef48db",
"secret": "s3cr3t-v4lu3-th4t-sh0uld-b3-s4v3d"
}Example success status: 201 Created.
curl "http://localhost:8080/v1/clients?offset=0&limit=20" \
-H "Authorization: Bearer <token>"Example response (200 OK):
{
"data": [
{
"id": "0194f4a6-7ec7-78e6-9fe7-5ca35fef48db",
"name": "payments-api",
"is_active": true,
"policies": [
{
"path": "/v1/secrets/*",
"capabilities": ["decrypt"]
}
],
"created_at": "2026-02-27T18:35:12Z"
}
]
}Example success status: 200 OK.
curl http://localhost:8080/v1/clients/0194f4a6-7ec7-78e6-9fe7-5ca35fef48db \
-H "Authorization: Bearer <token>"Example response (200 OK):
{
"id": "0194f4a6-7ec7-78e6-9fe7-5ca35fef48db",
"name": "payments-api",
"is_active": true,
"policies": [
{
"path": "/v1/secrets/*",
"capabilities": ["decrypt"]
}
],
"created_at": "2026-02-27T18:35:12Z"
}Clears the lockout state for a client that was locked due to too many failed authentication attempts. See Account Lockout for lockout behavior.
curl -X POST http://localhost:8080/v1/clients/<id>/unlock \
-H "Authorization: Bearer <admin-token>"Returns 200 OK with the updated client object.
Example response (200 OK):
{
"id": "0194f4a6-7ec7-78e6-9fe7-5ca35fef48db",
"name": "payments-api",
"is_active": true,
"policies": [
{
"path": "/v1/secrets/*",
"capabilities": ["decrypt"]
}
],
"created_at": "2026-02-27T18:35:12Z"
}401 Unauthorized: missing/invalid bearer token403 Forbidden: caller lacks required capability for the path404 Not Found: client ID not found409 Conflict: unique constraint conflicts422 Unprocessable Entity: invalid request/query payload429 Too Many Requests: per-client rate limit exceeded
Representative error payloads (exact messages may vary):
401 Unauthorized
{
"error": "unauthorized",
"message": "Authentication is required"
}403 Forbidden
{
"error": "forbidden",
"message": "You don't have permission to access this resource"
}422 Unprocessable Entity
{
"error": "validation_error",
"message": "invalid client request"
}# 1) Create a client
curl -s -X POST http://localhost:8080/v1/clients \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{
"name": "quickflow-client",
"is_active": true,
"policies": [{"path":"/v1/secrets/*","capabilities":["decrypt"]}]
}'
# 2) List clients
curl -i "http://localhost:8080/v1/clients?offset=0&limit=10" \
-H "Authorization: Bearer <admin-token>"Expected result: create returns 201 Created with one-time secret; list returns 200 OK.
- 📘 Policy cookbook
- 🧭 Wildcard matcher semantics
- 🧪 Curl examples
- 🐍 Python examples
- 🟨 JavaScript examples
- 🐹 Go examples
- 🧩 Create one client per service
- 🔒 Grant only required capabilities per path
- 🔄 Rotate credentials by creating new clients and deactivating old ones