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.
Vault auth methods
Section titled “Vault auth methods”The runtime can authenticate to Vault in several ways:
| Method | Use case |
|---|---|
| Token | Long-lived static token; suitable for local development, discouraged in production. |
| Kubernetes | Runtime pods authenticate using projected service-account tokens. |
| JWT | Workloads or agents authenticate using SPIFFE JWT-SVIDs. |
Production deployments should use Kubernetes auth for runtime services and JWT auth for per-agentspace agent identities.
Secret resolver configuration
Section titled “Secret resolver configuration”The runtime uses a pluggable secret resolver selected by ALQUIMIA_REGISTRY_SECRET_RESOLVER:
| Resolver | Value | Use case |
|---|---|---|
| Vault | vault (default) | Production; dynamic credentials, audit logging, central rotation |
| Environment | env | Local development, CI tests, or air-gapped environments |
Vault resolver
Section titled “Vault resolver”When ALQUIMIA_REGISTRY_SECRET_RESOLVER=vault, the runtime reads:
| Variable | Description |
|---|---|
VAULT_ADDR | Vault server address |
VAULT_MOUNT_POINT | KV mount point (default secret) |
VAULT_TOKEN | Token, Kubernetes service-account JWT, or other Vault token source |
Secret references in agent specs are resolved to KV v2 paths based on their scope:
| Scope | Key format | Vault path |
|---|---|---|
global | KEY | secret/data/global/KEY |
shared | {REALM}_KEY | secret/data/{realm}/shared/KEY |
local | {REALM}_{ASSISTANT_ID}_KEY | secret/data/{realm}/local/{assistant_id}/KEY |
REALM is the agentspace_id.
Environment resolver
Section titled “Environment resolver”When ALQUIMIA_REGISTRY_SECRET_RESOLVER=env, the runtime reads secret values directly from environment variables. The same key formats apply:
export RESPONSE_PROVIDER_API_KEY="sk-..." # globalexport DEFAULT_OPENAI_API_KEY="sk-..." # shared (realm=default)export DEFAULT_SUPPORT_BOT_RESPONSE_PROVIDER_API_KEY="sk-..." # localSwitching resolvers
Section titled “Switching resolvers”# Productionexport ALQUIMIA_REGISTRY_SECRET_RESOLVER=vaultexport VAULT_ADDR=https://vault.internal:8200export VAULT_MOUNT_POINT=secretexport VAULT_TOKEN=s.xxx
# Local developmentexport ALQUIMIA_REGISTRY_SECRET_RESOLVER=envexport DEFAULT_SUPPORT_BOT_RESPONSE_PROVIDER_API_KEY="sk-..."Policy design principles
Section titled “Policy design principles”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.
Service roles
Section titled “Service roles”At minimum, separate the runtime into two service roles:
| Role | Typical access |
|---|---|
| Master | Read/write registry and agentspace secrets, manage identity provisioning, lease its own database credentials. |
| Worker | Read 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.
Agentspace provisioning with SPIFFE / JWT
Section titled “Agentspace provisioning with SPIFFE / JWT”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}-agentsroles: as-{agentspace_id}-reader as-{agentspace_id}-editor as-{agentspace_id}-operatorEach 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.
Dynamic credentials
Section titled “Dynamic credentials”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.
Static secrets
Section titled “Static secrets”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.
Bootstrapping checklist
Section titled “Bootstrapping checklist”Before the runtime starts in production:
- Enable the required secrets engines: KV v2, database, and any others you need.
- Enable the Kubernetes and JWT auth backends.
- Write a master policy scoped to registry, identity provisioning, and its own credentials.
- Write worker policies scoped to the agentspaces they serve.
- Configure Kubernetes auth roles bound to the runtime service account.
- Configure the JWT auth backend with the SPIFFE trust-domain keys.
- Populate KV secrets for static credentials.
- Set the runtime environment to use Kubernetes auth and the correct Vault role.