REST API v1
Updated
The public programmatic API for machine access to secrets. Base URL
https://secrets.kryptic.dev (or your self-hosted Secrets API host). The complete
OpenAPI document is served at /openapi/v1.json.
The API is end-to-end encrypted: reads return ciphertext envelopes plus the org key
sealed to the machine, and writes accept envelopes the caller encrypted locally. The
server stores and delivers ciphertext it cannot open. For shell use, prefer
kryptic ci export, which performs the decryption chain for you.
Authentication
Create a machine identity in the dashboard (Machine identities -> New identity). You
get a clientId and a one-time clientSecret. Exchange them for a short-lived bearer
token:
curl -X POST https://secrets.kryptic.dev/v1/token \
-H 'Content-Type: application/json' \
-d '{ "clientId": "kmi_...", "clientSecret": "..." }'
{ "accessToken": "eyJ...", "expiresInSeconds": 900 }
Machine identities can be scoped to specific projects; an unscoped identity sees every project in the organization. Every read and write is audit-logged.
Projects
GET /v1/projects # projects the token can access
GET /v1/projects/{publicId}/environments # environments of one project
Machine key material
Before you can decrypt a bundle, fetch the machine's wrapped private key record:
GET /v1/keys/me
Authorization: Bearer <token>
The response contains the machine's public key, wrapped private key, and Argon2id KDF
salt. Derive an unwrap key from the client secret, open the private key, then open the
wrappedOrgKey that arrives with each secrets response.
Secrets
Read the ciphertext bundle for one environment:
GET /v1/projects/proj_x/secrets?environment=production
Authorization: Bearer <token>
{
"projectPublicId": "proj_x",
"environment": "production",
"orgKeyId": "key_org_...",
"wrappedOrgKey": "sbx.v1....",
"secrets": [
{
"key": "DATABASE_URL",
"envelope": "v1.key_org_....",
"definitionId": "00000000-0000-0000-0000-000000000001",
"environmentId": "00000000-0000-0000-0000-000000000002"
}
]
}
Set (create or version) one secret by uploading an envelope you encrypted under the org key in your own process:
PUT /v1/projects/proj_x/secrets/DATABASE_URL
Authorization: Bearer <token>
Content-Type: application/json
{ "environment": "production", "envelope": "v1.key_org_...." }
Delete a secret definition across all environments:
DELETE /v1/projects/proj_x/secrets/DATABASE_URL
Authorization: Bearer <token>
- Name
environment- Type
- string
- Required
- required
- Enum
- Description
The environment slug (
development,staging,production, or a custom one).
- Name
envelope- Type
- string
- Required
- required
- Enum
- Description
A ciphertext envelope in the form
v1.<orgKeyId>.<nonce>.<ciphertext>, encrypted under the organization's active key and bound to the project/environment row.
Errors
| Status | Meaning |
|---|---|
| 401 | Missing/expired token, or wrong client credentials |
| 403 | The machine identity's scopes exclude this project, or it has no org-key grant yet |
| 404 | Unknown project public id, environment slug, or secret key |
| 400 | Invalid secret key (must look like an environment variable name) or invalid envelope |
For CI jobs that just need secrets as a .env or shell exports, the Pipelines BFF's
ciphertext bundle plus kryptic ci export is usually simpler than implementing the
full decryption chain yourself.