Server & Backend›Secrets & Sync Protocol
Secrets & Sync Protocol
The secrets synchronization protocol enables multi-device and multi-user secret sharing without the server ever processing or storing plaintext credentials.
Double-Envelope Secret Lifecycle
[ Developer Machine ] [ agentsecrets-server ] Plaintext Secret (sk_live_...) │ ▼ (AES-256-GCM using project key) Client Ciphertext (Opaque Base64) │ ▼ (POST /api/secrets/) JSON Payload ─────────────────────────────────────► Double-Envelope (Fernet) └── Client Ciphertext (PostgreSQL)
- Client Encryption: The
agentsecretsCLI encrypts secrets using AES-256-GCM with an ephemeral project key derived from the workspace key. - Metadata Preservation: Key names (e.g.
STRIPE_API_KEY) and optional secret-level policies (e.g. allowed domains) are transmitted alongside ciphertext to enable sync coordination and proxy enforcement. - At-Rest Double Envelope:
agentsecrets-serverapplies an outer Fernet encryption layer before persisting records to PostgreSQL. - Client Retrieval: When a client requests secrets via
GET /api/secrets/{project_id}/, the server strips its outer Fernet layer and returns the client-encrypted ciphertext blobs. The client performs local AES decryption.
Sync API Endpoints
1Bulk Upsert Secrets ()
Performs an atomic, multi-secret upsert for a specific project and environment.
Request Payload:
{ "project_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "environment": "development", "secrets": [ { "key": "STRIPE_API_KEY", "value": "base64_aes_gcm_ciphertext_blob_here", "policy": { "allowed_domains": ["api.stripe.com"], "allowed_methods": ["GET", "POST"] } }, { "key": "DATABASE_URL", "value": "base64_aes_gcm_ciphertext_blob_here", "policy": null } ] }
Response Envelope:
{ "status": "success", "data": { "created": 2, "updated": 0 } }
2List Project Secrets ()
Lists encrypted secret keys and metadata for a specific project.
- Query Parameters:
environment(optional, defaults todevelopment)
- Response:
{ "status": "success", "data": [ { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "key": "STRIPE_API_KEY", "created_at": "2026-08-20T10:00:00Z", "updated_at": "2026-08-20T10:00:00Z" } ] }
3Retrieve Secret Ciphertext ()
Retrieves the encrypted ciphertext and execution policy for a single secret key.
- Query Parameters:
environment(optional, defaults todevelopment)
- Response:
{ "status": "success", "data": { "key": "STRIPE_API_KEY", "value": "base64_aes_gcm_ciphertext_blob_here", "policy": { "allowed_domains": ["api.stripe.com"], "allowed_methods": ["GET", "POST"] } } }
4Delete Secret ()
Permanently deletes a secret key from the specified environment.
- Query Parameters:
environment(optional, defaults todevelopment)
Was this helpful?
Thanks for your feedback!
Your feedback helps us improve the platform.