API Reference
Sirr exposes HTTP endpoints for secrets management, audit logging, webhooks, and scoped API keys. All endpoints except /health require a Bearer token — either your SIRR_MASTER_KEY or a scoped API key. Requests and responses use JSON.
All authenticated endpoints require the Authorization: Bearer <SIRR_MASTER_KEY> header. The master key is set when you start the server and is used both for authentication and as the seed for encryption.
Create a secret
Create an encrypted secret. The value is encrypted at rest using ChaCha20Poly1305 with a per-record nonce derived from your master key via Argon2id.
Required attributes
- Name
key- Type
- string
- Description
Unique identifier for the secret. Used to retrieve or delete it later.
- Name
value- Type
- string
- Description
The secret value to encrypt and store.
Optional attributes
- Name
ttl_seconds- Type
- integer
- Description
Time-to-live in seconds. The secret is automatically destroyed after this duration. Omit for no expiration.
- Name
max_reads- Type
- integer
- Description
Maximum number of times the secret can be read. The secret is permanently destroyed after this many reads. Omit for unlimited reads.
Without a valid license key, Sirr allows a maximum of 100 active secrets per instance. Attempting to exceed this limit returns a 402 Payment Required error.
Request
curl -X POST http://localhost:39999/secrets \
-H "Authorization: Bearer $SIRR_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"key": "DB_URL",
"value": "postgres://user:pass@db:5432/myapp",
"ttl_seconds": 3600,
"max_reads": 1
}'
Response (201)
{
"key": "DB_URL"
}
Error (402)
{
"error": "secret limit reached",
"message": "Free tier allows up to 100 active secrets. Set SIRR_LICENSE_KEY to unlock unlimited usage."
}
List secrets
List metadata for all active secrets. This endpoint never returns secret values — only keys, timestamps, and read counters. This is a deliberate security design choice.
Secret values are never included in list responses. Use GET /secrets/:key to retrieve and decrypt a specific secret.
Request
curl http://localhost:39999/secrets \
-H "Authorization: Bearer $SIRR_MASTER_KEY"
Response
{
"secrets": [
{
"key": "DB_URL",
"created_at": 1700000000,
"expires_at": 1700003600,
"max_reads": 1,
"read_count": 0
}
]
}
Retrieve a secret
Retrieve and decrypt a secret by its key. Each call increments the read counter. If the secret has reached its max_reads limit, it is permanently destroyed after this response. Returns 404 if the secret has expired, been burned, or does not exist.
Path parameters
- Name
key- Type
- string
- Description
The key of the secret to retrieve.
Request
curl http://localhost:39999/secrets/DB_URL \
-H "Authorization: Bearer $SIRR_MASTER_KEY"
Response
{
"key": "DB_URL",
"value": "postgres://user:pass@db:5432/myapp"
}
Error (404)
{
"error": "not found or expired"
}
Error (410) — sealed
{
"error": "secret is sealed — reads exhausted"
}
Delete a secret
Permanently delete a secret immediately, regardless of its TTL or remaining reads.
Path parameters
- Name
key- Type
- string
- Description
The key of the secret to delete.
Request
curl -X DELETE http://localhost:39999/secrets/DB_URL \
-H "Authorization: Bearer $SIRR_MASTER_KEY"
Response
{
"deleted": true
}
Prune expired secrets
Delete all expired secrets from the database. This is a housekeeping endpoint that reclaims storage by removing secrets whose TTL has elapsed. Returns the count of pruned secrets.
Request
curl -X POST http://localhost:39999/prune \
-H "Authorization: Bearer $SIRR_MASTER_KEY"
Response
{
"pruned": 3
}
Update a secret
Update the TTL or read limit of an existing secret without changing its value.
Path parameters
- Name
key- Type
- string
- Description
The key of the secret to update.
Optional attributes
- Name
ttl_seconds- Type
- integer
- Description
New time-to-live in seconds from now.
- Name
max_reads- Type
- integer
- Description
New maximum read count.
Request
curl -X PATCH http://localhost:39999/secrets/DB_URL \
-H "Authorization: Bearer $SIRR_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{ "ttl_seconds": 7200 }'
Response
{
"key": "DB_URL",
"updated": true
}
Audit logs
Query the append-only audit trail of secret operations. See the full Audit Logs documentation for details.
| Endpoint | Description |
|---|---|
GET /audit | Query audit log entries with filters (since, until, action, key, limit) |
Webhooks
Register HTTP endpoints to receive real-time event notifications. See the full Webhooks documentation.
| Endpoint | Description |
|---|---|
POST /webhooks | Register a new webhook endpoint |
GET /webhooks | List all registered webhooks |
DELETE /webhooks/:id | Remove a webhook |
Principal keys
Principals can create named API keys via the /me/keys endpoints. Keys support optional validity windows and are shown only once on creation.
| Endpoint | Description |
|---|---|
POST /me/keys | Create a new principal key |
DELETE /me/keys/:id | Revoke a principal key |
Health check
Check whether the Sirr server is running and ready to accept requests. This endpoint does not require authentication and is suitable for load balancer health checks and uptime monitoring.
Request
curl http://localhost:39999/health
Response
{
"status": "ok"
}
Org-Scoped API (Multi-Tenant)
Sirr supports multi-tenant isolation through organizations, principals, and role-based access control. Org-scoped endpoints live under /orgs/{org_id}/ and require authentication via either the master key (SIRR_API_KEY) or a principal key. Master key holders have full access; principal key holders are limited by their assigned role's permissions.
Organization management (creating/deleting orgs, principals, and roles) requires the master key. Day-to-day secret operations use principal keys with role-based permissions.
Create an org
Create a new organization. Requires master key authentication.
Required attributes
- Name
name- Type
- string
- Description
Human-readable name for the organization.
Optional attributes
- Name
metadata- Type
- object
- Description
Arbitrary key-value metadata for the organization.
Request
curl -X POST http://localhost:39999/orgs \
-H "Authorization: Bearer $SIRR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "acme-corp" }'
Response (201)
{
"id": "org_a1b2c3d4",
"name": "acme-corp",
"created_at": 1700000000
}
List orgs
List all organizations. Requires master key authentication.
Request
curl http://localhost:39999/orgs \
-H "Authorization: Bearer $SIRR_API_KEY"
Response
{
"orgs": [
{
"id": "org_a1b2c3d4",
"name": "acme-corp",
"created_at": 1700000000
}
]
}
Delete an org
Delete an organization. The org must have no principals — cascading deletes are not allowed. Requires master key authentication.
Path parameters
- Name
org_id- Type
- string
- Description
The ID of the organization to delete.
Request
curl -X DELETE http://localhost:39999/orgs/org_a1b2c3d4 \
-H "Authorization: Bearer $SIRR_API_KEY"
Response
{
"deleted": true
}
Create a principal
Create a new principal (user or service account) within an organization. Requires master key authentication.
Path parameters
- Name
org_id- Type
- string
- Description
The organization to create the principal in.
Required attributes
- Name
name- Type
- string
- Description
Human-readable name for the principal.
- Name
role- Type
- string
- Description
The role to assign. Built-in roles:
reader,writer,admin,owner. Custom roles can be created per-org.
Request
curl -X POST http://localhost:39999/orgs/org_a1b2c3d4/principals \
-H "Authorization: Bearer $SIRR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "ci-bot", "role": "writer" }'
Response (201)
{
"id": "prin_e5f6a7b8",
"name": "ci-bot",
"org_id": "org_a1b2c3d4",
"role": "writer",
"created_at": 1700000000
}
List principals
List all principals in an organization. Requires master key authentication.
Path parameters
- Name
org_id- Type
- string
- Description
The organization to list principals for.
Request
curl http://localhost:39999/orgs/org_a1b2c3d4/principals \
-H "Authorization: Bearer $SIRR_API_KEY"
Response
{
"principals": [
{
"id": "prin_e5f6a7b8",
"name": "ci-bot",
"org_id": "org_a1b2c3d4",
"role": "writer",
"created_at": 1700000000
}
]
}
Delete a principal
Delete a principal. The principal must have no active keys — cascading deletes are not allowed. Requires master key authentication.
Path parameters
- Name
org_id- Type
- string
- Description
The organization the principal belongs to.
- Name
id- Type
- string
- Description
The ID of the principal to delete.
Request
curl -X DELETE http://localhost:39999/orgs/org_a1b2c3d4/principals/prin_e5f6a7b8 \
-H "Authorization: Bearer $SIRR_API_KEY"
Response
{
"deleted": true
}
Create a role
Create a custom role for an organization. Requires master key authentication.
Built-in roles (reader, writer, admin, owner) are always available and cannot be modified. Custom roles let you define fine-grained permission sets.
Path parameters
- Name
org_id- Type
- string
- Description
The organization to create the role in.
Required attributes
- Name
name- Type
- string
- Description
Unique name for the role within this org.
- Name
permissions- Type
- string
- Description
Permission letter string. Each letter enables a permission bit. Example:
"rRlL"grants secret read, secret list, audit read, and audit list.
Request
curl -X POST http://localhost:39999/orgs/org_a1b2c3d4/roles \
-H "Authorization: Bearer $SIRR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "auditor", "permissions": "rRlL" }'
Response (201)
{
"name": "auditor",
"org_id": "org_a1b2c3d4",
"permissions": "rRlL"
}
List roles
List all roles (built-in and custom) for an organization. Requires master key authentication.
Path parameters
- Name
org_id- Type
- string
- Description
The organization to list roles for.
Request
curl http://localhost:39999/orgs/org_a1b2c3d4/roles \
-H "Authorization: Bearer $SIRR_API_KEY"
Response
{
"roles": [
{ "name": "reader", "permissions": "rRl", "builtin": true },
{ "name": "writer", "permissions": "rRlLcCpP", "builtin": true },
{ "name": "admin", "permissions": "rRlLcCpPaAmM", "builtin": true },
{ "name": "owner", "permissions": "rRlLcCpPaAmMdD", "builtin": true },
{ "name": "auditor", "permissions": "rRlL", "builtin": false }
]
}
Delete a role
Delete a custom role. Built-in roles cannot be deleted. Requires master key authentication.
Path parameters
- Name
org_id- Type
- string
- Description
The organization the role belongs to.
- Name
name- Type
- string
- Description
The name of the custom role to delete.
Request
curl -X DELETE http://localhost:39999/orgs/org_a1b2c3d4/roles/auditor \
-H "Authorization: Bearer $SIRR_API_KEY"
Response
{
"deleted": true
}
Get current identity
Returns the authenticated principal's identity, org, role, and permissions. Works with any principal key.
Request
curl http://localhost:39999/me \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY"
Response
{
"id": "p_e5f6a7b8",
"name": "deploy-bot",
"role": "writer",
"org_id": "org_a1b2c3d4",
"metadata": {},
"created_at": 1700000000,
"keys": [
{
"id": "k_c9d0e1f2",
"name": "ci-deploy",
"valid_after": 1700000000,
"valid_before": 1732000000,
"created_at": 1700000000
}
]
}
Update current identity
Update the authenticated principal's metadata. Works with any principal key.
Optional attributes
- Name
metadata- Type
- object
- Description
Arbitrary key-value metadata to set on the principal.
Request
curl -X PATCH http://localhost:39999/me \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY" \
-H "Content-Type: application/json" \
-d '{ "metadata": { "team": "platform" } }'
Response
{
"id": "p_e5f6a7b8",
"name": "deploy-bot",
"role": "writer",
"org_id": "org_a1b2c3d4",
"metadata": { "team": "platform" },
"created_at": 1700000000,
"keys": []
}
Create a principal key
Create a new API key for the authenticated principal. Each principal can have unlimited named keys with optional time windows.
Required attributes
- Name
name- Type
- string
- Description
Human-readable label for the key.
Optional attributes
- Name
valid_after- Type
- integer
- Description
Unix timestamp after which the key becomes valid. Omit for immediate validity.
- Name
valid_before- Type
- integer
- Description
Unix timestamp after which the key expires. Omit for no expiration.
Request
curl -X POST http://localhost:39999/me/keys \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "deploy-key",
"valid_before": 1700100000
}'
Response (201)
{
"id": "k_f3a4b5c6",
"name": "deploy-key",
"key": "sirr_key_7f3a9b2c...",
"valid_after": 1700000000,
"valid_before": 1700100000
}
The key is shown only once. Save it immediately — it cannot be retrieved later.
Delete a principal key
Permanently revoke one of the authenticated principal's keys. This is a hard delete — the key is immediately unusable.
Path parameters
- Name
key_id- Type
- string
- Description
The ID of the key to delete.
Request
curl -X DELETE http://localhost:39999/me/keys/key_f3a4b5c6 \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY"
Response
{
"deleted": true
}
Create an org secret
Create a secret within an organization scope. Requires the SecretCreate permission (c).
Path parameters
- Name
org_id- Type
- string
- Description
The organization to store the secret in.
Required attributes
- Name
key- Type
- string
- Description
Unique identifier for the secret within this org.
- Name
value- Type
- string
- Description
The secret value to encrypt and store.
Optional attributes
- Name
ttl_seconds- Type
- integer
- Description
Time-to-live in seconds. The secret is automatically destroyed after this duration.
- Name
max_reads- Type
- integer
- Description
Maximum number of reads before the secret is burned.
- Name
delete- Type
- boolean
- Description
Whether to burn (
true, default) or seal (false) on max_reads. Sealed secrets block reads but allow PATCH.
- Name
allowed_keys- Type
- array
- Description
List of principal key IDs allowed to read this secret. Omit for org-wide access.
Request
curl -X POST http://localhost:39999/orgs/org_a1b2c3d4/secrets \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"key": "DB_URL",
"value": "postgres://user:pass@db:5432/myapp",
"ttl_seconds": 3600,
"max_reads": 5
}'
Response (201)
{
"key": "DB_URL"
}
List org secrets
List metadata for all active secrets in an organization. Requires the SecretList permission (l). Secret values are never included.
Path parameters
- Name
org_id- Type
- string
- Description
The organization to list secrets for.
Request
curl http://localhost:39999/orgs/org_a1b2c3d4/secrets \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY"
Response
{
"secrets": [
{
"key": "DB_URL",
"created_at": 1700000000,
"expires_at": 1700003600,
"max_reads": 5,
"read_count": 0,
"owner_id": "prin_e5f6a7b8"
}
]
}
Retrieve an org secret
Retrieve and decrypt a secret by key within an organization. Requires the SecretRead permission (r). Each call increments the read counter. Returns 410 Gone if the secret is sealed, 404 if not found.
Path parameters
- Name
org_id- Type
- string
- Description
The organization the secret belongs to.
- Name
key- Type
- string
- Description
The key of the secret to retrieve.
Request
curl http://localhost:39999/orgs/org_a1b2c3d4/secrets/DB_URL \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY"
Response (200)
{
"key": "DB_URL",
"value": "postgres://user:pass@db:5432/myapp"
}
Sealed (410)
{
"error": "sealed",
"message": "Secret has been sealed and is no longer readable."
}
Check org secret existence
Check whether a secret exists without reading or decrypting it. Does not increment the read counter. Requires the SecretRead permission (r). Returns 200 if the secret exists, 404 otherwise.
Path parameters
- Name
org_id- Type
- string
- Description
The organization the secret belongs to.
- Name
key- Type
- string
- Description
The key to check.
Request
curl -I http://localhost:39999/orgs/org_a1b2c3d4/secrets/DB_URL \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY"
Response (200)
HTTP/1.1 200 OK
Update an org secret
Update the TTL or read limit of an existing org secret. Only works on secrets created with delete=false (sealable secrets). Requires the SecretPatch permission (P).
Path parameters
- Name
org_id- Type
- string
- Description
The organization the secret belongs to.
- Name
key- Type
- string
- Description
The key of the secret to update.
Optional attributes
- Name
ttl_seconds- Type
- integer
- Description
New time-to-live in seconds from now.
- Name
max_reads- Type
- integer
- Description
New maximum read count.
Request
curl -X PATCH http://localhost:39999/orgs/org_a1b2c3d4/secrets/DB_URL \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY" \
-H "Content-Type: application/json" \
-d '{ "ttl_seconds": 7200 }'
Response
{
"key": "DB_URL",
"updated": true
}
Delete an org secret
Permanently delete a secret from an organization. Requires the SecretDelete permission (d).
Path parameters
- Name
org_id- Type
- string
- Description
The organization the secret belongs to.
- Name
key- Type
- string
- Description
The key of the secret to delete.
Request
curl -X DELETE http://localhost:39999/orgs/org_a1b2c3d4/secrets/DB_URL \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY"
Response
{
"deleted": true
}
Prune org secrets
Delete all expired secrets within an organization. Requires the SecretPrune permission (C).
Path parameters
- Name
org_id- Type
- string
- Description
The organization to prune secrets for.
Request
curl -X POST http://localhost:39999/orgs/org_a1b2c3d4/prune \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY"
Response
{
"pruned": 7
}
Org audit logs
Query the audit log for an organization. Requires the AuditRead permission (a).
Path parameters
- Name
org_id- Type
- string
- Description
The organization to query audit logs for.
Query parameters
- Name
since- Type
- integer
- Description
Only return events after this Unix timestamp.
- Name
until- Type
- integer
- Description
Only return events before this Unix timestamp.
- Name
action- Type
- string
- Description
Filter by action type (e.g.
secret.read,secret.created).
- Name
key- Type
- string
- Description
Filter by secret key.
- Name
limit- Type
- integer
- Description
Maximum number of entries to return.
Request
curl "http://localhost:39999/orgs/org_a1b2c3d4/audit?limit=20" \
-H "Authorization: Bearer $SIRR_PRINCIPAL_KEY"
Response
{
"entries": [
{
"timestamp": 1700000100,
"action": "secret.read",
"key": "DB_URL",
"principal_id": "prin_e5f6a7b8",
"ip": "10.0.0.5"
}
]
}
Org webhooks
Manage webhooks scoped to an organization. Requires the WebhookManage permission (M).
| Endpoint | Description |
|---|---|
POST /orgs/:org_id/webhooks | Register a webhook for org events |
GET /orgs/:org_id/webhooks | List all webhooks for the org |
DELETE /orgs/:org_id/webhooks/:id | Remove an org webhook |