KMS.API exposes a minimal JSON API for backend KMS clients.

This API is an admin/backend surface. Do not expose it directly to browsers or the public internet.

Most applications should use KMS.Client.Remote instead of hand-writing HTTP calls.

Authentication

Health endpoints do not require a token.

All /api/* endpoints require:

Authorization: Bearer <KMS_API_TOKEN>

If config :kms, :api has no :api_token, API routes fail closed:

{"error":"api_token_required"}

Common request shape

Most POST bodies are JSON objects.

Operations that accept options use an opts object:

{
  "alias": "owner:alice",
  "cleartext": "secret",
  "opts": {"aad": "document:123/body"}
}

opts.session may carry a KMS session secret for principal-scoped authorization.

Common responses

Success returns 200 with an operation-specific JSON key.

Errors return JSON:

{"error":"not_found"}

Validation errors return:

{"error":"invalid_changeset","details":{}}

Common statuses:

StatusMeaning
200Success
400Invalid JSON/body shape
401Missing or wrong API token
404Not found
422Invalid changeset
503API token missing or readiness failed

Health

MethodPathAuthDescription
GET/healthnoCheap compatibility check.
GET/health/livenoLiveness check.
GET/health/readynoReadiness check for DB, RMK access, and API token config.

Encryption

MethodPathBodyResponse
POST/api/encryptalias, cleartext, optsencrypted
POST/api/decryptalias, encrypted, optscleartext or cleartexts
POST/api/rmk_pdk/encryptcleartext, secret, optsencrypted
POST/api/rmk_pdk/decryptencrypted, secret, optscleartext

Example:

curl -fsS \
  -H "authorization: Bearer $KMS_API_TOKEN" \
  -H "content-type: application/json" \
  -d '{"alias":"owner:alice","cleartext":"secret","opts":{"aad":"document:123/body"}}' \
  https://kms.internal.example.com/api/encrypt

KEKs

MethodPathBodyResponse
POST/api/keks/createalias, optskek
POST/api/keks/tagsalias, optstags
POST/api/keks/aliases_by_tagtag, optsaliases
POST/api/keks/add_tagsalias, tags, optstags
POST/api/keks/remove_tagsalias, tags, optstags
POST/api/keks/rewrap_for_principalalias, target_kind, target_ref, optsok
POST/api/keks/rewrap_for_passphrasealias, passphrase, optswrapping_id
POST/api/keks/revoke_passphrasealias, wrapping_id, optsok

KEK metadata includes protection: "rmk" | "session", never key material. New aliases created with opts.session are session-protected. Passphrase sharing/revocation requires the principal's active session, kek.rewrap permission, and a usable recipient envelope. See Factor-bound aliases for the complete flow and compatibility limits.

Principals

MethodPathBodyResponse
POST/api/principals/getkind, ref, optsprincipal
POST/api/principals/listoptsprincipals
POST/api/principals/createattrs, optsprincipal
POST/api/principals/updatekind, ref, attrs, optsprincipal
POST/api/principals/deletekind, refprincipal

When opts.session is supplied to principal creation, it must authorize principal.create against the new principal's reference/tags. Omitting it remains trusted bootstrap/admin execution; a malformed supplied session is not treated as absent.

Principal factors

MethodPathBodyResponse
POST/api/principal_factors/getidprincipal_factor
POST/api/principal_factors/listkind, refprincipal_factors
POST/api/principal_factors/createkind, ref, attrsprincipal_factor
POST/api/principal_factors/updateid, attrsprincipal_factor
POST/api/principal_factors/deleteidprincipal_factor

Bindings

MethodPathBodyResponse
POST/api/bindings/getidbinding
POST/api/bindings/listprincipal_idbindings
POST/api/bindings/createprincipal_id, attrsbinding
POST/api/bindings/updateid, attrsbinding
POST/api/bindings/deleteidbinding

Fallback recovery

Fallback operations are absent from the compiled HTTP router. This includes public-key registry, envelope metadata, and private-key operations. Use trusted local Elixir calls or a controlled remote shell on the KMS host. See Fallback recovery.

Sessions

MethodPathBodyResponse
POST/api/sessions/getsecretsession
POST/api/sessions/activesecretsession
POST/api/sessions/listkind, refsessions
POST/api/sessions/createkind, ref, attrs, optssession
POST/api/sessions/passphraseattrssession
POST/api/sessions/advancesecret, attrssession
POST/api/sessions/nudgesecret, optssession
POST/api/sessions/deletesecretsession
POST/api/sessions/delete_allkind, ref, optssessions
POST/api/sessions/refreshsecret, optssession

Session response JSON redacts bearer secrets in inspect-like contexts, but HTTP session creation returns the session secret because callers need it. Treat it like a password.

WebAuthn

MethodPathBodyResponse
POST/api/webauthn/registration/beginkind, ref, optschallenge
POST/api/webauthn/registration/finishchallenge_id, response, optscredential
POST/api/webauthn/authentication/beginkind, ref, optschallenge
POST/api/webauthn/authentication/finishchallenge_id, response, optssession

See WebAuthn.

Security rules

  • Use TLS or trusted private networking.
  • Keep API tokens high entropy.
  • Do not log request or response bodies.
  • Do not log bearer tokens, plaintext, ciphertext payloads, passwords, factor codes, or RMK material.
  • Put authorization in your application and/or use KMS sessions/bindings.