Configuration Reference
What you'll learn: All environment variables for the SDK, engine, and platform API.
SDK / Engine configuration
Precedence (highest to lowest): explicit kwargs > environment variables > .env in cwd > built-in defaults.
Authentication and identity
KV_API_URL
https://platform.kyvvu.com
Base URL of the Kyvvu platform API.
KV_API_KEY
--
Bearer API key (KvKey-...). Required for policy fetch.
KV_AGENT_KEY
--
Stable agent identifier used to fetch policies.
KV_INSTANCE_ID
auto-generated
Identifier for this runner instance. A random suffix is appended to prevent collisions.
Log output
KV_LOG_LOCATION
stdout
WHERE logs go. URL → HTTP POST, file path → JSONL, stdout → terminal, none/empty → disabled.
KV_LOG_FORMAT
kv
HOW logs are formatted: kv (Kyvvu batch API), json, or otlp.
KV_INCIDENT_LOCATION
unset (inherit trace sink)
WHERE incidents go. Same vocabulary as KV_LOG_LOCATION. Unset inherits the trace sink, using the …/api/v1/incidents path for the kv format.
KV_INCIDENT_FORMAT
unset (inherit KV_LOG_FORMAT)
HOW incidents are formatted: kv, json, or otlp (a standalone kyvvu.incident span).
Behaviour
KV_ENVIRONMENT
production
Forwarded to EvalContext.environment.
KV_LOG_PAYLOADS
full
full includes step input/output in logs. metadata_only redacts content but preserves shape.
KV_TEMPLATE_LOCATION
built-in
Path to a custom YAML behaviour template.
Cache and limits
KV_POLICY_TTL_SECONDS
300
How long to cache fetched policies (seconds).
KV_HTTP_TIMEOUT_SECONDS
10
Per-request HTTP timeout.
KV_TASK_MAX_AGE_SECONDS
3600
Abandoned-task eviction threshold for sweep_stale_tasks().
KV_SWEEP_ENABLED
true
Whether the background sweeper thread starts automatically. Set false to call sweep_stale_tasks() manually.
KV_SWEEP_INTERVAL_SECONDS
300
How often the background sweeper runs (seconds).
KV_SWEEP_FLUSH_ON_EVICT
true
Whether to attempt a batch log post for evicted tasks before discarding their buffers.
Resilience (opt-in)
KV_POLICY_FAIL_MODE
open
open = allow all when no policies loaded. closed = block all step_execution behaviors when no policies are available.
KV_POLICY_CACHE_PATH
empty (disabled)
File path for on-disk policy cache. Written after each successful fetch; loaded on cold start if the API is unreachable.
KV_POLICY_CACHE_MAX_AGE_SECONDS
86400
Maximum age (seconds) of the disk cache before a staleness warning is emitted. The cache is still used when stale.
KV_POLICY_HMAC_SECRET
empty (disabled)
Shared secret for HMAC-SHA256 verification of policy fetch responses. Must be set on both the engine and API for signing to activate.
KV_REGISTRATION_TTL
empty (infinite)
How long a cached agent registration is valid before re-registering. Accepts 30m, 24h, 7d, or raw seconds. Empty = cache never expires (re-registration only on payload change).
Logging
KV_LOG_LEVEL
INFO
Log level for kyvvu / kyvvu_engine Python loggers. Set to DEBUG for per-evaluation traces.
Policy-bundle integrity (HMAC)
KV_POLICY_HMAC_SECRET adds integrity and authenticity protection to the policy-distribution channel. When set, the API signs every policy-fetch response with HMAC-SHA256 (header X-Kyvvu-Policy-Signature, computed over the JSON body) and the engine verifies that signature before trusting the policies. It is defense-in-depth on top of TLS: TLS protects the connection, while the HMAC binds each policy bundle to a shared secret that a passive proxy or compromised intermediary cannot forge.
Set KV_POLICY_HMAC_SECRET to the same value on the API and on every verifying engine. Generate a secret with:
Rollout order
Set the API first. Engines that do not yet have the secret simply skip verification, so enabling it on the API is non-breaking.
Then set the engines. Each engine begins verifying once the secret is present on both sides.
An engine configured with a mismatched secret rejects every fetch and keeps serving its previously cached policies. On a cold start with no cache, an engine running KV_POLICY_FAIL_MODE=closed blocks all step_execution behaviors until the secret is aligned.
Rotation caveat
With a single shared secret, rotation is not zero-downtime. During rotation the API and the engines briefly hold different secrets; fetches are rejected and policies stop updating (the last cached bundle is still enforced) until both sides are aligned again. Plan rotations for a window where a short policy-update pause is acceptable.
Scope caveat
This is a self-hosted / full-stack feature: a single shared secret is only appropriate when one operator controls both the API and the engine. It is not intended for hosted / multi-tenant verification. Per-API-key / asymmetric scoping for multi-tenant deployments is tracked in issue #278.
Email (magic-link auth)
Magic link is the sole login and signup path, so every environment needs a working transport -- there is no password fallback. Transport is selected by KV_EMAIL_TRANSPORT:
KV_EMAIL_TRANSPORT
smtp
smtp, ses, or log (log is refused in production; see below).
KV_SMTP_HOST
empty
SMTP server hostname. Required when KV_EMAIL_TRANSPORT=smtp.
KV_SMTP_PORT
587
SMTP server port (TLS).
KV_SMTP_USER
empty
SMTP authentication username (smtp transport only).
KV_SMTP_PASSWORD
empty
SMTP authentication password (smtp transport only).
KV_SMTP_FROM
noreply@kyvvu.com
Sender / From address, used by both smtp and ses.
KV_WEB_URL
http://localhost:3000
Dashboard URL used to build magic-link URLs.
KV_EMAIL_ALLOWED_DOMAINS
kyvvu.com,mail-test.kyvvu.com
Recipient allowlist enforced outside production.
In local development, make dev points KV_SMTP_HOST at Mailpit, so mail is readable at http://localhost:8025 without any SES setup. KV_EMAIL_TRANSPORT=log logs the magic-link URL instead of sending -- must be set explicitly and is refused in production, since it puts a live login credential in the log.
Production setup (AWS SES)
Dev, stage and production all send via the SES API (KV_EMAIL_TRANSPORT=ses), authenticated as the ECS task role -- there is no SMTP credential to provision or copy. The domain identity, DKIM, and MAIL FROM subdomain are provisioned by Terraform (infra/terraform/ses.tf); the task role's ses:SendEmail/ses:SendRawEmail grant is provisioned per environment by modules/platform-env/email.tf, scoped to that one domain identity.
Note: New SES accounts start in sandbox mode. Request production access via AWS Console → SES → Account dashboard.
Next steps
Self-Hosted Setup — deployment guide
Architecture — how components use these settings
Last updated
