Secrets
Encrypted storage for sensitive values such as API keys and credentials.
Overview
Secrets are associated with a project. Values are encrypted at rest using AES-256-GCM and are never returned by any API response. Once stored, a secret's value can only be replaced. All operations return a has_value boolean to indicate whether an encrypted value is on file.
Secrets can be linked to AI Providers to supply credentials at inference time.
See the Permissions Reference for the IAM action strings for this module.
Related Tutorials
- Connect Third-Party LLMs - Step 3 (Store provider credentials as secrets)
- Connect Third-Party LLMs - Step 4 (Create provider records)
Data Model
| Field | Type | Description |
|---|---|---|
id | string | Public identifier (e.g. sec_…) |
project_id | string | ID of the owning project |
name | string | Human-readable label |
has_value | boolean | true when an encrypted value is stored |
created_at | string | ISO 8601 creation timestamp |
updated_at | string | ISO 8601 last-updated timestamp |
Key Concepts
Deletion
By default, deleting a secret that is still referenced by one or more AI providers returns 409 Conflict. Pass ?force=true to cascade-delete the dependent AI providers along with the secret.
Configuration
| Environment Variable | Required | Description |
|---|---|---|
SECRETS_ENCRYPTION_KEY | Yes | 64-character hex string (32 bytes). Used for AES-256-GCM encryption of all stored secret values. |
Generate a key with:
openssl rand -hex 32
Examples
Create a secret
- CLI
- SDK
- curl
soat create-secret --project-id proj_ABC --name "OpenAI Key"
import { SoatClient } from '@soat/sdk';
const soat = new SoatClient({ baseUrl: 'https://api.example.com', token: 'sk_...' });
const { data, error } = await soat.secrets.createSecret({
body: { project_id: 'proj_ABC', name: 'OpenAI Key' },
});
if (error) throw new Error(JSON.stringify(error));
curl -X POST https://api.example.com/api/v1/secrets \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"project_id": "proj_ABC", "name": "OpenAI Key"}'
Update secret value
- CLI
- SDK
- curl
soat update-secret --secret-id sec_01 --value sk-abc123...
const { data, error } = await soat.secrets.updateSecret({
path: { secret_id: 'sec_01' },
body: { value: 'sk-abc123...' },
});
if (error) throw new Error(JSON.stringify(error));
curl -X PATCH https://api.example.com/api/v1/secrets/sec_01 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"value": "sk-abc123..."}'