Runtime configuration reference
alquimia-runtime is configured through environment variables (and an optional .env file). Environment variables always take precedence over values in .env.
Required secrets
Section titled “Required secrets”The following secrets must be set before the runtime starts. They are never committed to version control.
| Secret | Purpose |
|---|---|
API_TOKEN | Bearer token for all authenticated endpoints. Required at startup in every runtime mode (master, worker, all) and with every AUTH_PROVIDER, including keycloak |
POSTGRES_USERNAME / POSTGRES_PASSWORD | PostgreSQL credentials. POSTGRES_PASSWORD may be omitted only when VAULT_POSTGRES_ENABLED=true |
BLOB_S3_ACCESS_KEY / BLOB_S3_SECRET_KEY | S3-compatible blob storage credentials |
KAFKA_SIGNING_KEY | 64-character hex key shared across all runtime instances. Used to sign and verify events between masters and workers |
Vault credentials depend on VAULT_AUTH_METHOD: a static VAULT_TOKEN is only used with token auth (local development). Kubernetes deployments use Vault Kubernetes auth instead; see External services.
Optionally, set ENCRYPTION_KEY (64-character hex) to enable application-layer AES-256-GCM encryption of Redis conversations and PostgreSQL worklog data at rest. Leave it empty to store data in plaintext.
Service settings
Section titled “Service settings”| Variable | Required | Default | Description |
|---|---|---|---|
BACKEND_SERVER_HOST | No | 0.0.0.0 | Bind address |
BACKEND_SERVER_PORT | No | 8080 | Listen port |
BACKEND_SERVER_WORKERS | No | 1 | Uvicorn worker count |
BACKEND_TIMEOUT_KEEP_ALIVE | No | 300 | Keep-alive timeout (seconds) |
DEBUG | No | false | Enable debug mode and verbose logging |
RESPONSE_MAX_RETRIES | No | 3 | Max retries for inference responses |
A2A_MAX_DEPTH | No | 5 | Maximum agent-to-agent call depth |
MAX_FILE_CONTENT_SIZE | No | 20971520 | Max knowledge file upload size in bytes (default 20 MB) |
Runtime mode
Section titled “Runtime mode”| Variable | Required | Default | Description |
|---|---|---|---|
ALQUIMIA_RUNTIME_MODE | No | master | master serves the external API (registry read/write); worker consumes Kafka events and opens the registry read-only. Use all for single-process local deployments |
In production, run master and worker as separate deployments so they can scale independently. Setting ALQUIMIA_RUNTIME_MODE=worker prevents the local registry from being mutated by inference pods.
The master must run exactly one replica with the Recreate deployment strategy: it is the single writer of the TinyDB registry (guarded by a Redis Redlock). Scale throughput with workers only, up to the partition count of the alquimia.events topic (6 in the shipped manifests); extra workers beyond that sit idle.
Authentication and security
Section titled “Authentication and security”| Variable | Required | Default | Description |
|---|---|---|---|
API_TOKEN | Yes | — | Bearer token for all authenticated endpoints. Required on masters and workers, whatever AUTH_PROVIDER is set to |
AUTH_PROVIDER | No | api_token | Auth backend: api_token, jwt, or keycloak |
JWT_SECRET | Conditional | "" | Required when AUTH_PROVIDER=jwt |
JWT_ALGORITHM | No | HS256 | JWT signing algorithm |
KEYCLOAK_SERVER_URL | Conditional | "" | Required when AUTH_PROVIDER=keycloak |
KEYCLOAK_REALM | Conditional | "" | Keycloak realm |
KEYCLOAK_CLIENT_ID | Conditional | "" | Keycloak client ID |
KEYCLOAK_CLIENT_SECRET | Conditional | "" | Keycloak client secret |
KEYCLOAK_ADMIN_CLIENT_SECRET | No | "" | Falls back to KEYCLOAK_CLIENT_SECRET |
KEYCLOAK_CALLBACK_URI | No | "" | OAuth callback URI |
KEYCLOAK_ACCEPTED_AUDIENCES | No | alquimia-runtime | Comma-separated accepted token audiences. Must not be empty and must not contain account (startup fails) |
KEYCLOAK_ROLE_SOURCE_CLIENTS | No | alquimia-runtime,alquimia-studio-service,alquimia-ci | Comma-separated Keycloak client IDs whose client roles are honoured in addition to realm roles |
IS_ALLOWED_CREDENTIALS | No | true | CORS allow credentials |
ALLOWED_ORIGINS | No | ["*"] | CORS allowed origins. Cannot be ["*"] when IS_ALLOWED_CREDENTIALS=true |
ALLOWED_METHODS | No | ["*"] | CORS allowed methods |
ALLOWED_HEADERS | No | ["*"] | CORS allowed headers |
See Authentication & authorization for the conceptual model and deployment patterns.
Channel ingress authentication
Section titled “Channel ingress authentication”Channel webhook endpoints (/event/infer/{assistant_id}/{channel_id}) do not use the global bearer token. The runtime delegates authentication to the channel implementation from alquimia-core.
| Variable | Required | Default | Description |
|---|---|---|---|
CHANNEL_AUTH_REQUIRED | No | true | Require every channel to implement provider-specific auth |
CHANNEL_MAX_BODY_SIZE | No | 1048576 | Max channel webhook body size in bytes (default 1 MB) |
CHANNEL_RATE_LIMIT_ENABLED | No | true | Enable per-source rate limiting |
CHANNEL_RATE_LIMIT_REQUESTS | No | 60 | Allowed requests per source per window |
CHANNEL_RATE_LIMIT_WINDOW_SECONDS | No | 60 | Rate-limit window |
See Channels and Connect a channel for provider-specific setup.
Streaming voice channel
Section titled “Streaming voice channel”The WS /streaming/{assistant_id}/{channel_id} endpoint is used for held-call audio streams such as Twilio Media Streams. The settings below replace the old STREAMING_* variables from earlier runtime versions; the previous names are no longer read.
| Variable | Required | Default | Description |
|---|---|---|---|
STREAMING_CHANNEL_AUTH_REQUIRED | No | true | Require channel-specific authentication (for example, Twilio Account SID validation) |
STREAMING_CHANNEL_RATE_LIMIT_ENABLED | No | true | Enable per-source concurrent session limits |
STREAMING_CHANNEL_MAX_SESSIONS_PER_SOURCE | No | 10 | Maximum concurrent streaming sessions allowed from a single source |
STREAMING_CHANNEL_MAX_SESSION_SECONDS | No | 3600 | Maximum lifetime of a streaming session in seconds |
See Connect a messaging or voice channel and Runtime API overview for the WebSocket path and message flow.
SPIFFE / SPIRE workload identity
Section titled “SPIFFE / SPIRE workload identity”| Variable | Required | Default | Description |
|---|---|---|---|
SPIFFE_ENABLED | No | false | Enable SPIFFE workload identity |
SPIFFE_SOCKET_PATH | No | /tmp/spire-agent/public/api.sock | Path to the SPIFFE Workload API socket |
SPIFFE_TRUST_DOMAIN | No | alquimia.ai | SPIFFE trust domain |
AGENTSPACE_PROVISIONING_ENABLED | No | false | Automate SPIRE entries and Vault roles per agentspace |
AGENTSPACE_PROVISIONING_INTERVAL_SECONDS | No | 300 | Reconciliation interval |
AGENTSPACE_PROVISIONING_K8S_NAMESPACE | No | spire | Namespace for ClusterStaticEntry CRDs |
AGENTSPACE_PROVISIONING_VAULT_JWT_AUTH_PATH | No | jwt | Vault JWT auth mount path |
When AGENTSPACE_PROVISIONING_ENABLED=true, the master creates or updates SPIRE ClusterStaticEntry CRDs, scoped Vault ACL policies, and JWT auth roles for each agentspace. A background reconciler runs every AGENTSPACE_PROVISIONING_INTERVAL_SECONDS seconds to converge state with the registry list. This is what produces per-agentspace, per-tier identities that agents use to authenticate to Vault.
See Workload hardening and Authorization policies for the Zero Trust deployment pattern.
| Variable | Required | Default | Description |
|---|---|---|---|
KAFKA_BOOTSTRAP_SERVERS | No | localhost:9092 | Broker address(es) |
KAFKA_TOPIC | No | alquimia.events | Topic for agent events |
KAFKA_CONSUMER_GROUP | No | alquimia-workers | Consumer group for workers |
KAFKA_SIGNING_KEY | Yes | "" | 64-character hex signing key shared by all instances |
KAFKA_SECURITY_PROTOCOL | No | PLAINTEXT | SASL_SSL or SSL in production |
KAFKA_SASL_MECHANISM | No | "" | SASL mechanism, e.g. SCRAM-SHA-256 |
KAFKA_SASL_USERNAME | No | "" | SASL username |
KAFKA_SASL_PASSWORD | No | "" | SASL password |
KAFKA_SSL_CA_FILE | No | "" | Path to CA certificate for broker verification |
KAFKA_SSL_CERT_FILE | No | "" | Path to client certificate for mTLS |
KAFKA_SSL_KEY_FILE | No | "" | Path to client key for mTLS |
KAFKA_SSL_VERIFY | No | true | Verify broker certificate hostname |
KAFKA_DLQ_TOPIC | No | alquimia.events.dlq | Dead-letter topic. Receives events that fail HMAC signature verification and events whose processing raised an error; they are routed there rather than dropped |
External services
Section titled “External services”| Variable | Required | Default | Description |
|---|---|---|---|
REDIS_URL | No | redis://localhost:6379 | Redis connection URL. See the TLS caution below before using rediss:// |
REDIS_TTL | No | 86400 | Default TTL for Redis keys (seconds) |
POSTGRES_HOST | No | localhost | PostgreSQL host |
POSTGRES_PORT | No | 5432 | PostgreSQL port |
POSTGRES_DB | No | alquimia | Database name |
POSTGRES_USERNAME | Yes | — | Database user |
POSTGRES_PASSWORD | Conditional | "" | Database password. Required unless VAULT_POSTGRES_ENABLED=true, in which case credentials are leased from Vault |
POSTGRES_SCHEMA | No | postgresql | SQLAlchemy schema prefix |
DB_POOL_SIZE | No | 60 | Connection pool size, per process |
DB_MAX_POOL_CON | No | 80 | Not read by the runtime; the effective per-process ceiling is DB_POOL_SIZE + DB_POOL_OVERFLOW |
DB_POOL_OVERFLOW | No | 20 | Pool overflow limit, per process |
DB_POOL_PRE_PING | No | true | Pre-ping connections before use |
DB_POOL_RECYCLE | No | 1800 | Connection recycle interval (seconds) |
DB_TIMEOUT | No | 5 | Query timeout (seconds) |
DB_CREATE_ON_STARTUP | No | false | Auto-create tables on startup (dev only) |
IS_DB_ECHO_LOG | No | false | Log all SQL statements |
QDRANT_URL | No | http://localhost:6333 | Qdrant vector store URL |
QDRANT_API_KEY | No | — | Qdrant API key (optional) |
ALQUIMIA_KNOWLEDGE_PROVIDER | Recommended | qdrant | Knowledge-base backend: qdrant, redis, or in_memory. The runtime exports this value to alquimia-core, where it replaces the connector declared on every topic-based, connector-backed knowledge base in the process. Set it explicitly: alquimia-core on its own (CLI/SDK) has no single default — inference keeps the spec’s connector, ingest/rebuild fall back to qdrant, and version rehydration is skipped when it is unset |
VAULT_ADDR | No | vault | HashiCorp Vault address. Use a full URL with scheme and port (for example https://vault.internal:8200); alquimia-core uses the value verbatim |
VAULT_MOUNT_POINT | No | secret | Vault KV v2 mount point. cubbyhole does not work (it is a per-token store) |
VAULT_AUTH_METHOD | No | token | Vault login method: token, kubernetes, or jwt. Use kubernetes in Kubernetes |
VAULT_TOKEN | Conditional | "" | Static Vault token; only used with VAULT_AUTH_METHOD=token (local development). The alquimia-vault Secret was removed from the Kubernetes manifests in favour of Kubernetes auth |
VAULT_K8S_ROLE | Conditional | "" | Vault Kubernetes auth role for the runtime’s own Vault client. Required with kubernetes auth |
VAULT_AUTH_ROLE | Conditional | — | Vault auth role for the alquimia-core secret resolver (registry secret resolution). Required with kubernetes or jwt auth, in addition to VAULT_K8S_ROLE |
VAULT_K8S_TOKEN_PATH | No | /var/run/secrets/kubernetes.io/serviceaccount/token | Service-account token used for Kubernetes auth. Point it at a projected token with audience vault |
VAULT_JWT_ROLE | Conditional | "" | Vault JWT auth role for the runtime; required with jwt auth |
VAULT_JWT_SVID | Conditional | "" | JWT-SVID used for jwt auth. In runtime ≤ 0.5.4 this must contain the token itself, not a file path |
Blob storage (S3 / Alarik)
Section titled “Blob storage (S3 / Alarik)”| Variable | Required | Default | Description |
|---|---|---|---|
BLOB_S3_ENDPOINT_URL | Yes | "" | S3-compatible endpoint, e.g. http://alarik:8080 |
BLOB_S3_PROVIDER | No | Minio | rclone S3 provider name. Keep the default Minio for Alarik and other S3-compatible servers; it is the rclone provider name for generic S3-compatible endpoints, not a MinIO dependency |
BLOB_S3_ACCESS_KEY | Yes | "" | S3 access key |
BLOB_S3_SECRET_KEY | Yes | "" | S3 secret key |
BLOB_S3_BUCKET_NAME | Yes | "" | Bucket name |
BLOB_S3_REGION_NAME | No | us-east-1 | S3 region |
BLOB_S3_SECURE | No | true | Use TLS for S3 connections. Has no effect when BLOB_S3_ENDPOINT_URL starts with http://; use an https:// endpoint in production |
Registry and OCI
Section titled “Registry and OCI”| Variable | Required | Default | Description |
|---|---|---|---|
ALQUIMIA_REGISTRY_DIR | No | ~/.local/share/alquimia | Local path for TinyDB registry files |
ALQUIMIA_EMBEDDINGS_CONFIG_DIR | No | $ALQUIMIA_REGISTRY_DIR | Directory containing embeddings.yaml. The Kubernetes manifests mount it at /var/lib/alquimia/embeddings.yaml and set this to /var/lib/alquimia |
ALQUIMIA_OCI_REGISTRY_DEFAULT | No | ghcr.io | Default OCI registry for push/pull |
ALQUIMIA_OCI_NAMESPACE_AGENTSPACES | No | agents | Deployment-owned namespace for agentspace artifacts and their index anchor (0.5.3+) |
ALQUIMIA_OCI_NAMESPACE_BRAINS | No | brains | Deployment-owned namespace for brain artifacts and their index anchor (0.5.3+) |
ALQUIMIA_REGISTRY_SECRET_RESOLVER | No | vault | Secret resolver backend: vault or env. env reads directly from environment variables |
ALQUIMIA_OCI_SIGNATURE_POLICY | No | required | Signature verification policy: required, warn, or off. required aborts on missing/invalid signatures; warn logs and continues; off skips verification. With required and no verification key or keyless identity configured, every pull fails |
ALQUIMIA_OCI_COSIGN_PUBKEY | No | — | Cosign public key (path or KMS/env:// reference) used to verify signatures on pull. Falls back to ALQUIMIA_OCI_COSIGN_KEY |
ALQUIMIA_OCI_COSIGN_KEY | No | — | Cosign signing (private) key used on push. Only works as the verification fallback for KMS/env:// references; for on-disk key pairs set ALQUIMIA_OCI_COSIGN_PUBKEY |
ALQUIMIA_OCI_COSIGN_CERT_IDENTITY | No | — | Keyless verification certificate identity (use with _CERT_OIDC_ISSUER) |
ALQUIMIA_OCI_COSIGN_CERT_OIDC_ISSUER | No | — | Keyless verification OIDC issuer |
ALQUIMIA_OCI_INDEX_ENABLED | No | false | Enable OCI 1.1 referrers-based namespace index lifecycle: attach on push, detach on delete, discover for listings (0.5.3+) |
ALQUIMIA_OCI_SUBPROCESS_TIMEOUT | No | 120 | Timeout in seconds for OCI push/delete_manifest/pull subprocesses running in the asyncio thread pool (0.5.4+) |
ALQUIMIA_OCI_COSIGN_SIGN_PUSH | No | auto | auto signs on push only when a key or keyless identity is configured; true always tries; false never signs |
ALQUIMIA_OCI_COSIGN_TLOG_UPLOAD | No | false | Upload key-based signatures to the public Rekor transparency log |
ALQUIMIA_OCI_COSIGN_HOME | No | temp dir | Writable directory cosign uses as HOME (needed with a read-only root filesystem) |
ALQUIMIA_OCI_REFERRERS_FALLBACK | No | error | Behaviour when the registry lacks native OCI referrers support. Only the exact value warn enables ORAS’s fallback; any other value behaves as error. warn accepts silently lost index writes under concurrent attaches |
ALQUIMIA_OCI_DEV_MODE | No | false | Enable insecure ORAS transport flags (dev only) |
ORAS_PLAIN_HTTP | No | false | Use plain HTTP for ORAS (ignored unless ALQUIMIA_OCI_DEV_MODE=true; keep off in production) |
ORAS_INSECURE | No | false | Skip TLS verification for ORAS (ignored unless ALQUIMIA_OCI_DEV_MODE=true; keep off in production) |
Registry credentials for ORAS and cosign come from the Docker config ($DOCKER_CONFIG/config.json, default ~/.docker/config.json).
Registry encryption at rest
Section titled “Registry encryption at rest”When ALQUIMIA_REGISTRY_KEY is set, the local TinyDB registry files (metadata.json, <agentspace>/dist.json) are transparently encrypted with AES-256-GCM. The key is a Base64-encoded AES-256 key sourced from Vault or another secret injector.
| Variable | Required | Default | Description |
|---|---|---|---|
ALQUIMIA_REGISTRY_KEY | No | — | Base64-encoded AES-256 key for encryption at rest |
ALQUIMIA_REGISTRY_KEY_ID | No | default | Key identifier stored in the ciphertext envelope (rotation support) |
Encryption at rest protects against volume or bucket exposure. It does not protect against a compromised runtime process, which can still read decrypted data through the registry APIs. In production, run workers with ALQUIMIA_RUNTIME_MODE=worker so the registry is mounted read-only.
Changing ALQUIMIA_REGISTRY_KEY_ID alongside a new key causes the next write to re-encrypt with the new envelope. If ALQUIMIA_REGISTRY_KEY is absent, the registry falls back to plaintext for backward compatibility.
File storage provider
Section titled “File storage provider”Registered topic files are stored outside the registry in a pluggable storage backend selected at deployment time.
| Variable | Required | Default | Description |
|---|---|---|---|
ALQUIMIA_FILE_STORAGE_PROVIDER | No | local | Storage backend: local or s3 |
ALQUIMIA_FILE_STORAGE_LOCAL_DIR | No | $ALQUIMIA_REGISTRY_DIR/files | Local filesystem root for local provider |
ALQUIMIA_FILE_STORAGE_S3_ENDPOINT_URL | Conditional | — | Required for s3 |
ALQUIMIA_FILE_STORAGE_S3_ACCESS_KEY | Conditional | — | Required for s3 |
ALQUIMIA_FILE_STORAGE_S3_SECRET_KEY | Conditional | — | Required for s3 |
ALQUIMIA_FILE_STORAGE_S3_BUCKET | Conditional | — | Required for s3 |
ALQUIMIA_FILE_STORAGE_S3_REGION | No | us-east-1 | AWS region for s3 |
The same provider is used by search_mode="direct" file reads and by alquimia registry topics add-file.
In alquimia-core ≤ 0.5.6 the s3 provider does not use the AWS default credential chain: set the endpoint URL, access key, and secret key explicitly, even on AWS.
Boltzmann brains
Section titled “Boltzmann brains”| Variable | Required | Default | Description |
|---|---|---|---|
BRAIN_STORE | No | memory | Where served brains live: memory, or layout:<root> |
BRAIN_CACHE_TTL | No | 300 | Seconds before a cached brain is revalidated |
BRAIN_CACHE_MAX_BRAINS | No | 4 | LRU cache size limit |
BRAIN_WARMUP_ENABLED | No | true | Open registered brains at worker startup |
Observability
Section titled “Observability”| Variable | Required | Default | Description |
|---|---|---|---|
OTEL_COLLECTOR_ENDPOINT_TRACES | No | — | OTLP HTTP endpoint for traces |
OTEL_COLLECTOR_ENDPOINT_LOGS | No | traces endpoint | OTLP HTTP endpoint for logs |
OTEL_COLLECTOR_ENDPOINT | No | — | OTLP HTTP endpoint for metrics |
OTEL_ALQUIMIA_SERVICE_NAME | No | alquimia | Service name reported to OTEL |
OTEL_ALQUIMIA_METER_NAME | No | alquimia-metrics | Meter name for metrics |
OTEL_EXPORTER_INTERVAL_MILLIS | No | 5000 | Metrics export push interval |
OTEL_EXCLUDED_ATTRIBUTES | No | "" | Comma-separated metric attribute keys to strip before export |
See Observability for how the signals correlate.