| Plane | Header format | Credential source |
|---|---|---|
| Management | Authorization: Bearer <token> |
Management:AdminApiKey config value |
| Consumer | X-Api-Key: <key> |
Plain API key returned on application creation |
The two planes are completely independent. A consumer API key cannot call management endpoints, and the admin bearer token cannot call consumer endpoints.
Include the admin bearer token in every management request:
1
2
curl https://grimoire.example.com/api/management/applications \
-H "Authorization: Bearer your-admin-key"
The token is compared directly against Management:AdminApiKey. There is no expiry — the token is valid until the config value is changed.
Set Management:AdminApiKey in your configuration:
1
2
# Docker env var
Management__AdminApiKey=your-strong-random-token
Store it in a password manager or secrets manager. There is no UI to retrieve it.
Consumer API keys are per-application. The plain key is shown once when the application is created or its key is rotated.
1
2
curl https://grimoire.example.com/api/consumer/secrets/my-secret?environment=production \
-H "X-Api-Key: grm_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
1
grm_{40 lowercase hex chars}
Example: grm_4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a
The plain key is never stored by Grimoire. Only the PBKDF2 hash is persisted. If you lose the key, rotate it via the Management API.
1
2
curl -X POST https://grimoire.example.com/api/management/applications/my-app/rotate-key \
-H "Authorization: Bearer your-admin-key"
The response contains the new plain key. The old key is invalidated immediately.
The following endpoints are always accessible without credentials:
| Endpoint | Purpose |
|---|---|
GET /health |
Health check (used by Docker, load balancers) |
1
2
3
4
5
{
"type": "https://tools.ietf.org/html/rfc7235#section-3.1",
"title": "Unauthorized",
"status": 401
}
Same 401 response — Grimoire does not distinguish between missing and wrong credentials to prevent enumeration.