REST API
Everything the web UI does goes through the REST API of the admin listener, with the same permission
checks. The description of every operation is the OpenAPI 3.1 file
api/openapi.yaml in the
repository. This page explains how to call it and what to expect.
Where it is
The API is served only on the admin listener, over HTTPS, under /api/v1:
https://pki.homelab.lan:9443/api/v1
It is not on the public listener, and not on the ACME listener. The ACME protocol itself (RFC 8555) is
not part of this API. The listener’s own GET /healthz is the health check.
Make an API token
Sign in to the UI and open My account. Under New API token give a name, a role with its scope
(the tenant, or one CA), and a validity. Creating a token needs a fresh second factor. The secret
starts with mop_ and is shown once.
- A token carries roles its owner has, never more, and ends within one year.
- You can list your own tokens, and revoke one; it stops working at once.
- Give each script its own token with the smallest role. For anything that only reads, use viewer.
Call the API with the token in a header. Pass the root as the trust anchor:
export MYOWNPKI_TOKEN=mop_…
curl -sS --cacert root.pem -H "Authorization: Bearer $MYOWNPKI_TOKEN" https://pki.homelab.lan:9443/api/v1/system/status
What a token cannot do
An API token never satisfies the fresh second factor that some operations require, because no
code can make a token fresh. Such a request answers 403 with the problem type forbidden. This covers:
- revoking certificates, and downloading or exporting private keys;
- creating, renewing, retiring and revoking CAs, and uploading a root’s CRL;
- managing users;
- managing agents: creating or revoking join tokens and enrollment passes, approving or denying enrollments, disabling or revoking an agent. (Reading them is allowed.)
- changing the agent enrollment mode:
PUT /settingswith a differentagent_enrollment(any other setting, or the same mode, works with a token); - creating other API tokens.
Issuing and renewing certificates, reading CAs, certificates, agents, alerts, reports, the analysis and the audit log, sending the test notification, and adding, scanning and removing TLS endpoints (see TLS scan) are allowed for the right role. A sign-in session in the browser can do everything its roles allow, after the step-up.
Conventions
- JSON with
snake_casefields. Times are RFC 3339 in UTC. Serial numbers and fingerprints are upper-case hex without separators. - A request with a body must send
Content-Type: application/json(else415). Unknown fields and trailing data are refused (400). Bodies are limited to 128 KiB (413). - Errors are
application/problem+json(RFC 9457). Thetypeis a URN such asurn:myownpki:problem:forbidden. Every response has anX-Request-ID, repeated in problems asrequest_id; quote it when you report a problem. - Lists are paged with a cursor:
limit(at most 100) andcursor; the answer hasnext_cursor. - What you may not read answers
404, like an unknown ID, so nobody can probe what exists. What you may read but not change answers403. - A browser session sends the cookie
__Host-myownpki_sessionand anX-CSRF-Tokenheader on changing requests. A token needs neither. - While the server is sealed, operations that sign answer
503; reading works.
Operation groups
| Group | Examples | Minimum role |
|---|---|---|
| system | GET /system/status, POST /system/unseal, POST /system/seal |
signed in; unseal and seal need an instance admin |
| auth, users | sign-in, step-up, GET /users, own password and second factor |
varies |
| tokens | GET /tokens, POST /tokens, DELETE /tokens/{tokenId} |
signed in |
| settings | GET /settings, PUT /settings |
viewer reads, admin changes (a different enrollment mode needs the second factor) |
| domains, acme | GET /domains, ACME accounts and their predecessor policies |
viewer / admin |
| cas | GET /cas, POST /cas, /cas/{caId}/certificate, /cas/{caId}/crl |
viewer reads, admin changes |
| certificates | GET /certificates, /certificates/{id}/download/{format}, …/renew, …/revoke |
viewer reads; operator issues, renews and revokes (revoking needs the second factor) |
| imports | legacy pki.sh import, external certificates |
admin |
| audit | GET /audit, POST /audit/verify |
per operation, see the OpenAPI file |
| agents | GET /agents and /agent-enrollments (both with an optional ?hostname=), /agent-join-tokens (join tokens and enrollment passes, no secrets), GET /agent-install (the facts for installing the agent without a browser), …/deployments/{name}/renew |
viewer reads, operator renews, admin manages (creating, revoking and approving need the second factor, so never a token) |
| monitoring | GET /alerts, GET /reports and GET /analysis (see Reports and analysis), POST /notifications/test |
viewer reads (tenant-wide), admin tests |
The OpenAPI file has the exact paths, parameters and the role each operation needs (x-required-role),
and marks operations that need a fresh second factor (x-step-up: true).
Examples
The open alerts:
curl -sS --cacert root.pem -H "Authorization: Bearer $MYOWNPKI_TOKEN" "https://pki.homelab.lan:9443/api/v1/alerts?state=open"
The admitted agents and their deployments:
curl -sS --cacert root.pem -H "Authorization: Bearer $MYOWNPKI_TOKEN" https://pki.homelab.lan:9443/api/v1/agents
The agent of one host, for example after a roll-out:
curl -sS --cacert root.pem -H "Authorization: Bearer $MYOWNPKI_TOKEN" "https://pki.homelab.lan:9443/api/v1/agents?hostname=minion-01.homelab.lan"
The first 20 certificates:
curl -sS --cacert root.pem -H "Authorization: Bearer $MYOWNPKI_TOKEN" "https://pki.homelab.lan:9443/api/v1/certificates?limit=20"
A test message through the notification channels (the token needs the tenant admin role):
curl -sS --cacert root.pem -X POST -H "Authorization: Bearer $MYOWNPKI_TOKEN" https://pki.homelab.lan:9443/api/v1/notifications/test