Secrets API reference
What the Secrets API does
- Path:
/api/secrets(+/metadata,/keys,/rotate) - Input: Canonical Secret URI (strictly parsed/normalized; tenant/mount guarded)
- YAML:
yaml://secret/<path>#<key> - OpenBao/HashiCorp KVv2:
openbao+kv2://<mount>/<path>#<key>[?version=N],hashicorp+kv2://...
- YAML:
Authentication and authorization
- Auth dependency is optional; enable with
SECRETS_API_REQUIRE_AUTH=true(usesAuthenticationService). - OAuth scopes optional; enable with
SECRETS_ENFORCE_SCOPES=true.- POST write:
secrets.write - DELETE soft:
secrets.delete; hard destroy:secrets.destroy - POST /rotate:
secrets.rotate - GET /metadata|/keys:
secrets.read_metadata - GET read (YAML):
secrets.read
- POST write:
- PDP enforced via
SecretPolicyService.authorize_batch:- Purposes:
write,delete,rotate,read_metadata(structured 403 with details on failure)
- Purposes:
- Tenant guard:
TENANT_ID,TENANT_ALLOWED_MOUNTS(e.g.,secret) constrain URIs.
Endpoints and provider behavior
- POST
/api/secrets(create/update)- YAML (dev/test only): writes nested map or fragment into
YAML_VAULT_PATH. - OpenBao/HashiCorp KVv2: requires engine
kv2; resolves provider via strategies; writes map, or{fragment: value}if#fragmentpresent.
- YAML (dev/test only): writes nested map or fragment into
- GET
/api/secrets?uri=...- YAML only (dev tooling): returns map or fragment value; non‑YAML returns 501 (use VaultService for reads).
- GET
/api/secrets/value?uri=...[&version=N]- Provider‑backed read through
VaultService(PEP). Supports KVv2 version pin query.
- Provider‑backed read through
- DELETE
/api/secrets?uri=...&destroy=[true|false]- YAML (dev/test only): removes fragment or node.
- OpenBao/HashiCorp KVv2: soft delete or hard destroy via provider.
- POST
/api/secrets/rotate- YAML: update semantics.
- KVv2: uses
RotationControllerto upsert new value (payload as{fragment: value}or full map).
- GET
/api/secrets/metadata?prefix=...and/api/secrets/keys?uri=...- YAML only (dev tooling) for metadata listing and key enumeration.
- GET
/api/secrets/metadata/detail?uri=...- KVv2 provider metadata (versions and custom metadata) for a given path.
- GET
/api/secrets/versions?uri=...- KVv2 versions listing for a given path.
- GET
/api/secrets/search?q=...&prefix=...- YAML search by path/fragment. KVv2 shallow traversal when provider supports
list_keys.
- YAML search by path/fragment. KVv2 shallow traversal when provider supports
- POST
/api/secrets/undelete- KVv2 undelete specific versions.
- POST
/api/secrets/destroy-versions- KVv2 hard‑destroy specific versions (irreversible).
- POST
/api/secrets/bulk- Batch set|delete|destroy|undelete|rotate operations with per‑op PDP/scope enforcement.
- POST
/api/secrets/copyand/api/secrets/move- Copy/move secrets between URIs. PDP: read on source, write on destination.
overwriteguard.
- Copy/move secrets between URIs. PDP: read on source, write on destination.
- GET
/api/secrets/events(SSE)- Server‑sent events stream for local dev tooling (reads/updates/deletes).
- GET
/api/secrets/audit- In‑memory audit buffer (local/dev); filterable and paginated.
Auditing
- Kafka events on read/update/delete (includes
resource_refHMAC whenTENANT_SALTis set). Provider strategies emit provider‑specific audit events (e.g., KVv2 delete/destroy). Local dev also exposes SSE/eventsand an in‑memory/auditbuffer.
Endpoint → scopes and PDP purposes
- POST
/api/secrets→ scopesecrets.write(optional) | PDP purposewrite - GET
/api/secrets(YAML only) → scopesecrets.read(optional) - GET
/api/secrets/value→ scopesecrets.read(optional) | PDP viaVaultService - DELETE
/api/secrets→ scopessecrets.deleteorsecrets.destroy| PDP purposedelete - POST
/api/secrets/rotate→ scopesecrets.rotate| PDP purposerotate - GET
/api/secrets/metadata,/keys→ scopesecrets.read_metadata| PDP purposeread_metadata - GET
/api/secrets/metadata/detail,/versions→ scopesecrets.read_metadata| PDP purposeread_metadata - POST
/api/secrets/undelete→ scopesecrets.delete| PDP purposeundelete - POST
/api/secrets/destroy-versions→ scopesecrets.destroy| PDP purposedestroy_versions - POST
/api/secrets/bulk→ per‑op scopes and PDP purposes as above - POST
/api/secrets/copy→ scopessecrets.read+secrets.write| PDP read on source, write on destination - POST
/api/secrets/move→ same as copy, then delete source (soft)
How Vault providers integrate
- YAML provider (dev‑only):
- File‑backed; path maps to nested YAML dicts; fragment is the key.
- Writes/deletes blocked outside dev/test (
ENVIRONMENTguard).
- OpenBao/HashiCorp providers (KVv2):
- Config via
VAULT_URL,VAULT_TOKEN(or AppRole). OtherVAULT_*vars optional (defaults applied). - Path is
<mount>/<path>; fragment selects a key from KV payload. - Versioned reads supported with
?version=N.
- Config via
Using in compose (examples)
YAML pointer
environment:
- CREDENTIAL_ENCRYPTION_KEY_POINTER=yaml://secret/crud#CREDENTIAL_ENCRYPTION_KEY
- YAML_VAULT_PATH=/app/config/data/dev_secrets.yaml
- TENANT_ID=dev
- TENANT_ALLOWED_MOUNTS=secret
OpenBao pointer
environment:
- CREDENTIAL_ENCRYPTION_KEY_POINTER=openbao+kv2://secret/crud#CREDENTIAL_ENCRYPTION_KEY
- VAULT_URL=http://openbao:8200
- VAULT_TOKEN=root
- TENANT_ID=dev
- TENANT_ALLOWED_MOUNTS=secret
Minimal API examples
Create/update KVv2
POST /api/secrets
{ "uri": "openbao+kv2://secret/app/test#value", "value": { "value": "hello" } }
Read YAML
GET /api/secrets?uri=yaml://secret/crud#CREDENTIAL_ENCRYPTION_KEY
Read KVv2 via PEP
GET /api/secrets/value?uri=openbao+kv2://secret/app/test#value&version=2
Delete KVv2
DELETE /api/secrets?uri=openbao+kv2://secret/app/test#value
# destroy=true for hard delete
Undelete versions (KVv2)
POST /api/secrets/undelete
{ "uri": "openbao+kv2://secret/app/test", "versions": [3,4] }
Destroy versions (KVv2)
POST /api/secrets/destroy-versions
{ "uri": "openbao+kv2://secret/app/test", "versions": [1,2] }
Bulk operations
POST /api/secrets/bulk
{ "operations": [
{ "op": "set", "uri": "yaml://secret/env#NEW", "value": "abc" },
{ "op": "delete", "uri": "openbao+kv2://secret/app/test#value" }
]}
Copy
POST /api/secrets/copy
{ "fromUri": "yaml://secret/env#FROM", "toUri": "yaml://secret/env#TO", "overwrite": false }
Search
GET /api/secrets/search?q=token&prefix=yaml://secret/env/
Notes
- Reads for non‑YAML should happen through
VaultService(PEP) in app code; the API’s YAML read is for dev tooling. - Scopes/PDP can be turned on progressively with the env flags above.