Skip to content

Vault policies

HashiCorp Vault is the recommended secret store for Alquimia Platform. Well-designed Vault policies let the runtime resolve credentials with the least privilege required, support rotation, and keep audit records for every secret access.

The runtime can authenticate to Vault in several ways:

MethodUse case
TokenLong-lived static token; suitable for local development, discouraged in production.
KubernetesRuntime pods authenticate using projected service-account tokens.
JWTWorkloads or agents authenticate using SPIFFE JWT-SVIDs.

Production deployments should use Kubernetes auth for runtime services and JWT auth for per-agentspace agent identities.

The runtime uses a pluggable secret resolver selected by ALQUIMIA_REGISTRY_SECRET_RESOLVER:

ResolverValueUse case
Vaultvault (default)Production; dynamic credentials, audit logging, central rotation
EnvironmentenvLocal development, CI tests, or air-gapped environments

When ALQUIMIA_REGISTRY_SECRET_RESOLVER=vault, the runtime reads:

VariableDescription
VAULT_ADDRVault server address
VAULT_MOUNT_POINTKV mount point (default secret)
VAULT_TOKENToken, Kubernetes service-account JWT, or other Vault token source

Secret references in agent specs are resolved to KV v2 paths based on their scope:

ScopeKey formatVault path
globalKEYsecret/data/global/KEY
shared{REALM}_KEYsecret/data/{realm}/shared/KEY
local{REALM}_{ASSISTANT_ID}_KEYsecret/data/{realm}/local/{assistant_id}/KEY

REALM is the agentspace_id.

When ALQUIMIA_REGISTRY_SECRET_RESOLVER=env, the runtime reads secret values directly from environment variables. The same key formats apply:

Terminal window
export RESPONSE_PROVIDER_API_KEY="sk-..." # global
export DEFAULT_OPENAI_API_KEY="sk-..." # shared (realm=default)
export DEFAULT_SUPPORT_BOT_RESPONSE_PROVIDER_API_KEY="sk-..." # local
Terminal window
# Production
export ALQUIMIA_REGISTRY_SECRET_RESOLVER=vault
export VAULT_ADDR=https://vault.internal:8200
export VAULT_MOUNT_POINT=secret
export VAULT_TOKEN=s.xxx
# Local development
export ALQUIMIA_REGISTRY_SECRET_RESOLVER=env
export DEFAULT_SUPPORT_BOT_RESPONSE_PROVIDER_API_KEY="sk-..."

A good Vault policy for Alquimia Platform follows these principles:

  • Scope by role — masters need broader registry access than workers.
  • Scope by agentspace — workers serving one agentspace should not read secrets from another.
  • Use dynamic credentials — prefer Vault database secrets engines for PostgreSQL and Redis over static passwords.
  • Avoid broad wildcards — grant access only to the paths each service actually needs.
  • Log everything — enable audit devices so every read and write is recorded.

At minimum, separate the runtime into two service roles:

RoleTypical access
MasterRead/write registry and agentspace secrets, manage identity provisioning, lease its own database credentials.
WorkerRead global secrets and the agentspace it serves, lease its own database credentials, no registry write access.

When agentspace isolation is required, generate a dedicated worker policy for each agentspace or use SPIFFE-based JWT roles created by the agentspace provisioner.

When AGENTSPACE_PROVISIONING_ENABLED=true, the runtime master creates a scoped Vault ACL policy and three JWT auth roles per agentspace:

policy: as-{agentspace_id}-agents
roles: as-{agentspace_id}-reader
as-{agentspace_id}-editor
as-{agentspace_id}-operator

Each role is bound to a SPIFFE ID such as spiffe://alquimia.ai/agentspace/{agentspace_id}/tier/{reader|editor|operator}. Agents authenticate to Vault with their JWT-SVID and receive a token scoped to their agentspace and role tier. This is the recommended way to enforce least-privilege secret access for agent identities.

Configure the Vault JWT auth mount path with AGENTSPACE_PROVISIONING_VAULT_JWT_AUTH_PATH (default jwt). See Runtime configuration and Authorization policies for the full Zero Trust flow.

Vault database secrets engines can issue short-lived PostgreSQL and Redis credentials. The runtime leases these credentials at startup, renews them while in use, and revokes them on shutdown. This reduces the value of stolen credentials and removes the need for manual rotation.

When using dynamic credentials:

  • Create a least-privilege database role for the runtime.
  • Set TTLs that match your compliance requirements without causing excessive churn.
  • Ensure the database user created by Vault can be dropped cleanly when the lease expires.

Some credentials, such as provider API keys and S3 access keys, do not support dynamic issuance. Store these as KV v2 secrets and rotate them manually or through an automated pipeline. Keep the secret reference name stable so agent specs do not need to change during rotation.

Before the runtime starts in production:

  1. Enable the required secrets engines: KV v2, database, and any others you need.
  2. Enable the Kubernetes and JWT auth backends.
  3. Write a master policy scoped to registry, identity provisioning, and its own credentials.
  4. Write worker policies scoped to the agentspaces they serve.
  5. Configure Kubernetes auth roles bound to the runtime service account.
  6. Configure the JWT auth backend with the SPIFFE trust-domain keys.
  7. Populate KV secrets for static credentials.
  8. Set the runtime environment to use Kubernetes auth and the correct Vault role.