Skip to content

Vault API compatibility

Kallisto implements the read half of the Vault KV-v2 API, plus the sys and auth/token routes an unmodified Vault SDK calls before its first real request. Compatibility is tested against three real clients: the official Go client (hashicorp/vault/api), Python’s hvac, and PHP’s csharpru/vault-php.

All routes are under /v1/. In the tables, secret stands for the configured mount.

RequestBehaviour
GET /v1/secret/data/<path>The secret. metadata.version is the file’s content version.
GET /v1/secret/data/<path>?version=NThe secret if N is the current content version, otherwise 404.
GET /v1/secret/metadata/<path>Metadata, with one entry in versions.
LIST /v1/secret/metadata/<path>Keys under the path.
GET /v1/secret/metadata/<path>?list=trueThe same listing, spelled as a GET.
PUT, POST, PATCH, DELETE on data/ or metadata/403 permission denied
Any method on subkeys/, delete/, undelete/, destroy/403 permission denied

The write-side routes are declared on purpose so they answer 403. A 404 would read as “not deployed yet”. A 403 says the door exists and is shut.

A request to a mount other than the configured one answers 404.

The file holds current values only. ?version=N answers for the current version and 404 for any other. Older values live in your git history and bucket versioning. LIST treats app and app/ as the same directory, as Vault does.

RequestBehaviour
GET /v1/sys/health200 when a file is loaded, 503 when sealed. Adds Kallisto fields, below.
GET /v1/sys/seal-statusReal sealed state.
GET /v1/sys/initAlways initialised.
GET /v1/sys/mountsThe configured KV-v2 mount.
GET /v1/sys/internal/ui/mounts/<path>Mount lookup, as SDKs use to detect KV version.
GET /v1/sys/metricsPrometheus text format. See metrics and logs.
/v1/auth/token/lookup-self, /v1/auth/token/renew-selfAnswered so SDK startup succeeds.

None of these serve a secret.

FieldMeaning
kallisto_file_versionContent version being served, null when sealed.
kallisto_etagETag of the object last loaded from a bucket.
kallisto_loaded_atWhen the current file was loaded, RFC 3339.
kallisto_authorizationenforced with a token table, none without.
kallisto_versionVersion string of the running binary.

A token is read from X-Vault-Token, or from Authorization: Bearer <token>. With no token table in the file, tokens are ignored and every read is permitted. With one, every request needs a token whose policies allow the path, and the check runs before the lookup, so a 403 reveals nothing about whether a path exists.

CodeWhen
200Served.
403A write, or a read the token’s policies do not allow.
404No such path, version or mount.
429Rate limit exceeded. Carries Retry-After, never zero.
503Sealed: no file has loaded yet.

Auth methods, dynamic secrets, leases, token expiry and revocation endpoints, PKI, transit, other secret engines, and any write. If you need these, run OpenBao or Vault. Kallisto can sit beside it for the operational secrets your services read on every request.