Workspace

Secrets Management

Open Astra supports three secret backends for managing API keys and sensitive values, plus per-workspace API key overrides so tenants can supply their own credentials without exposing platform keys.

Secret backends

Set SECRET_BACKEND to select the backend. All backends use an in-process TTL cache (default 5 minutes) to avoid redundant network calls. On cache miss, every secret read is recorded to secret_audit_log.

BackendValueWhen to use
Environment (default)envDevelopment and simple deployments — reads directly from process.env
HashiCorp VaultvaultProduction — fetches the entire KV v2 secret blob and caches all keys
AWS Secrets Manageraws-asmAWS-native production — fetches a JSON-valued ASM secret

HashiCorp Vault (KV v2)

Store all Astra secrets as a single JSON object at a KV v2 path. The gateway fetches the whole blob on startup and caches individual keys with a 5-minute TTL.

bash
SECRET_BACKEND=vault
VAULT_ADDR=http://vault:8200
VAULT_TOKEN=s.xxxx
# Optional: custom path (default: secret/data/astra)
VAULT_PATH=secret/data/astra
SECRET_TTL_SECONDS=300

The Vault secret object should be a flat JSON map of env var name → value:

json
{
  "JWT_SECRET": "...",
  "ANTHROPIC_API_KEY": "sk-ant-...",
  "TYPESENSE_API_KEY": "...",
  "INTERNAL_API_KEY": "..."
}

AWS Secrets Manager

Requires @aws-sdk/client-secrets-manager installed at runtime. The secret value must be a JSON-encoded object with env var names as keys.

bash
SECRET_BACKEND=aws-asm
AWS_REGION=us-east-1
AWS_SECRET_ID=prod/astra
# Also needs AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (or an IAM role)
💡For Kubernetes deployments, use the included k8s/external-secrets.yaml (External Secrets Operator) to sync AWS ASM secrets automatically into a Kubernetes Secret that the pod mounts as environment variables.

Fallback behaviour

If a Vault or ASM fetch fails at runtime (network error, token expiry), the gateway falls back to process.env for that key and logs a warning. The secret is not cached after a fallback fetch, so the next request will retry the remote backend.

Per-workspace API key overrides

Workspace owners and admins can store their own API keys for supported providers. When an agent runs inside that workspace, its provider client uses the workspace key instead of the platform-level env var. This enables multi-tenant SaaS deployments where each customer brings their own credentials.

Overrideable keys

Env varProvider
OPENAI_API_KEYOpenAI
ANTHROPIC_API_KEYAnthropic (Claude)
GEMINI_API_KEYGoogle Gemini
GROK_API_KEYxAI Grok
GROQ_API_KEYGroq
BRAVE_API_KEYBrave Search
RESEND_API_KEYResend (Email)

Setting a workspace secret

Requires owner or admin role. Values are stored encrypted in the workspace_secrets table. An optional expiry can be set in days.

bash
# Set a per-workspace API key (owner or admin only)
curl -X PUT http://localhost:3000/workspaces/ws_abc123/secrets/ANTHROPIC_API_KEY \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{ "value": "sk-ant-...", "expiresInDays": 90 }'

Listing workspace secrets

Returns metadata only — secret values are never returned by any API endpoint.

bash
# List secret metadata (values are never returned)
curl http://localhost:3000/workspaces/ws_abc123/secrets \
  -H "Authorization: Bearer ${JWT_TOKEN}"

# Response
[
  {
    "key": "ANTHROPIC_API_KEY",
    "setBy": "usr_xyz",
    "updatedAt": "2026-02-26T10:00:00Z",
    "expiresAt": "2026-05-26T10:00:00Z"
  }
]

Deleting a workspace secret

bash
curl -X DELETE http://localhost:3000/workspaces/ws_abc123/secrets/ANTHROPIC_API_KEY \
  -H "Authorization: Bearer ${JWT_TOKEN}"

Audit trail

Every secret read (cache hit or remote fetch) is recorded to the secret_audit_log table with the key name, backend used, and timestamp. All sensitive gateway operations (auth, workspace changes, secret writes) are also recorded to the audit_log table via the event bus. Both tables are created by migration 023-security-rbac.sql.

TableRecords
secret_audit_logEvery secret key read: key name, backend, timestamp
audit_logSensitive operations: auth events, workspace changes, admin actions
The audit_log is populated by an event bus subscriber (src/events/audit.ts) that listens for structured events emitted by gateway routes. No additional configuration is required — it runs automatically when the gateway starts.