Skip to main content

Configuration Reference

Complete reference for AgentVisor™ configuration options.

Every setting is available both as a YAML key in agentvisor.yaml and as an AGENTVISOR_* environment variable. Environment variables take precedence over the config file.

Env var convention: take the YAML key, uppercase it, replace dots with underscores, and prefix with AGENTVISOR_. For example, temporal.targetAGENTVISOR_TEMPORAL_TARGET. Every env var appears in its concept section alongside the YAML key, default, and description — use your browser's Find (⌘F / Ctrl+F) to locate any variable by name.

Configuration Sources

Configuration is read from (in order of precedence, later wins):

  1. Default values (built-in)
  2. Base config file (agentvisor.yaml)
  3. conf.d/ drop-in fragments (alphabetically sorted, adjacent to base config)
  4. Overlay files (--config flags or AGENTVISOR_CONFIG_FILES)
  5. Environment variables (highest precedence)

The root-level file-loading variables are:

VariableDescription
AGENTVISOR_CONFIGPath to base config file (overrides default search paths)
AGENTVISOR_CONFIG_FILESComma-separated overlay config files merged on top of base config

See Config File Locations and Multi-Config Files for layering details.


Logging

AgentVisor uses a unified structured logging pipeline. All components — host, guest runtime, Temporal SDK, and agent logs — share the same output sink and format.

Env varDescription
AGENTVISOR_LOGGING_FORMATLog format: plain (human-readable) or json (structured)
AGENTVISOR_LOGGING_LEVELLog level grammar: \\<global\\>[,\\<component\\>=\\<level\\>]* (e.g. warn,agent=debug,temporal=error); components: host, guest, temporal, agent
AGENTVISOR_LOGGING_OUTPUTLog destination: empty/stderr, stdout, discard, /path/to/file, or rotate:/path/to/file
logging:
format: "plain"
level: "info"
output: ""
rotation:
compress: false
max_age_days: 28
max_backups: 3
max_size_mb: 100

Log Level Grammar

logging.level accepts a grammar string with optional per-component overrides:

<global>[,<component>=<level>]*
FormExampleEffect
SimpleinfoAll components at info
With overridewarn,agent=debugHost/guest/temporal at warn; agent at debug
Multiple overrideswarn,agent=debug,temporal=errorMixed levels

Valid levels: trace, debug, info, warn, warning, error (case-insensitive). Known components: host, guest, temporal, agent, mcp, a2a.

Components may have dot-separated sub-components (e.g. host.accesslog, mcp.client, mcp.pool, a2a.client, a2a.pool). An override matches the longest dot-boundary prefix of the logger name: given overrides for both host and host.accesslog, a log line from host.accesslog uses the host.accesslog level and a log line from host.grpc falls back to the host level. A component with no matching override (exact or prefix) falls back to the global level. mcp=warn,mcp.pool=debug is valid — it quiets the mcp umbrella while raising the connection pool sub-component to debug.

An override key that doesn't resolve to a known component — neither exactly nor as a dot-boundary descendant of one — parses without error but has no effect at runtime (there is no logger by that name to match); Setup logs a startup warning naming the unrecognized key rather than failing, since a typo here should never abort startup.

Guest Agent RPC Audit Logging

VariableDefaultDescription
AGENTVISOR_GUEST_AGENT_RPC_LOG_LEVELsummaryAgentService gRPC call audit logging: none, summary, full

Examples

# Debug all components
AGENTVISOR_LOG_LEVEL=debug agentvisor serve ./my-agent

# Quiet Temporal SDK while keeping everything else at debug
AGENTVISOR_LOG_LEVEL=debug,temporal=warn agentvisor serve ./my-agent

# Debug agent code only
AGENTVISOR_LOG_LEVEL=warn,agent=debug agentvisor serve ./my-agent
Troubleshooting
  • Agent not starting? AGENTVISOR_LOG_LEVEL=debug
  • Agent logic issues? AGENTVISOR_LOG_LEVEL=warn,agent=debug
  • Unexpected API behavior? AGENTVISOR_GUEST_AGENT_RPC_LOG_LEVEL=full
  • Temporal SDK noise? AGENTVISOR_LOG_LEVEL=debug,temporal=warn

Deprecated Fields

Deprecated env varReplacement
AGENTVISOR_LOG_LEVELAGENTVISOR_LOGGING_LEVEL
AGENTVISOR_LOG_FORMATAGENTVISOR_LOGGING_FORMAT

Temporal

Connect AgentVisor to a Temporal server (local or Temporal Cloud).

Env varDescription
AGENTVISOR_TEMPORAL_CAN_PAYLOAD_BUDGET_BYTESAdvanced override (0 = auto, derived from max_checkpoint_bytes): threshold a thread's estimated Continue-As-New payload (checkpoint data/state plus any pending writes) must stay under for pending writes to be retained rather than dropped on a CAN. Pinned into a thread's config at creation — raising it only benefits threads created afterward
AGENTVISOR_TEMPORAL_FORCE_CONTINUE_AS_NEW_AFTER_RUNSForce Continue-As-New after this many run completions per workflow execution (0 = disabled)
AGENTVISOR_TEMPORAL_FORCE_CONTINUE_AS_NEW_DURING_ACTIVE_RUNForce Continue-As-New while a run is actively executing (testing only; a thread's whole Continue-As-New chain is pinned to whichever value was in effect when the thread was first created — enabling or disabling this later only affects threads created afterward; see the Temporal guide for the transient interrupted response this causes)
AGENTVISOR_TEMPORAL_LOG_LEVELTemporal SDK log level override (empty = inherit from global logging.level)
AGENTVISOR_TEMPORAL_MAX_CHECKPOINT_BYTESThe largest single checkpoint an agent may write — state + metadata + channel_values combined (0 = automatic: 1MiB with checkpoint storage disabled, 8MiB with it enabled). Every other pending-writes size knob derives from this one unless explicitly overridden. Pinned into a thread's config at creation — raising it only benefits threads created afterward
AGENTVISOR_TEMPORAL_MAX_CHECKPOINT_HISTORYMaximum number of checkpoints retained per run (older ones pruned)
AGENTVISOR_TEMPORAL_MAX_PUT_WRITES_PER_EXECUTIONForce Continue-As-New after this many put_writes Update calls per workflow execution (0 = disabled); bounds LangGraph checkpoint-write-driven history growth proactively instead of relying solely on Temporal's own history-size CAN suggestion
AGENTVISOR_TEMPORAL_MAX_RUN_HISTORYMaximum number of runs retained per thread workflow (older ones pruned on Continue-As-New)
AGENTVISOR_TEMPORAL_NAMESPACETemporal namespace
AGENTVISOR_TEMPORAL_PENDING_WRITE_VALUE_MAX_SIZEMaximum size in bytes of a single LangGraph pending write's value (0 = auto, derived from max_checkpoint_bytes; oversized writes are dropped, not errored). Pinned into a thread's config at creation and enforced by the guest's own per-write validator — raising it only benefits threads created afterward
AGENTVISOR_TEMPORAL_PENDING_WRITES_ENABLEDPersist LangGraph's mid-superstep pending writes (put_writes) (a thread's whole Continue-As-New chain is pinned to whichever value was in effect when the thread was first created — enabling or disabling this later only affects threads created afterward)
AGENTVISOR_TEMPORAL_PENDING_WRITES_MAX_PER_CHECKPOINTMaximum number of distinct pending writes retained per checkpoint (excess writes are dropped, not errored). A fixed guest-side validator constant additionally caps every request at 256 writes — this setting can only lower that effective limit, never raise it
AGENTVISOR_TEMPORAL_PENDING_WRITES_TOTAL_BYTESAdvanced override (0 = auto, derived from max_checkpoint_bytes and can_payload_budget_bytes): maximum total size in bytes across all pending writes retained against a single checkpoint (excess writes are dropped, not errored), both at Continue-As-New time and at write time
AGENTVISOR_TEMPORAL_STATE_KEY_MAX_SIZEMaximum size in bytes of a single thread state key
AGENTVISOR_TEMPORAL_STATE_MAX_KEYSMaximum number of keys in thread state
AGENTVISOR_TEMPORAL_STATE_TOTAL_MAXMaximum total size in bytes of all thread state values combined
AGENTVISOR_TEMPORAL_STATE_VAL_MAX_SIZEMaximum size in bytes of a single thread state value
AGENTVISOR_TEMPORAL_TARGETTemporal server address (e.g. localhost:7233 or my-ns.account.tmprl.cloud:7233)
AGENTVISOR_TEMPORAL_TASK_QUEUETemporal task queue name
temporal:
can_payload_budget_bytes: 0
force_continue_as_new_after_runs: 0
force_continue_as_new_during_active_run: false
log_level: ""
max_checkpoint_bytes: 0
max_checkpoint_history: 1
max_put_writes_per_execution: 0
max_run_history: 100
namespace: "default"
pending_write_value_max_size: 0
pending_writes_enabled: true
pending_writes_max_per_checkpoint: 256
pending_writes_total_bytes: 0
state_key_max_size: 1024
state_max_keys: 10000
state_total_max: 10485760
state_val_max_size: 1048576
target: "localhost:7233"
task_queue: "agentvisor"

Temporal Cloud Authentication

For connecting to Temporal Cloud, AgentVisor supports API Key and mTLS authentication.

Env varDescription
AGENTVISOR_TEMPORAL_AUTH_API_KEYTemporal Cloud API key — set via AGENTVISOR_TEMPORAL_AUTH_API_KEY env var
AGENTVISOR_TEMPORAL_AUTH_TYPETemporal Cloud authentication: api_key, mtls, or empty (local Temporal)
AGENTVISOR_TEMPORAL_AUTH_MTLS_CA_DATABase64-encoded custom CA certificate for verifying the Temporal Cloud server (alternative to ca_file)
AGENTVISOR_TEMPORAL_AUTH_MTLS_CA_FILEPath to custom CA certificate for verifying the Temporal Cloud server
AGENTVISOR_TEMPORAL_AUTH_MTLS_CERT_DATABase64-encoded mTLS client certificate (alternative to cert_file)
AGENTVISOR_TEMPORAL_AUTH_MTLS_CERT_FILEPath to mTLS client certificate file
AGENTVISOR_TEMPORAL_AUTH_MTLS_KEY_DATABase64-encoded mTLS client private key (alternative to key_file)
AGENTVISOR_TEMPORAL_AUTH_MTLS_KEY_FILEPath to mTLS client private key file
AGENTVISOR_TEMPORAL_AUTH_MTLS_SERVER_NAMETLS SNI server name override for the Temporal Cloud connection
temporal:
auth:
api_key: ""
mtls:
ca_data: ""
ca_file: ""
cert_data: ""
cert_file: ""
key_data: ""
key_file: ""
server_name: ""
type: ""

Example — API Key:

temporal:
target: my-namespace.account-id.tmprl.cloud:7233
namespace: my-namespace.account-id
auth:
type: api_key
# Set via AGENTVISOR_TEMPORAL_AUTH_API_KEY — do not put in YAML

Example — mTLS:

temporal:
target: my-namespace.account-id.tmprl.cloud:7233
namespace: my-namespace.account-id
auth:
type: mtls
mtls:
cert_file: /etc/temporal/client.crt
key_file: /etc/temporal/client.key

See the Temporal Configuration Guide for setup instructions.

Encryption at Rest

AgentVisor supports encrypting Temporal workflow payloads at rest using a pluggable codec.

Env varDescription
AGENTVISOR_TEMPORAL_CODEC_ENABLEDEnable payload encryption for Temporal workflows (encryption at rest)
AGENTVISOR_TEMPORAL_CODEC_TYPEPayload codec provider (e.g. aes256); required when enabled: true
AGENTVISOR_TEMPORAL_CODEC_SERVER_ALLOWED_ORIGINSCORS origins allowed to access the codec server (required for Temporal Web UI)
AGENTVISOR_TEMPORAL_CODEC_SERVER_ENABLEDEnable the HTTP codec server for Temporal Web UI payload decryption
AGENTVISOR_TEMPORAL_CODEC_SERVER_LISTEN_ADDRListen address for the HTTP codec server (loopback by default)
AGENTVISOR_TEMPORAL_CODEC_SERVER_MAX_BODY_SIZEMaximum request body size in bytes for the codec server's /encode and /decode endpoints
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_ALLOW_CREDENTIALSSet Access-Control-Allow-Credentials, enabling the Web UI's cookie-based auth mode
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_ENABLEDRequire a valid Bearer token on /encode and /decode — without this, /decode is an unauthenticated decryption oracle
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_ALLOW_INSECUREPermit plaintext http:// OIDC endpoints for the codec server — never enable in production (loopback hosts are always permitted)
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_AUDIENCEExpected OIDC aud claim for the codec server's token validation
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_ISSUEROIDC issuer used to validate the Bearer token the Temporal Web UI forwards
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_JWKS_URLOverride JWKS URL for codec server auth (must be https; use when discovered URL is not reachable, e.g. inside K8s)
temporal:
codec:
enabled: false
server:
allowed_origins: []
auth:
allow_credentials: false
enabled: false
oidc_allow_insecure: false
oidc_audience: ""
oidc_issuer: ""
oidc_jwks_url: ""
enabled: false
listen_addr: "127.0.0.1:8091"
max_body_size: 10485760
type: ""

AES-256 Provider

The aes256 provider uses AES-256-GCM with PBKDF2 key derivation. Provider-specific options are set via env vars namespaced by provider type:

VariableDefaultDescription
AGENTVISOR_TEMPORAL_CODEC_AES256_PASSWORD-Encryption password (required)
AGENTVISOR_TEMPORAL_CODEC_AES256_SALT-PBKDF2 salt, unique per deployment (required)
AGENTVISOR_TEMPORAL_CODEC_AES256_ITERATIONS600000PBKDF2 iteration count (OWASP minimum; rejected below 100,000)

Or via YAML config file:

temporal:
codec:
enabled: true
type: aes256
aes256:
# password is not set here: config loading does not expand ${VAR}
# syntax, so a value like "${CODEC_PASSWORD}" would become the literal
# password. Set AGENTVISOR_TEMPORAL_CODEC_AES256_PASSWORD instead.
salt: "unique-deployment-salt"
iterations: 600000
server:
enabled: true
listen_addr: "127.0.0.1:8091"
allowed_origins:
- "http://localhost:8080"
auth:
enabled: true
oidc_issuer: "https://idp.example.com"
oidc_audience: "agentvisor-codec"
Security Notes
  • Password: Store in a secrets manager, not in the config file.
  • Salt: Required. Must be unique per deployment — startup fails without one, to prevent rainbow table attacks against a shared value.
  • Iterations: 600,000 is the OWASP-recommended minimum for PBKDF2-HMAC-SHA256; values below 100,000 are rejected at startup.
  • /decode is a decryption oracle: it has no authentication until auth.enabled is set. listen_addr defaults to loopback for this reason — see Codec Server for Temporal Web UI before widening it or adding an off-host allowed_origins entry.

Automatic Run Restart

When a run's agent invocation fails due to an infrastructure fault (heartbeat timeout, worker loss, guest sandbox unavailable) or a guest/agent-process crash (signal-killed exit, e.g. OOM/SEGV), AgentVisor can automatically restart it from the last checkpoint with exponential backoff, bounded by an attempt budget and a wall-clock ceiling. Agent-raised exceptions, cancellation, and interrupt() are never restarted.

Env varDescription
AGENTVISOR_TEMPORAL_RUN_RESTART_FORCE_FAILURE_CLASSTest-only: force InvokeRun to synthesize a classified failure (CRASH or INFRA) on a run's first attempt only, bypassing the real guest client entirely (empty = disabled). Rejected by config validation when env: production
AGENTVISOR_TEMPORAL_RUN_RESTART_INITIAL_INTERVALBackoff before the first restart attempt of a crashed/infra-failed run; doubles each subsequent attempt, capped at max_interval
AGENTVISOR_TEMPORAL_RUN_RESTART_MAX_ATTEMPTSNumber of restart attempts allowed after the initial InvokeRun invocation for a run that fails with an infrastructure or guest/agent-process crash error (never agent-raised errors, cancellation, or interrupt()); 0 disables restart entirely
AGENTVISOR_TEMPORAL_RUN_RESTART_MAX_ELAPSEDTotal wall-clock time allowed across all restart attempts for a single run, checked between attempts
AGENTVISOR_TEMPORAL_RUN_RESTART_MAX_INTERVALCap on the exponential backoff between restart attempts
AGENTVISOR_TEMPORAL_RUN_RESTART_REQUIRE_PROGRESSStop restarting early if a crash repeats with no checkpoint progress since the previous attempt, instead of exhausting the full attempt budget on a crash that will keep reproducing identically (always allows at least one restart regardless)
temporal:
run_restart:
force_failure_class: ""
initial_interval: "2s"
max_attempts: 3
max_elapsed: "10m"
max_interval: "30s"
require_progress: true

Set max_attempts: 0 to disable restart entirely — a restartable failure then surfaces as a run error on the first attempt, identical to pre-restart behavior.

External Checkpoint Storage

AgentVisor stores checkpoints and pending writes entirely inside Temporal workflow history, which inherits Temporal's own per-payload ceiling. External Checkpoint Storage lets a payload at or above threshold be stored in a pluggable backend instead, raising that ceiling without giving up the zero-infrastructure, workflow-native storage model that stays the default.

Env varDescription
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_CALL_TIMEOUTTimeout for each individual store/retrieve call to the checkpoint storage backend
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_ENABLEDEnable External Checkpoint Storage; workflow-native storage (plain Temporal history) stays the default
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_PROVIDERStorage backend (e.g. memory, filesystem, postgresql, s3, ycql) — only registered backends are usable; required when enabled: true
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_THRESHOLDMinimum serialized payload size in bytes that triggers storing a payload in the backend; smaller payloads stay inline in Temporal history
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_SWEEP_BATCH_SIZENumber of keys a single safety-net sweep batch's scan and delete round trip handles
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_SWEEP_CALL_TIMEOUTTimeout for each workflow-liveness check a safety-net sweep batch makes
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_SWEEP_CONCURRENCYMaximum number of workflow-liveness checks a single safety-net sweep batch may have in flight at once
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_SWEEP_ENABLEDEnable the scheduled safety-net sweep that reclaims stored objects whose owning workflow execution has left Temporal retention — Temporal itself never garbage-collects checkpoint storage payloads
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_SWEEP_GRACE_PERIODMinimum age an object must reach before a sweep will consider reclaiming it, so an in-flight upload is never reclaimed out from under its own claim
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_SWEEP_INTERVALHow often the scheduled safety-net sweep runs
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_SWEEP_LIVE_CACHE_SIZEMaximum number of distinct workflow executions a single safety-net sweep batch tracks to dedupe repeated liveness checks, bounded via LRU eviction
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_SWEEP_RATE_LIMITMaximum aggregate rate, in workflow-liveness checks per second, a safety-net sweep issues across every batch it processes
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_CLEANUP_RETENTION_MARGINSafety buffer added to a namespace's own retention period before the per-thread cleanup mechanism re-checks whether an object's owning execution has left retention
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_CIRCUIT_BREAKER_FAILURE_THRESHOLDNumber of consecutive checkpoint storage call failures that trips the circuit breaker open
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_CIRCUIT_BREAKER_RESET_TIMEOUTHow long the checkpoint storage circuit breaker stays open before allowing a single probe call through
temporal:
checkpoint_storage:
call_timeout: "10s"
circuit_breaker:
failure_threshold: 5
reset_timeout: "30s"
cleanup:
retention_margin: "1h"
enabled: false
provider: ""
sweep:
batch_size: 100
call_timeout: "10s"
concurrency: 10
enabled: true
grace_period: "24h"
interval: "24h"
live_cache_size: 4096
rate_limit: 20
threshold: 1048576

Disabling External Checkpoint Storage

Flipping checkpoint_storage.enabled from true back to false while checkpoint_storage.provider is still set is rejected at startup by default. Once a thread's history references an object stored in the backend (a checkpoint, a Continue-As-New payload, or a pending-write batch), that reference can only be resolved while the same storage backend stays configured — if this host restarts without it, that thread can never be replayed again. A non-empty provider left in place alongside enabled: false is treated as a strong signal the operator likely flipped the boolean without removing the rest of the config.

To disable the feature safely, remove temporal.checkpoint_storage.provider entirely once you are certain no thread ever stored a payload there. To override the check anyway (a break-glass escape hatch, following the same convention as AGENTVISOR_TLS_ALLOW_INSECURE), set:

AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_ALLOW_DISABLE=true

Enabling checkpoint_storage requires temporal.max_put_writes_per_execution (above) to be set to a non-zero value — with payloads moved to the backend, workflow history shrinks in bytes, so Temporal's own history-size-based Continue-As-New suggestion fires much later, and a run could otherwise accumulate an unbounded number of put_writes Update events. Startup validation rejects the combination of checkpoint_storage.enabled: true with max_put_writes_per_execution: 0.

checkpoint_storage.enabled: true alone raises the automatic temporal.max_checkpoint_bytes ceiling from 1 MiB to 8 MiB — the guest's own write-time validation ceiling is max_checkpoint_bytes, so this is what actually gives a checkpoint room to grow past threshold before the feature has anything to do. Setting max_checkpoint_bytes explicitly always wins over the automatic value. See Checkpoint Sizing and Limits: Raising the Ceiling for the full picture of what that knob governs and what derives from it.

Startup validation keeps the two fields consistent: threshold must stay below max_checkpoint_bytes whenever checkpoint storage is enabled, and must never exceed 1.5 MiB regardless (a payload at or below threshold stays inline in Temporal workflow history, where Temporal's raw per-payload ceiling still binds). With storage disabled, max_checkpoint_bytes is capped at roughly 1.33 MiB — the largest value whose derived Continue-As-New budget still lands on Temporal's raw ~2 MiB per-payload ceiling — since nothing would move an oversized payload out of workflow history.

Provider-specific options use temporal.checkpoint_storage.<provider>.* in config files, or AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_<PROVIDER>_<KEY> as environment variables — the same shape as Store's provider options:

temporal:
checkpoint_storage:
enabled: true
provider: postgresql
postgresql:
connection_string: "postgres://user:pass@localhost:5432/agentvisor"
# Same tls_*/pool_* options as the postgresql store provider (see Store below).
# statement_timeout: "30s" # optional; server-enforced backstop, independent
# of the checkpoint storage driver's own context-based
# call deadline -- unset by default, like connect_timeout

Or via environment variables:

AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_POSTGRESQL_CONNECTION_STRING=postgres://user:pass@localhost:5432/agentvisor

The s3 provider talks to Amazon S3 or an S3-compatible service (e.g. MinIO):

temporal:
checkpoint_storage:
enabled: true
provider: s3
s3:
bucket: "agentvisor-blobstore" # required
region: "us-east-1" # optional; falls back to the AWS SDK's
# default resolution (env vars, shared config)
key_prefix: "agentvisor/blobstore" # optional; "" means the bucket root
# Static credentials (optional; falls back to the AWS SDK's default credential
# chain -- env vars, shared config, IAM role, etc.):
# access_key_id: "..."
# secret_access_key: "..."
# session_token: "..."
# Custom endpoint for S3-compatible backends. Must include a scheme
# (http:// or https://). use_path_style defaults to true whenever endpoint is
# set (most S3-compatible services require path-style addressing) and to
# false otherwise.
# endpoint: "http://localhost:9000"
# use_path_style: true
# Same tls_*/tls_trust_system_roots options as the postgresql provider above,
# applied only to a custom endpoint -- real AWS S3 relies on the SDK's own
# default HTTPS transport.

Or via environment variables:

AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_S3_BUCKET=agentvisor-blobstore
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_S3_REGION=us-east-1

The ycql provider talks to a YugabyteDB cluster over its Cassandra-compatible YCQL protocol:

temporal:
checkpoint_storage:
enabled: true
provider: ycql
ycql:
hosts: "10.0.0.1,10.0.0.2,10.0.0.3" # required; comma-separated contact points
# (or a YAML list in a config file)
keyspace: "agentvisor" # required; must already exist -- this
# provider never creates it, matching the
# postgresql provider's expectation that its
# database already exists
# table: "blobstore_objects" # optional; default shown
# port: 9042 # optional; gocql default
# username: "..." # optional; set together with password,
# password: "..." # or not at all
# consistency: "quorum" # optional; any gocql consistency level name
# timeout: "8s" # optional; per-query timeout. Default
# (shown) is below the checkpoint storage
# driver's 10s per-call deadline, not gocql's
# own native 11s -- otherwise the outer
# context, not gocql, is what actually
# cancels a wedged call
# connect_timeout: "8s" # optional; same default reasoning as
# timeout above
# num_conns: 2 # optional; connections per host
# page_size: 5000 # optional; rows fetched per page for a
# Scan query. Default (shown) is gocql's
# own library default
# retry_num_retries: 3 # optional; SimpleRetryPolicy's retry
# count. Default (shown) replaces
# gocql's own default of no retry at
# all; set to 0 to explicitly disable
# disable_initial_host_lookup: false # optional; set true behind a NAT, port-
# forward, or other address-translating
# indirection (e.g. a dynamically-mapped
# container port) -- otherwise gocql
# replaces the configured hosts with
# unreachable internal addresses
# discovered from system.peers. Costs
# token-aware/DC-aware routing.
# ttl: "720h" # optional row-expiry TTL -- an opt-in backstop
# alongside the cleanup mechanism, not a
# substitute for it (TTL alone can't express
# run-liveness-aware reclamation)
# buckets: 16 # optional; number of hash buckets the
# Scan-serving secondary index is
# partitioned over. Default (shown) turns
# what would otherwise be one partition
# for the whole deployment into 16. Must
# stay fixed for the lifetime of a
# deployment's data -- changing it strands
# previously-written objects from future
# Scan calls (Get/Delete by exact key are
# unaffected).
# Same tls_*/tls_trust_system_roots options as the postgresql provider above.

Or via environment variables:

AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_YCQL_HOSTS=10.0.0.1,10.0.0.2,10.0.0.3
AGENTVISOR_TEMPORAL_CHECKPOINT_STORAGE_YCQL_KEYSPACE=agentvisor

The filesystem provider accepts a single dir option (default: <cache_dir>/blobstore); memory accepts no options and does not survive a process restart, so it is intended for throwaway testing only.

get_checkpoint, list_checkpoints, and getState reads are covered the same way writes are: a read result at or above threshold is served from the configured backend too, so a checkpoint written past Temporal's raw ~2MiB per-payload ceiling reads back correctly, and a thread whose head checkpoint has grown that large keeps running normally. See Checkpoint Sizing and Limits for how to size a threshold and pinned ceiling, and the External Checkpoint Storage guide for the full operational picture.


Authorization

AgentVisor uses the Manetu PolicyEngine (MPE) for request authorization. The provider is pluggable.

Env varDescription
AGENTVISOR_AUTHZ_TYPEAuthorization provider: embedded (local MPE), http (remote PDP), or allowall (dev only)

HTTP Provider

Delegates policy decisions to a remote Policy Decision Point (PDP) server.

Env varDescription
AGENTVISOR_AUTHZ_HTTP_TIMEOUTHTTP request timeout for policy evaluation calls to the remote PDP
AGENTVISOR_AUTHZ_HTTP_URLURL of the remote HTTP Policy Decision Point (PDP) server
AGENTVISOR_AUTHZ_HTTP_TLS_CA_DATABase64-encoded PEM CA certificate for verifying the PDP server (alternative to ca_file)
AGENTVISOR_AUTHZ_HTTP_TLS_CA_FILEPath to PEM CA certificate for verifying the PDP server
AGENTVISOR_AUTHZ_HTTP_TLS_CERT_DATABase64-encoded PEM client certificate for mTLS to the PDP (alternative to cert_file)
AGENTVISOR_AUTHZ_HTTP_TLS_CERT_FILEPath to PEM client certificate for mTLS authentication to the PDP
AGENTVISOR_AUTHZ_HTTP_TLS_KEY_DATABase64-encoded PEM client private key for mTLS to the PDP (alternative to key_file)
AGENTVISOR_AUTHZ_HTTP_TLS_KEY_FILEPath to PEM client private key for mTLS authentication to the PDP
AGENTVISOR_AUTHZ_HTTP_TLS_MODETLS verification mode: verify-full (default), verify-ca, require, or disable
AGENTVISOR_AUTHZ_HTTP_TLS_SERVER_NAMETLS SNI server name override (useful when PDP is behind a proxy/load balancer)
AGENTVISOR_AUTHZ_HTTP_TLS_TRUST_SYSTEM_ROOTSAppend the configured CA to the system root pool instead of replacing it (default: false)
authz:
http:
timeout: ""
tls:
ca_data: ""
ca_file: ""
cert_data: ""
cert_file: ""
key_data: ""
key_file: ""
mode: ""
server_name: ""
trust_system_roots: false
url: ""
note

authz.http.headers (custom request headers to the PDP) can only be configured via YAML — not via flat environment variables. Use value_env within a header entry to reference a secret at startup.

Embedded Provider

The embedded provider runs the Manetu PolicyEngine locally using Rego evaluation. Configure via provider-specific env vars:

VariableDefaultDescription
AGENTVISOR_AUTHZ_EMBEDDED_POLICY_DOMAIN_FILES-Comma-separated paths to MPE policy domain YAML files (required)
AGENTVISOR_AUTHZ_EMBEDDED_ACCESS_LOG_OUTPUTstdoutAccess log destination: stdout, stderr, logger, discard, /path, rotate:/path. In exec mode defaults to logger.
AGENTVISOR_AUTHZ_EMBEDDED_ACCESS_LOG_FORMATjsonJSON formatting: json (compact) or pretty (indented). Ignored for logger/discard.
AGENTVISOR_AUTHZ_EMBEDDED_ACCESS_LOG_LEVELinfoLog level when ACCESS_LOG_OUTPUT=logger.
AGENTVISOR_AUTHZ_EMBEDDED_ACCESS_LOG_PRETTY_PRINTfalseDeprecated — use ACCESS_LOG_FORMAT=pretty.
# Embedded provider (recommended for most deployments)
authz:
type: embedded
embedded:
policy_domain_files: /etc/agentvisor/policies/domain.yml

# HTTP provider (remote PDP)
# authz:
# type: http
# http:
# url: https://pdp.example.com:9000
# timeout: 5s
# tls:
# mode: verify-full
# ca_file: /etc/agentvisor/pdp-ca.pem
# headers:
# - name: "X-Tenant-ID"
# value: "acme"
# - name: "Authorization"
# value_env: "PDP_TOKEN"

# AllowAll provider (development only — NEVER use in production!)
# authz:
# type: allowall

HTTP Proxy

The HTTP proxy provides TLS termination and credential substitution for outbound agent requests. Agents route through the proxy transparently via the HTTPS_PROXY environment variable injected at guest startup.

Env varDescription
AGENTVISOR_PROXY_ALLOWED_PATTERNSNo longer supported; rejected at config load. Restrict outbound destinations via MPE HTTP policy (mrn:agentvisor:http:<host>/<path>) instead
AGENTVISOR_PROXY_INTERCEPT_CACHE_TTLMax lifetime of a response_intercept resolver's cached symbolic-to-real credential mapping (e.g. intercepted OAuth tokens)
AGENTVISOR_PROXY_MAX_BODY_SIZEMaximum buffered response body size in bytes for unary proxy requests
AGENTVISOR_PROXY_REQUEST_TIMEOUTTimeout for HTTP proxy requests forwarded to upstream services
AGENTVISOR_PROXY_SSRF_ALLOWED_CIDRSDestinations (CIDR range, bare IP, or bare hostname) exempted from the SSRF guard's default-deny of loopback, unspecified, link-local (incl. cloud metadata), private, and carrier-grade-NAT destinations. A hostname entry is resolved at startup and every resolved address is allowed -- the recommended way to allowlist "localhost", since a CIDR-only entry for one address family (e.g. 127.0.0.1/32) does not also cover ::1
AGENTVISOR_PROXY_STREAM_MAX_BODY_SIZEMaximum streaming response body size in bytes for streaming proxy requests
AGENTVISOR_PROXY_UPSTREAM_TLS_CA_DATABase64-encoded PEM CA certificate to trust for upstream requests (alternative to ca_file)
AGENTVISOR_PROXY_UPSTREAM_TLS_CA_FILEPath to PEM CA certificate to trust for upstream requests (e.g. a private/internal CA)
AGENTVISOR_PROXY_UPSTREAM_TLS_TRUST_SYSTEM_ROOTSAppend the configured CA to the system root pool instead of replacing it (default: true — unlike every other TLS site, the proxy must reach both private and public destinations)
proxy:
intercept_cache_ttl: "15m"
max_body_size: 10485760
request_timeout: "5m"
ssrf_allowed_cidrs: []
stream_max_body_size: 209715200
upstream_tls:
ca_data: ""
ca_file: ""
trust_system_roots: true
Proxy Credentials

Credential substitution (injecting real API keys while agents use placeholder tokens) is configured under proxy.credentials. See Proxy Credentials for the full reference.

Egress Proxy Upstream TLS Trust

proxy.upstream_tls configures which CA(s) the proxy trusts when dialing agent-chosen upstream destinations — narrower than other TLS sites (no mode, server_name, or client certs). See TLS Trust Configuration for the full reference.


API Server

All API transports share a single HTTP server with common listen address, connection limits, timeouts, and body size settings.

Env varDescription
AGENTVISOR_API_IDLE_TIMEOUTMaximum time an idle connection is kept open
AGENTVISOR_API_LISTEN_ADDRListen address shared by all API transports (e.g. :8090)
AGENTVISOR_API_MAX_BODY_SIZEMaximum request body size in bytes; requests exceeding this receive 413
AGENTVISOR_API_MAX_CONNECTIONSMaximum concurrent connections; requests over this limit receive 503
AGENTVISOR_API_MAX_CONNECTIONS_PER_IPMaximum concurrent connections per client IP; excess receives 503
AGENTVISOR_API_MIN_BODY_RATEMinimum upload rate in bytes/s; connections below this are terminated (slow-loris protection)
AGENTVISOR_API_READ_BODY_TIMEOUTMaximum duration for reading the complete request body
AGENTVISOR_API_TRUSTED_PROXIESCIDR ranges of reverse proxies trusted to set X-Forwarded-For/X-Real-IP (comma-separated); empty (default) ignores these headers and uses RemoteAddr
AGENTVISOR_API_WRITE_TIMEOUTMaximum duration for writing the response (disabled for SSE endpoints)
api:
idle_timeout: "2m"
listen_addr: ":8090"
max_body_size: 10485760
max_connections: 10000
max_connections_per_ip: 100
min_body_rate: 1024
read_body_timeout: "1m"
trusted_proxies: []
write_timeout: "1m"

API Authentication

Authentication is shared across all API transports. When enabled, all requests must present a valid OIDC JWT.

Env varDescription
AGENTVISOR_API_AUTH_ENABLEDRequire OIDC authentication for all API requests
AGENTVISOR_API_AUTH_OIDC_ALLOW_INSECUREPermit plaintext http:// OIDC endpoints — an on-path attacker can substitute signing keys; never enable in production (loopback hosts are always permitted)
AGENTVISOR_API_AUTH_OIDC_AUDIENCEExpected OIDC aud claim value
AGENTVISOR_API_AUTH_OIDC_ISSUEROIDC issuer URL for token validation
AGENTVISOR_API_AUTH_OIDC_JWKS_URLOverride JWKS URL (must be https; use when discovered URL is not reachable, e.g. inside K8s)
AGENTVISOR_API_AUTH_TEST_MODEAllow principal injection via X-Test-Principal header — never enable in production
AGENTVISOR_API_AUTH_TLS_CA_DATABase64-encoded PEM CA certificate for verifying the OIDC provider (alternative to ca_file)
AGENTVISOR_API_AUTH_TLS_CA_FILEPath to PEM CA certificate for verifying the OIDC provider
AGENTVISOR_API_AUTH_TLS_CERT_DATABase64-encoded PEM client certificate for mTLS to the OIDC provider (alternative to cert_file)
AGENTVISOR_API_AUTH_TLS_CERT_FILEPath to PEM client certificate for mTLS authentication to the OIDC provider
AGENTVISOR_API_AUTH_TLS_KEY_DATABase64-encoded PEM client private key for mTLS to the OIDC provider (alternative to key_file)
AGENTVISOR_API_AUTH_TLS_KEY_FILEPath to PEM client private key for mTLS authentication to the OIDC provider
AGENTVISOR_API_AUTH_TLS_MODETLS verification mode: verify-full (default), verify-ca, require, or disable
AGENTVISOR_API_AUTH_TLS_SERVER_NAMETLS SNI server name override (useful when the OIDC provider is behind a proxy/load balancer)
AGENTVISOR_API_AUTH_TLS_TRUST_SYSTEM_ROOTSAppend the configured CA to the system root pool instead of replacing it (default: false)
api:
auth:
enabled: false
oidc_allow_insecure: false
oidc_audience: ""
oidc_issuer: ""
oidc_jwks_url: ""
test_mode: false
tls:
ca_data: ""
ca_file: ""
cert_data: ""
cert_file: ""
key_data: ""
key_file: ""
mode: ""
server_name: ""
trust_system_roots: false
TLS trust for the OIDC provider

api.auth.tls configures outbound trust for the discovery document fetch and JWKS fetch made against oidc_issuer / oidc_jwks_url (e.g. tls.ca_file to trust a private CA). See TLS Trust Configuration for the full field reference.


API Transports

API Transports control how external clients access AgentVisor agents. Each transport can be independently enabled or disabled.

Transport vs Gateway

Don't confuse API Transports (inbound — external clients → agents) with Service Gateways (outbound — agents → external services):

  • api.mcp.enabled enables the MCP Transport (external MCP clients → agents)
  • mcp.servers[] configures the MCP Gateway (agents → external MCP servers)

See MCP Gateway and A2A Gateway below for gateway configuration.

Env varDescription
AGENTVISOR_API_OPENAPI_ENABLEDEnable OpenAPI/REST transport implementing LangGraph Agent Protocol v0.2.0
AGENTVISOR_API_MCP_ENABLEDEnable MCP transport at /mcp (exposes agents as MCP tools to external MCP clients)
AGENTVISOR_API_MCP_TOOLS_AGENTSExpose auto-generated per-agent invocation tools via MCP
AGENTVISOR_API_MCP_TOOLS_RUNSExpose run management tools via MCP (get_run, cancel_run, list_runs, wait_for_run)
AGENTVISOR_API_MCP_TOOLS_STATEExpose thread state tools via MCP (get_thread_state, update_thread_state)
AGENTVISOR_API_MCP_TOOLS_STOREExpose key-value store tools via MCP (store_put, store_get, store_delete, store_search)
AGENTVISOR_API_MCP_TOOLS_SYSTEMExpose system tools via MCP (health_check, list_agents)
AGENTVISOR_API_MCP_TOOLS_THREADSExpose thread management tools via MCP (create_thread, get_thread, delete_thread)
AGENTVISOR_API_A2A_ENABLEDEnable A2A transport at /a2a (exposes agents via Google Agent-to-Agent Protocol)
api:
openapi:
enabled: true
mcp:
enabled: false
tools:
agents: true
runs: true
state: true
store: true
system: true
threads: true
a2a:
enabled: false

Transport endpoints:

  • OpenAPI/REST: /* (root paths for threads, runs, agents, store, etc.)
  • MCP: /mcp (Model Context Protocol, streamable HTTP)
  • A2A: /a2a and /.well-known/agent-card.json (Google Agent-to-Agent Protocol)

API TLS

Enable HTTPS for the API server with optional mutual TLS (mTLS) for client authentication.

Env varDescription
AGENTVISOR_API_TLS_AUTO_CERTAuto-generate a self-signed certificate on startup — development only
AGENTVISOR_API_TLS_CERT_DATABase64-encoded server TLS certificate (alternative to cert_file)
AGENTVISOR_API_TLS_CERT_FILEPath to server TLS certificate file (PEM)
AGENTVISOR_API_TLS_CLIENT_AUTHClient certificate policy: none, request, require, verify, or require_and_verify
AGENTVISOR_API_TLS_CLIENT_CA_FILEPath to CA certificate for client certificate verification (mTLS)
AGENTVISOR_API_TLS_ENABLEDEnable HTTPS for the API server
AGENTVISOR_API_TLS_KEY_DATABase64-encoded server TLS private key (alternative to key_file)
AGENTVISOR_API_TLS_KEY_FILEPath to server TLS private key file (PEM)
AGENTVISOR_API_TLS_MIN_VERSIONMinimum TLS version: 1.2 or 1.3
api:
tls:
auto_cert: false
cert_data: ""
cert_file: ""
client_auth: "none"
client_ca_file: ""
enabled: false
key_data: ""
key_file: ""
min_version: "1.2"

Client Authentication Modes

ModeDescription
noneNo client certificate requested (default)
requestRequest client cert but don't require it
requireRequire any client cert (no verification)
verifyVerify client cert if presented
require_and_verifyRequire and verify client cert (most secure for mTLS)

Examples

Production TLS with mTLS:

api:
tls:
enabled: true
cert_file: /etc/agentvisor/tls/server.crt
key_file: /etc/agentvisor/tls/server.key
client_ca_file: /etc/agentvisor/tls/client-ca.crt
client_auth: require_and_verify
min_version: "1.3"

Development with auto-generated certificate:

api:
tls:
enabled: true
auto_cert: true # WARNING: Development only!

API Request Hardening

All hardening is enabled by default with sensible limits. Disabling any protection logs a WARNING at startup.

JSON Validation

Env varDescription
AGENTVISOR_API_VALIDATION_MAX_ARRAY_LENGTHMaximum number of elements in any JSON array in a request body
AGENTVISOR_API_VALIDATION_MAX_JSON_DEPTHMaximum JSON nesting depth in request bodies
AGENTVISOR_API_VALIDATION_MAX_JSON_KEYSMaximum number of keys across an entire JSON request body
AGENTVISOR_API_VALIDATION_MAX_METADATA_KEY_LENGTHMaximum length of a metadata object key in characters
AGENTVISOR_API_VALIDATION_MAX_METADATA_KEYSMaximum number of keys in any metadata object
AGENTVISOR_API_VALIDATION_MAX_METADATA_VALUE_LENGTHMaximum length of a metadata object value in characters
AGENTVISOR_API_VALIDATION_MAX_STRING_LENGTHMaximum length of any single string value in a JSON request body
AGENTVISOR_API_VALIDATION_STRICT_MODEReject JSON objects with duplicate keys
api:
validation:
max_array_length: 10000
max_json_depth: 20
max_json_keys: 10000
max_metadata_key_length: 128
max_metadata_keys: 100
max_metadata_value_length: 4096
max_string_length: 1048576
strict_mode: true

Rate Limiting

Rate limiting uses the token bucket algorithm with per-client and global limits.

Per-client format: rate/period,burst, e.g. 100/min,20.

Env varDescription
AGENTVISOR_API_RATE_LIMIT_ENABLEDEnable HTTP API rate limiting
AGENTVISOR_API_RATE_LIMIT_GLOBAL_BURSTGlobal burst capacity (maximum instantaneous requests across all clients)
AGENTVISOR_API_RATE_LIMIT_GLOBAL_RPSGlobal requests per second across all clients
AGENTVISOR_API_RATE_LIMIT_MAX_CLIENTSMaximum number of per-client rate limit tracking entries (LRU)
AGENTVISOR_API_RATE_LIMIT_PER_CLIENT_AGENT_QUERIESPer-client rate limit for agent list/query operations (format: rate/period,burst)
AGENTVISOR_API_RATE_LIMIT_PER_CLIENT_RUN_CREATIONPer-client rate limit for run creation operations (format: rate/period,burst)
AGENTVISOR_API_RATE_LIMIT_PER_CLIENT_RUN_POLLINGPer-client rate limit for run polling/wait operations (format: rate/period,burst)
AGENTVISOR_API_RATE_LIMIT_PER_CLIENT_SSE_CONNECTIONSPer-client rate limit for SSE stream connections (format: rate/period,burst)
AGENTVISOR_API_RATE_LIMIT_PER_CLIENT_STORE_OPSPer-client rate limit for key-value store operations (format: rate/period,burst)
AGENTVISOR_API_RATE_LIMIT_PER_CLIENT_THREAD_CRUDPer-client rate limit for thread create/read/update/delete (format: rate/period,burst)
api:
rate_limit:
enabled: true
global_burst: 20000
global_rps: 10000
max_clients: 10000
per_client:
agent_queries: "100/min,30"
run_creation: "60/min,10"
run_polling: "300/min,50"
sse_connections: "10/min,5"
store_ops: "200/min,50"
thread_crud: "100/min,20"

Clients are identified by authenticated principal (sub claim) or client IP for anonymous requests. Exceeded limits return 429 Too Many Requests with a Retry-After header.

CORS

CORS is restrictive by default (no cross-origin requests allowed).

Env varDescription
AGENTVISOR_API_CORS_ALLOW_ALLAllow all CORS origins (Access-Control-Allow-Origin: *) — insecure, development only
AGENTVISOR_API_CORS_ALLOW_CREDENTIALSAllow cookies and authorization headers in cross-origin requests
AGENTVISOR_API_CORS_ALLOWED_ORIGINSAllowed CORS origins (comma-separated); supports exact match and *.example.com wildcards
AGENTVISOR_API_CORS_MAX_AGEPreflight cache duration in seconds
api:
cors:
allow_all: false
allow_credentials: false
allowed_origins: []
max_age: 86400
Wildcard Subdomain Depth

*.example.com matches all subdomain depths. *.example.com allows both https://app.example.com and https://deep.sub.example.com. For single-level semantics, enumerate allowed origins explicitly.


Guest Sandbox

Configuration for the guest sandbox container that runs agent code in isolation.

Env varDescription
AGENTVISOR_GUEST_AGENT_LOG_CAPTURE_ROOTWhether the Python SDK transparently captures idiomatic/third-party root-logger output via gRPC; forwarded to the guest/agent as AGENTVISOR_LOG_CAPTURE_ROOT
AGENTVISOR_GUEST_BINARY_PATHPath to the agentvisor-guest-runtime binary inside the guest container image (gVisor sandbox only; Docker uses the image ENTRYPOINT instead)
AGENTVISOR_GUEST_BUNDLE_DIRDirectory for OCI bundle state (gVisor/Docker sandboxes)
AGENTVISOR_GUEST_CPU_LIMITCPU limit as a fraction of one core (e.g. 1.0 = 1 CPU, 0 = unlimited)
AGENTVISOR_GUEST_DOCKER_IMAGEDocker image containing agent code (used by unified packaging mode)
AGENTVISOR_GUEST_ENTRYPOINTAgent entry-point file for sandbox: none mode
AGENTVISOR_GUEST_ENVIRONMENT_FILESComma-separated paths to .env files whose variables are passed to the guest
AGENTVISOR_GUEST_ENVIRONMENT_PASSTHROUGHHost environment variable names to forward into the guest sandbox (comma-separated; use HOST=GUEST to rename)
AGENTVISOR_GUEST_FSIZE_HARD_LIMITHard RLIMIT_FSIZE (maximum file size, bytes) for the guest
AGENTVISOR_GUEST_FSIZE_SOFT_LIMITSoft RLIMIT_FSIZE (maximum file size, bytes) for the guest
AGENTVISOR_GUEST_GVISOR_DEBUGEnable gVisor debug logging (runsc --debug); output is captured through the host logger
AGENTVISOR_GUEST_GVISOR_PLATFORMgVisor platform: `` (auto), systrap, ptrace, or kvm
AGENTVISOR_GUEST_GVISOR_SECCOMPApply OCI seccomp profile to gVisor sandbox (--oci-seccomp); disable only to debug startup failures
AGENTVISOR_GUEST_IMAGEPre-built guest OCI image reference; pulled and extracted at runtime instead of using a local rootfs
AGENTVISOR_GUEST_INTERPRETERLanguage interpreter for agent code (e.g. python3)
AGENTVISOR_GUEST_MEMORY_LIMITMemory limit for the guest sandbox in bytes
AGENTVISOR_GUEST_NPROC_HARD_LIMITHard RLIMIT_NPROC (maximum processes) for the guest
AGENTVISOR_GUEST_NPROC_SOFT_LIMITSoft RLIMIT_NPROC (maximum processes) for the guest
AGENTVISOR_GUEST_PIDS_LIMITMaximum number of processes (PIDs) inside the guest
AGENTVISOR_GUEST_PRINCIPALGuest identity principal for sandbox: none mode
AGENTVISOR_GUEST_ROOTFS_PATHPath to the guest root filesystem (OCI rootfs or pre-extracted image)
AGENTVISOR_GUEST_ROOTLESSRun gVisor in rootless mode using user namespaces (no --privileged required)
AGENTVISOR_GUEST_RUNSC_PATHPath to the runsc binary (gVisor runtime)
AGENTVISOR_GUEST_RUNTIME_ROOTRoot directory for gVisor/container runtime state
AGENTVISOR_GUEST_SANDBOXSandbox mode: gvisor (production), docker (development), or none (local debug)
AGENTVISOR_GUEST_SHUTDOWN_TIMEOUTMaximum time to wait for the guest sandbox to shut down gracefully
AGENTVISOR_GUEST_SOURCE_DIRPath to agent source code on the host (used with sandbox: none)
AGENTVISOR_GUEST_STARTUP_TIMEOUTMaximum time to wait for the guest sandbox to become ready
AGENTVISOR_GUEST_VENV_PATHPath to Python virtual environment (used by unified packaging with sandbox: none)
AGENTVISOR_GUEST_WORK_DIRWorking directory inside the guest sandbox
guest:
agent_log_capture_root: true
binary_path: "/usr/local/bin/agentvisor-guest-runtime"
bundle_dir: "/var/run/agentvisor/bundles"
cpu_limit: 0
docker_image: ""
entrypoint: "main.py"
environment_files: ""
environment_passthrough: []
fsize_hard_limit: 209715200
fsize_soft_limit: 104857600
gvisor_debug: false
gvisor_platform: ""
gvisor_seccomp: true
image: ""
interpreter: "python3"
memory_limit: 536870912
nproc_hard_limit: 512
nproc_soft_limit: 256
pids_limit: 1024
principal: ""
rootfs_path: "/opt/guest-rootfs"
rootless: true
runsc_path: "runsc"
runtime_root: "/var/run/agentvisor/runtime"
sandbox: "gvisor"
shutdown_timeout: "10s"
source_dir: ""
startup_timeout: "30s"
venv_path: ""
work_dir: ""

Fields specific to sandbox: none (local debugging without isolation): source_dir, entrypoint, interpreter, principal, venv_path.

Registry Authentication

For pulling pre-built guest OCI images (guest.image):

Env varDescription
AGENTVISOR_GUEST_REGISTRY_AUTH_DOCKER_CONFIGPath to Docker config.json for registry credential helpers (alternative to username/password env)
AGENTVISOR_GUEST_REGISTRY_AUTH_PASSWORD_ENVEnvironment variable name containing the registry password/token
AGENTVISOR_GUEST_REGISTRY_AUTH_USERNAME_ENVEnvironment variable name containing the registry username
guest:
registry_auth:
docker_config: ""
password_env: ""
username_env: ""

Registry TLS

Outbound TLS trust for registry pull/push operations (guest image, mcp-tools image, and the agentvisor build/build guest CLI commands). Like the egress proxy's proxy.upstream_tls, this exposes a narrower ca_file/ca_data/trust_system_roots-only shape rather than the full tlsutil.TrustConfig, since a registry client commonly reaches both private and arbitrary public registries through the same client. See TLS Configuration for the full outbound-TLS reference.

Env varDescription
AGENTVISOR_GUEST_REGISTRY_TLS_CA_DATABase64-encoded PEM CA certificate to trust for registry pull/push (alternative to ca_file)
AGENTVISOR_GUEST_REGISTRY_TLS_CA_FILEPath to a PEM CA certificate to trust when pulling/pushing images from a private-CA registry
AGENTVISOR_GUEST_REGISTRY_TLS_INSECURESkip TLS certificate verification for registry operations; requires AGENTVISOR_TLS_ALLOW_INSECURE=true
AGENTVISOR_GUEST_REGISTRY_TLS_TRUST_SYSTEM_ROOTSAppend the configured CA to the system root pool instead of replacing it (default true)
guest:
registry_tls:
ca_data: ""
ca_file: ""
insecure: false
trust_system_roots: true

Equivalent CLI flags on build, build guest, run, serve, and exec: --registry-ca-file, --registry-ca-data, --registry-insecure.

Sandbox Modes

ModePlatformHardeningUse Case
noneAnyNoneLocal debugging (no isolation)
dockerLinuxFullDevelopment with security
dockermacOS/WindowsFull†Development (CLI default)
gvisorLinuxFullProduction (host runtime default)

†Docker on macOS/Windows uses nftables-based network isolation instead of --network=none.


Guest Hardening

Granular security hardening for the guest sandbox. Each feature defaults to auto, which enables it when the sandbox supports it.

Env varDescription
AGENTVISOR_GUEST_HARDENING_ENV_CURATIONEnvironment curation: allowlist system env vars and set umask 0077 (auto, enabled, disabled)
AGENTVISOR_GUEST_HARDENING_FILESYSTEM_HARDENINGFilesystem hardening: read-only rootfs, seccomp profiles, tmpfs mounts, masked paths (auto, enabled, disabled)
AGENTVISOR_GUEST_HARDENING_KERNEL_HARDENINGKernel hardening: capability bounding set, NoNewPrivileges, user-namespace blocking (auto, enabled, disabled)
AGENTVISOR_GUEST_HARDENING_NETWORK_FILTERINGnftables outbound traffic filtering for TCP transport mode (Docker macOS/Windows) (auto, enabled, disabled)
AGENTVISOR_GUEST_HARDENING_NETWORK_ISOLATIONLoopback-only networking (--network=none) (auto, enabled, disabled)
AGENTVISOR_GUEST_HARDENING_PROCESS_ISOLATIONPrivilege separation, UID isolation, and capability dropping (auto, enabled, disabled)
guest:
hardening:
env_curation: "auto"
filesystem_hardening: "auto"
kernel_hardening: "auto"
network_filtering: "auto"
network_isolation: "auto"
process_isolation: "auto"

Hardening Values

ValueBehavior
autoEnable if supported by sandbox type (default)
enabledForce enable — fails startup if not supported
disabledForce disable — WARNING logged

Auto-Detection Matrix

Featuregvisordocker (Linux)docker (macOS/Win)none
process_isolation
env_curation
network_isolation
network_filtering✓†
filesystem_hardening
kernel_hardening

network_isolation and network_filtering are mutually exclusive. Docker on macOS/Windows uses nftables-based outbound restriction (network_filtering) instead of --network=none.

See Sandbox Modes for detailed feature descriptions.

Guest Proxy Hardening

These settings configure connection limits and TLS parameters for the guest HTTP proxy. They are read by the guest-runtime (not the host-runtime config system) and can only be set via environment variables.

VariableDefaultDescription
AGENTVISOR_GUEST_PROXY_LOG_LEVELnoneProxy request audit logging: none, summary, full
AGENTVISOR_GUEST_PROXY_MAX_CONNECTIONS500Maximum total concurrent connections across all agents
AGENTVISOR_GUEST_PROXY_MAX_CONNECTIONS_PER_AGENT50Maximum concurrent connections per agent
AGENTVISOR_GUEST_PROXY_MAX_INFLIGHT_PER_AGENT20Maximum concurrent in-flight requests per agent
AGENTVISOR_GUEST_PROXY_RATE_LIMIT_RPS100.0Per-agent request rate limit (requests per second)
AGENTVISOR_GUEST_PROXY_RATE_LIMIT_BURST200Per-agent rate limit burst capacity
AGENTVISOR_GUEST_PROXY_TLS_HANDSHAKE_TIMEOUT10sMaximum time for TLS handshake
AGENTVISOR_GUEST_PROXY_CONN_MAX_DURATION30mMaximum connection duration before forced close

Per-host TLS certificate settings (guest ephemeral CA):

VariableDefaultDescription
AGENTVISOR_GUEST_CA_VALIDITY720hValidity period for the ephemeral CA certificate
AGENTVISOR_GUEST_CERT_VALIDITY1hValidity period for per-host TLS certificates
AGENTVISOR_GUEST_CERT_EVICTION_INTERVAL5mInterval for evicting expired certificates from cache

Guest Runtime Size & Rate Limits

These settings configure size limits for the guest-runtime's per-agent control surface. They are read by the guest-runtime and can only be set via environment variables.

VariableDefaultDescription
AGENTVISOR_GUEST_CHECKPOINT_MAX_SIZE50MBSizes the guest↔host gRPC transport envelope for SaveCheckpoint/LoadCheckpoint calls — not itself a checkpoint-size ceiling. The real per-checkpoint ceiling is temporal.max_checkpoint_bytes (see Checkpoint Sizing and Limits); startup validation rejects this setting if lowered below the resolved max_checkpoint_bytes value
AGENTVISOR_GUEST_STORE_VALUE_MAX_SIZE10MBMaximum store value size
AGENTVISOR_GUEST_STREAM_CHUNK_MAX_SIZE1MBMaximum stream chunk data size
AGENTVISOR_GUEST_LOG_MESSAGE_MAX_SIZE64KBMaximum log message size

Each AGENTVISOR_GUEST_RATELIMIT_* variable below caps one AgentService RPC category with a per-agent token bucket, format "<rate>/s,<burst>" (e.g. "10/s,20" = 10 requests/second, burst capacity 20). They are read by the guest-runtime and can only be set via environment variables.

VariableDefaultDescription
AGENTVISOR_GUEST_RATELIMIT_HEARTBEAT10/s,20Heartbeat operations
AGENTVISOR_GUEST_RATELIMIT_CHECKPOINT5/s,10SaveCheckpoint, LoadCheckpoint, DeleteCheckpoints, and ListCheckpoints operations share this bucket
AGENTVISOR_GUEST_RATELIMIT_PUTWRITES50/s,100Pending-write operations; kept separate from RATELIMIT_CHECKPOINT because it fires once per task per LangGraph superstep — a meaningfully higher frequency than SaveCheckpoint's once-per-superstep
AGENTVISOR_GUEST_RATELIMIT_STORE50/s,100Key-value store operations
AGENTVISOR_GUEST_RATELIMIT_MCP20/s,50MCP gateway operations
AGENTVISOR_GUEST_RATELIMIT_STREAM100/s,200Stream chunk operations
AGENTVISOR_GUEST_RATELIMIT_LOG100/s,500Log forwarding operations
AGENTVISOR_GUEST_RATELIMIT_INVALIDCALL10/s,20Validation-rejected calls; a separate sub-bucket so adversarial invalid requests can't starve legitimate operations in the per-category buckets above
AGENTVISOR_GUEST_RATELIMIT_TRACING20/s,50ForwardSpans (OpenTelemetry trace export) operations
AGENTVISOR_GUEST_RATELIMIT_STATE50/s,100Thread state operations (StateGet, StatePut, StateDelete, StateList)
AGENTVISOR_GUEST_RATELIMIT_A2A20/s,50A2A gateway operations

Guest Python Debugging

AgentVisor supports interactive debugging with VS Code and PyCharm via debugpy and pydevd. Only available with sandbox: none.

Env varDescription
AGENTVISOR_GUEST_DEBUG_ENABLEDEnable Python remote debugging (supported only with sandbox: none)
AGENTVISOR_GUEST_DEBUG_HOSTDebugger listen host/IP
AGENTVISOR_GUEST_DEBUG_PORTDebugger listen port
AGENTVISOR_GUEST_DEBUG_PROVIDERDebug provider: debugpy (VS Code) or pydevd (PyCharm)
AGENTVISOR_GUEST_DEBUG_WAIT_FOR_CLIENTBlock agent startup until the debugger attaches
guest:
debug:
enabled: false
host: "0.0.0.0"
port: 5678
provider: "debugpy"
wait_for_client: true

Debug Providers

ProviderProtocolBest ForInstall
debugpyDAPVS Code, any DAP clientpip install debugpy
pydevdpydevdPyCharm native featurespip install pydevd-pycharm
agentvisor serve ./my-agent --sandbox=none --debug
agentvisor serve ./my-agent --sandbox=none --debug --debug-provider=pydevd

See Local Development Setup.


Guest SDK Retry

The Python SDK automatically retries transient gRPC errors (UNAVAILABLE, DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED) with exponential backoff.

Global Settings

Env varDescription
AGENTVISOR_GUEST_SDK_RETRY_BASE_DELAY_MSInitial delay between SDK retries in milliseconds
AGENTVISOR_GUEST_SDK_RETRY_ENABLEDEnable automatic retry for transient gRPC failures in the Python SDK
AGENTVISOR_GUEST_SDK_RETRY_EXPONENTIAL_BASEExponential backoff multiplier for SDK retries
AGENTVISOR_GUEST_SDK_RETRY_JITTERAdd randomized delay (jitter) to SDK retries to prevent thundering herd
AGENTVISOR_GUEST_SDK_RETRY_MAX_ATTEMPTSMaximum retry attempts including the initial attempt
AGENTVISOR_GUEST_SDK_RETRY_MAX_DELAY_MSMaximum delay between SDK retries in milliseconds
guest:
sdk:
retry:
base_delay_ms: 100
enabled: true
exponential_base: 2
jitter: true
max_attempts: 3
max_delay_ms: 5000

Per-Operation Overrides

Each operation type can override the global settings. Available operations: checkpoint, store, mcp, a2a, stream. Each supports: max_attempts, base_delay_ms, max_delay_ms, exponential_base, jitter.

guest:
sdk:
retry:
# Global defaults shown above; per-operation overrides:
checkpoint:
max_attempts: 5
mcp:
max_attempts: 2
base_delay_ms: 500

See SDK Retry Reference for per-operation defaults and programmatic API.


Store

The Store API provides persistent key-value storage for agents. Disabled by default.

Env varDescription
AGENTVISOR_STORE_PROVIDERStore backend: empty (disabled), sqlite (single-instance), or postgresql
store:
provider: ""

Provider-specific options use store.<provider>.* in YAML or AGENTVISOR_STORE_<PROVIDER>_<KEY> as env vars:

# SQLite (single-instance / development):
store:
provider: sqlite
sqlite:
db_path: /var/lib/agentvisor/store.db # default: <cache_dir>/store.db

# PostgreSQL (multi-instance deployments):
store:
provider: postgresql
postgresql:
connection_string: "postgres://user:pass@localhost:5432/agentvisor"
tls_mode: verify-full
tls_ca_file: /path/ca.crt
tls_cert_file: /path/client.crt
tls_key_file: /path/client.key
pool_max_conns: 10
connect_timeout: 10s

PostgreSQL env vars:

VariableDescription
AGENTVISOR_STORE_POSTGRESQL_CONNECTION_STRINGPostgreSQL connection URI
AGENTVISOR_STORE_POSTGRESQL_TLS_MODESSL mode: disable, require, verify-ca, verify-full
AGENTVISOR_STORE_POSTGRESQL_TLS_CA_FILECA certificate path
AGENTVISOR_STORE_POSTGRESQL_TLS_CERT_FILEClient certificate path
AGENTVISOR_STORE_POSTGRESQL_TLS_KEY_FILEClient private key path
AGENTVISOR_STORE_POSTGRESQL_POOL_MAX_CONNSMaximum pool connections (default: 4)
AGENTVISOR_STORE_POSTGRESQL_CONNECT_TIMEOUTConnection timeout (default: 2m)

MCP Gateway

The MCP Gateway allows agents to access external MCP servers (GitHub, Slack, filesystem tools, etc.). AgentVisor manages connections and credentials on behalf of agents.

note

This section documents the MCP Gateway (agents → external MCP servers). To expose agents as MCP tools to external clients (Claude Desktop, Cursor), see API Transports and enable api.mcp.enabled.

Stdio Sandbox Image

When mcp.servers[] includes stdio entries and guest.sandbox is not none, AgentVisor runs each stdio MCP server inside a dedicated mcp-tools sandbox (providing node/npx and python/uvx). The rootfs for that sandbox is resolved using the following priority order (first match wins):

  1. mcp.tools_rootfs_path — explicit pre-extracted directory on disk
  2. /opt/agentvisor/mcp-tools-rootfs — baked into images built with agentvisor build --bundle-mcp-tools
  3. On-demand pull of mcp.tools_image — pulled and cached on first use; defaults to the version-matched ghcr.io/manetu/agentvisor/agentvisor-mcp-tools:<version>
Env varConfig keyDescription
AGENTVISOR_MCP_TOOLS_IMAGEmcp.tools_imageOCI image reference for the mcp-tools sandbox. Defaults to the version-matched image from buildinfo. Consulted only when tools_rootfs_path is unset and the baked rootfs is absent.
AGENTVISOR_MCP_TOOLS_ROOTFS_PATHmcp.tools_rootfs_pathPath to a pre-extracted mcp-tools rootfs directory. Takes precedence over the baked rootfs and any image pull.
mcp:
# tools_rootfs_path: "/path/to/pre-extracted/mcp-tools-rootfs" # AGENTVISOR_MCP_TOOLS_ROOTFS_PATH
# tools_image: "ghcr.io/manetu/agentvisor/agentvisor-mcp-tools:latest" # AGENTVISOR_MCP_TOOLS_IMAGE

See MCP Gateway: The mcp-tools Sandbox Image for the full explanation.

Pre-installing packages (prepull)

To pre-install npm or PyPI packages into the sandbox before startup, use mcp.prepull in mav-agent-config.yaml (not agentvisor.yaml). See MCP Gateway: Pre-installing Packages for the schema and usage.

Connection Pool

Env varDescription
AGENTVISOR_MCP_POOL_IDLE_TIMEOUTClose idle principal-bound MCP connections after this duration
AGENTVISOR_MCP_POOL_MAX_SIZEMaximum connections in the principal-bound MCP LRU pool
mcp:
pool:
idle_timeout: "5m"
max_size: 100

Startup Failure Posture

Env varConfig keyDefaultDescription
AGENTVISOR_MCP_ON_CONNECT_FAILUREmcp.on_connect_failurefailBehavior when a static (non-principal-bound) MCP server fails to connect at startup. fail aborts startup; warn logs a warning and continues in a degraded state — the degraded status and failure counts are always visible via GET /ready regardless of this setting, while failed server names and failure classes are only disclosed to an authorized principal.
mcp:
on_connect_failure: fail # fail | warn

Audit Logging

Env varConfig keyDefaultDescription
AGENTVISOR_MCP_LOG_LEVELmcp.log_levelsummaryVerbosity of MCP gateway call audit logging: none, summary, full. Independent of both AGENTVISOR_LOG_LEVEL and a2a_gateway.log_level — mirrors the guest.proxy.log_level split between severity and audit detail.
mcp:
log_level: summary # none | summary | full

Server Configuration

MCP servers are configured in the YAML file only (mcp.servers[] — not expressible as flat env vars):

FieldRequiredDescription
nameYesUnique identifier for the server
transportYesTransport type: stdio, sse, or streamable_http
commandstdio onlyCommand and arguments to launch the server
urlHTTP onlyServer URL
envNoEnvironment variables for stdio servers. Values support $VAR / ${VAR} expansion against host env vars (use $$ for a literal $). Unset variables log a warning and expand to "".
credentialsNoAuthentication configuration
enrichmentNoAuthz enrichment (rego or http provider)
tlsHTTP onlyOutbound TLS trust configuration for url. Rejected as a config error on stdio servers.

Transport Types

TransportDescriptionWhen to Use
stdioSpawns a local process, communicates via stdin/stdoutLocal tools (filesystem, git, shell)
sseServer-Sent Events over HTTPLegacy remote MCP servers
streamable_httpBidirectional HTTP streamingModern remote MCP servers (recommended)

Examples

mcp:
servers:
- name: filesystem
transport: stdio
command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"]

- name: github
transport: streamable_http
url: "https://api.githubcopilot.com/mcp/"
credentials:
type: bearer_token
source: env
env_var: GITHUB_TOKEN

- name: internal-service
transport: streamable_http
url: "https://internal.example.com/mcp"
credentials:
type: principal_passthrough
# tls: # Optional: trust a private CA for url
# mode: verify-ca
# ca_file: /etc/ssl/internal-service-ca.pem

- name: scoped-service
transport: streamable_http
url: "https://service.example.com/mcp"
credentials:
type: token_exchange
exchange_url: "https://auth.example.com/oauth/token"
audience: "service.example.com"
client_id: "agentvisor-client"
client_secret_env_var: "SERVICE_CLIENT_SECRET"
# tls: # Optional: trust a private CA for exchange_url
# mode: verify-ca
# ca_file: /etc/ssl/internal-idp-ca.pem

pool:
max_size: 100
idle_timeout: 5m
TLS trust for MCP servers

mcp.servers[].tls configures outbound trust for the connection to that server's url (e.g. tls.ca_file to trust a private CA). Only valid for sse/streamable_http transports — see TLS Trust Configuration for the full field reference.

Credential Types Reference

TypeFieldsDescription
bearer_tokensource, env_varStatic bearer token from env var
api_keyheader, source, env_varCustom header with API key
principal_passthrough(none)Forward caller's JWT
token_exchangeexchange_url, audience, scope, subject_token_type, client_id, client_secret, client_secret_env_var, tlsRFC 8693 token exchange; supports confidential clients
Subject Token Type

subject_token_type defaults to access_token, compatible with Keycloak and most OAuth 2.0 servers. Override with jwt, id_token, saml1, saml2, or a full URN if needed.

TLS trust for exchange_url

tls configures outbound trust for the token_exchange resolver's call to exchange_url (e.g. tls.ca_file to trust a private CA). See TLS Trust Configuration for the full field reference.

Connection Pool Behavior

  • Static servers (no credentials, bearer_token, api_key, stdio): Shared connections created at startup
  • Principal-bound servers (principal_passthrough, token_exchange): Per-(server, principal) connections in LRU cache

Enrichment Definitions

The top-level enrichment.definitions section (a peer of mcp:/a2a_gateway:, not nested under either) lets you define a reusable enrichment provider configuration once and reference it by name from any mcp.servers[].enrichment or a2a_gateway.agents[].enrichment block via ref:, instead of repeating the same provider/options/rego fields at every site.

enrichment:
definitions:
- name: corp-http-enricher
provider: http
options:
url: https://enrich.example.com/enrich
timeout: 5s
tls:
mode: verify-full
ca_file: /etc/ssl/enrich-ca.pem
headers:
- { name: Authorization, value_env: ENRICH_TOKEN }
- name: repo-rego
provider: rego
rego_policy: /etc/agentvisor/policies/enrich.rego
FieldRequiredDescription
enrichment.definitions[].nameYesUnique identifier referenced by a site's ref: field. A duplicate name is a config validation error at startup.
enrichment.definitions[].providerYesProvider type: rego or http.
enrichment.definitions[].optionsConditionalProvider-specific options (required for http; see http Provider Options below).
enrichment.definitions[].rego_policyConditionalPath to a Rego policy file (rego provider).
enrichment.definitions[].rego_policy_inlineConditionalInline Rego policy string (rego provider).

Definitions must be fully inline — a definition cannot itself set ref, context, or headers (those are site-level overrides; see below).

note

This section is YAML-only; there is no flat AGENTVISOR_ENRICHMENT_DEFINITIONS_* environment variable form, consistent with other list-of-struct sections like mcp.servers[] and proxy.credentials[].

Authorization Enrichment

Enrichment is configured per MCP server (mcp.servers[].enrichment) or per A2A agent (a2a_gateway.agents[].enrichment) — the fields below are identical for both. A site can configure a provider fully inline, or reference a shared enrichment definition via ref:.

Fully inline:

mcp:
servers:
- name: github
transport: streamable_http
url: "https://api.githubcopilot.com/mcp/"
credentials:
type: bearer_token
source: env
env_var: GITHUB_TOKEN
enrichment:
provider: rego
rego_policy_inline: |
package agentvisor.authz.enrichment
result := {"operation": op, "resource": res} if {
input.tool_name == "list_commits"
repo := input.arguments.repo
op := sprintf("mcp:tool:github:repo:%v:commits:list", [repo])
res := sprintf("mrn:agentvisor:github:repo:%v", [repo])
}

Referencing a central definition, with per-site overrides:

mcp:
servers:
- name: github
enrichment:
ref: corp-http-enricher # see Enrichment Definitions above
context: # merged into the provider's site_context
site: github-mcp
environment: prod
headers: # http provider only; merged by header name
- { name: X-Enrichment-Site, value: github-mcp }
FieldRequiredDescription
providerConditionalProvider type: rego or http. Required unless ref is set; mutually exclusive with ref.
optionsConditionalProvider-specific options. Required for http inline configs; mutually exclusive with ref.
rego_policyConditionalPath to a Rego policy file (rego provider). Mutually exclusive with rego_policy_inline and ref.
rego_policy_inlineConditionalInline Rego policy string (rego provider). Mutually exclusive with rego_policy and ref.
refNoName of an enrichment.definitions[] entry to use as the base configuration. Mutually exclusive with provider/options/rego_policy/rego_policy_inline. An unknown name fails startup.
contextNoArbitrary key/value map layered onto the resolved options as site_context — passed to rego as input.site_context and to http as the request body's site_context field. Works with or without ref.
headersNo[]{name, value, value_env} list merged into the resolved http provider's headers, by header name (new names appended, matching names overridden). Ignored with a startup warning if the resolved provider is not http.

rego_policy and rego_policy_inline are mutually exclusive — set exactly one when using the rego provider inline.

http Provider Options

The http enrichment provider's TLS/mTLS/header/timeout options follow the same shape and semantics as the authz HTTP Provider used for MPE/PDP authorization — see that section for TLS mode trade-offs.

enrichment:
definitions:
- name: corp-http-enricher
provider: http
options:
url: https://enrich.example.com/enrich # required
timeout: 5s # default: 5s
tls:
mode: verify-full # disable | require | verify-ca | verify-full (default: verify-full for https://)
ca_file: /etc/ssl/enrich-ca.pem
ca_data: ""
cert_file: /etc/ssl/client.pem # optional, for mTLS
cert_data: ""
key_file: /etc/ssl/client-key.pem
key_data: ""
server_name: enrich.internal # optional TLS SNI override
headers:
- name: Authorization
value_env: ENRICH_TOKEN # preferred: read from host env at startup
# value: "literal-value" # supported, but logs a startup warning
retry: # optional; shown values are the defaults
enabled: true # set false to disable retry entirely
max_attempts: 3 # total tries, including the first
initial_interval: 100ms
max_interval: 1s
max_elapsed_time: 1.5s # hard cap on total time spent retrying
FieldRequiredDescription
options.urlYesEnrichment endpoint. POSTed to verbatim — no path is appended (unlike the PDP provider, which appends /decision).
options.timeoutNoRequest timeout (default 5s).
options.tls.modeNodisable, require, verify-ca, or verify-full (default verify-full for https:// URLs).
options.tls.ca_file / options.tls.ca_dataNoCA certificate for verifying the enrichment server (file path or base64-encoded PEM).
options.tls.cert_file / options.tls.cert_data, options.tls.key_file / options.tls.key_dataNoClient certificate/key for mTLS.
options.tls.server_nameNoTLS SNI override.
options.headers[]NoStatic request headers ({name, value, value_env}); value_env is preferred over value to avoid committing secrets to version control.
options.retry.enabledNoEnables bounded retry for transient failures (default true). Set false to disable.
options.retry.max_attemptsNoTotal tries, including the first (default 3).
options.retry.initial_intervalNoInitial exponential-backoff interval (default 100ms).
options.retry.max_intervalNoBackoff interval cap (default 1s).
options.retry.max_elapsed_timeNoHard cap on total time spent retrying, across all attempts (default 1.5s). Bounds tail latency on this synchronous, pre-authorization call regardless of max_attempts.

Retry applies only to transient conditions: network errors and 429/502/503/504 responses. Any other error (a non-retryable status, a malformed response body) is returned immediately without retrying. Retry is an availability optimization on top of the fail-open contract below — it reduces how often a transient blip causes this provider to be skipped, but exhausting retries still fails open rather than blocking the request.

note

The http enrichment provider is fail-open — an outage or bad response degrades to the original, un-enriched operation/resource rather than blocking the request. This is the opposite of the fail-closed HTTP Provider used for MPE/PDP authorization. See Authorization Enrichment concepts for the full request/response wire protocol.

See Authorization Enrichment for the full guide.

Debug Logging

AGENTVISOR_LOG_LEVEL=info,mcp=debug agentvisor serve ./my-agent

See MCP Gateway Guide for architecture and security details.


A2A Gateway

The A2A Gateway allows agents to communicate with external A2A-compatible agents using Google's Agent-to-Agent protocol (JSON-RPC 2.0 with SSE streaming).

note

This section documents the A2A Gateway (agents → external A2A agents). To expose agents via A2A protocol to external clients, see API Transports and enable api.a2a.enabled.

Connection Pool & Defaults

Env varDescription
AGENTVISOR_A2A_GATEWAY_POOL_IDLE_TIMEOUTClose idle principal-bound A2A connections after this duration
AGENTVISOR_A2A_GATEWAY_POOL_MAX_SIZEMaximum connections in the principal-bound A2A LRU pool
AGENTVISOR_A2A_GATEWAY_DEFAULTS_TIMEOUTDefault request timeout for A2A agent calls
AGENTVISOR_A2A_GATEWAY_DEFAULTS_RETRY_INITIAL_INTERVALInitial backoff between A2A retry attempts (exponential backoff)
AGENTVISOR_A2A_GATEWAY_DEFAULTS_RETRY_MAX_ATTEMPTSMaximum retry attempts for A2A requests
AGENTVISOR_A2A_GATEWAY_DEFAULTS_RETRY_MAX_INTERVALMaximum backoff between A2A retry attempts
a2a_gateway:
defaults:
retry:
initial_interval: "1s"
max_attempts: 3
max_interval: "30s"
timeout: "1m"
log_level: "summary"
on_connect_failure: "fail"
pool:
idle_timeout: "5m"
max_size: 100

Startup Failure Posture

Env varConfig keyDefaultDescription
AGENTVISOR_A2A_GATEWAY_ON_CONNECT_FAILUREa2a_gateway.on_connect_failurefailBehavior when a static (non-principal-bound) A2A agent fails to connect at startup. fail aborts startup; warn logs a warning and continues in a degraded state — the degraded status and failure counts are always visible via GET /ready regardless of this setting, while failed agent names and failure classes are only disclosed to an authorized principal.

Audit Logging

Env varConfig keyDefaultDescription
AGENTVISOR_A2A_GATEWAY_LOG_LEVELa2a_gateway.log_levelsummaryVerbosity of A2A gateway call audit logging: none, summary, full. Independent of both AGENTVISOR_LOG_LEVEL and mcp.log_level — mirrors the guest.proxy.log_level split between severity and audit detail.
a2a_gateway:
log_level: summary # none | summary | full

Agent Configuration

A2A agents are configured in the YAML file only (a2a_gateway.agents[]):

FieldRequiredDescription
nameYesUnique identifier (used in SDK calls)
urlYesA2A agent endpoint URL
credentialsNoAuthentication configuration (same types as MCP)
timeoutNoPer-agent timeout override
retryNoPer-agent retry override
enrichmentNoAuthz enrichment (rego or http provider)
tlsNoOutbound TLS trust configuration for url
a2a_gateway:
agents:
- name: research-agent
url: "https://research.example.com/a2a"
credentials:
type: bearer_token
source: env
env_var: RESEARCH_AGENT_TOKEN
timeout: 120s

- name: internal-agent
url: "https://internal.example.com/a2a"
credentials:
type: principal_passthrough
# tls: # Optional: trust a private CA for url
# mode: verify-ca
# ca_file: /etc/ssl/internal-agent-ca.pem
TLS trust for A2A agents

a2a_gateway.agents[].tls configures outbound trust for the connection to that agent's url (e.g. tls.ca_file to trust a private CA). See TLS Trust Configuration for the full field reference.

Task States

StateDescription
workingTask is in progress
input_requiredTask needs additional input from the caller
auth_requiredTask requires authentication
completedTask finished successfully
failedTask failed with an error
canceledTask was canceled
rejectedTask was rejected by the agent

See A2A Gateway Guide for usage examples and SDK integration.


Telemetry

OpenTelemetry distributed tracing and Prometheus metrics.

Env varDescription
AGENTVISOR_TELEMETRY_ENVIRONMENTDeployment environment tag (e.g. development, production)
AGENTVISOR_TELEMETRY_SERVICE_NAMEOTLP service.name resource attribute for the host process
telemetry:
environment: "development"
service_name: "agentvisor-host"

Tracing

Env varDescription
AGENTVISOR_TELEMETRY_TRACING_ENABLEDEnable OTLP trace export
AGENTVISOR_TELEMETRY_TRACING_ENDPOINTOTLP collector endpoint; for gRPC: host:port; for HTTP: URL with path
AGENTVISOR_TELEMETRY_TRACING_HEADERSCustom HTTP headers for OTLP/HTTP export; used for authentication (e.g. Langfuse). Config file only (YAML map) -- this env var is not bound
AGENTVISOR_TELEMETRY_TRACING_PROTOCOLOTLP transport: grpc (default) or http
AGENTVISOR_TELEMETRY_TRACING_SAMPLE_RATETrace sampling rate from 0.0 (none) to 1.0 (all)
AGENTVISOR_TELEMETRY_TRACING_TLS_CA_DATABase64-encoded PEM CA certificate for verifying the OTLP collector (alternative to ca_file)
AGENTVISOR_TELEMETRY_TRACING_TLS_CA_FILEPath to PEM CA certificate for verifying the OTLP collector
AGENTVISOR_TELEMETRY_TRACING_TLS_CERT_DATABase64-encoded PEM client certificate for mTLS to the collector (alternative to cert_file)
AGENTVISOR_TELEMETRY_TRACING_TLS_CERT_FILEPath to PEM client certificate for mTLS authentication to the collector
AGENTVISOR_TELEMETRY_TRACING_TLS_KEY_DATABase64-encoded PEM client private key for mTLS to the collector (alternative to key_file)
AGENTVISOR_TELEMETRY_TRACING_TLS_KEY_FILEPath to PEM client private key for mTLS authentication to the collector
AGENTVISOR_TELEMETRY_TRACING_TLS_MODETLS verification mode: verify-full (default), verify-ca, require, or disable — an unset mode defaults to verify-full
AGENTVISOR_TELEMETRY_TRACING_TLS_SERVER_NAMETLS SNI server name override
AGENTVISOR_TELEMETRY_TRACING_TLS_TRUST_SYSTEM_ROOTSAppend the configured CA to the system root pool instead of replacing it (default: false)
telemetry:
tracing:
enabled: false
endpoint: "localhost:4317"
headers: {}
protocol: "grpc"
sample_rate: 1
tls:
ca_data: ""
ca_file: ""
cert_data: ""
cert_file: ""
key_data: ""
key_file: ""
mode: ""
server_name: ""
trust_system_roots: false

Metrics

Env varDescription
AGENTVISOR_TELEMETRY_METRICS_ENABLEDEnable Prometheus metrics endpoint
AGENTVISOR_TELEMETRY_METRICS_ENDPOINTHTTP path for the Prometheus metrics endpoint
telemetry:
metrics:
enabled: false
endpoint: "/metrics"

Trace Propagation

Env varDescription
AGENTVISOR_TELEMETRY_PROPAGATION_INPUTTrace context formats to extract from incoming requests (comma-separated): tracecontext, baggage, b3, b3multi, jaeger, xray
AGENTVISOR_TELEMETRY_PROPAGATION_OUTPUTTrace context formats to inject into outgoing requests (comma-separated): tracecontext, baggage, b3, b3multi, jaeger, xray
telemetry:
propagation:
input:
- tracecontext
- baggage
output:
- tracecontext
- baggage

Agent Span Forwarding

Env varDescription
AGENTVISOR_TELEMETRY_AGENT_TRACING_ENABLEDForward OTLP spans from agents to the host exporter
AGENTVISOR_TELEMETRY_AGENT_TRACING_SERVICE_NAME_TEMPLATETemplate for service.name on forwarded agent spans; supports {agent_name} (empty = preserve original)
telemetry:
agent_tracing:
enabled: true
service_name_template: ""

Langfuse Example

telemetry:
service_name: agentvisor-host
environment: production
tracing:
enabled: true
protocol: http
endpoint: https://cloud.langfuse.com/api/public/otel
headers:
Authorization: "Basic <base64(publicKey:secretKey)>"
agent_tracing:
enabled: true
service_name_template: "agent-{agent_name}"

gVisor Syscall Tracing

gVisor syscall tracing provides visibility into agent behavior for security monitoring, debugging, and compliance. Only applies to the gvisor sandbox mode.

See Runtime Tracing for architecture details and Security Monitoring Guide for operational guidance.

Env varDescription
AGENTVISOR_TRACE_CATEGORIESPreset syscall groups to trace (comma-separated): file_access, process, network, identity, filesystem
AGENTVISOR_TRACE_CONTEXT_FIELDSgVisor context fields to include in events: container_id, process_name, credentials, cwd
AGENTVISOR_TRACE_ENABLEDEnable gVisor syscall tracing for security monitoring and observability
AGENTVISOR_TRACE_OPTIONAL_FIELDSExpensive optional fields to include in events: fd_path (resolves file descriptors to paths)
AGENTVISOR_TRACE_SYSCALLSExplicit list of syscalls to trace (alternative to categories; comma-separated)
trace:
categories:
- file_access
- process
context_fields: []
enabled: false
optional_fields: []
syscalls: []

Trace Categories

CategoryDescription
file_accessFile open, read, write, close operations
processProcess creation, execution, exit
networkSocket operations, connections
identityUser/group ID operations
filesystemMount, unmount, filesystem metadata

Event Buffer

Env varDescription
AGENTVISOR_TRACE_BUFFER_DROP_POLICYAction when the trace event buffer is full: oldest (drop oldest), newest (drop new), or block
AGENTVISOR_TRACE_BUFFER_SIZETrace event ring buffer capacity (number of events)
trace:
buffer:
drop_policy: "oldest"
size: 10000
Drop PolicyDescription
oldestDrop oldest events when buffer is full (default)
newestDrop new events when buffer is full
blockBlock until space is available (may impact agent performance)

Classification Rules (Rego)

Env varDescription
AGENTVISOR_TRACE_RULES_ENABLEDEnable Rego-based event classification engine for trace events
AGENTVISOR_TRACE_RULES_POLICY_FILESPaths to Rego policy files for trace event classification (comma-separated)
AGENTVISOR_TRACE_RULES_POLICY_INLINEInline Rego policy string for trace event classification
AGENTVISOR_TRACE_RULES_USE_DEFAULT_POLICYLoad the built-in default classification policy when the Rego rules engine is enabled
trace:
rules:
enabled: false
policy_files: []
policy_inline: ""
use_default_policy: true

Log, Metrics & OTEL Sinks

Env varDescription
AGENTVISOR_TRACE_SINKS_LOG_ENABLEDEnable structured log sink for trace events
AGENTVISOR_TRACE_SINKS_LOG_LEVELMinimum severity level for log sink output: debug, info, warn, or error
AGENTVISOR_TRACE_SINKS_METRICS_ENABLEDEnable Prometheus metrics sink for trace event counts
AGENTVISOR_TRACE_SINKS_OTEL_ENABLEDEnable OpenTelemetry trace sink (exports trace events as OTEL spans)

gRPC Streaming Sink

Env varDescription
AGENTVISOR_TRACE_SINKS_GRPC_BUFFER_SIZEEvent buffer size for the gRPC trace sink (handles network hiccups)
AGENTVISOR_TRACE_SINKS_GRPC_ENABLEDEnable gRPC streaming sink for real-time trace event consumers
AGENTVISOR_TRACE_SINKS_GRPC_ENDPOINTgRPC server address for streaming trace events (e.g. collector.example.com:9090)
AGENTVISOR_TRACE_SINKS_GRPC_MAX_RECONNECT_BACKOFFMaximum backoff between gRPC trace sink reconnection attempts
AGENTVISOR_TRACE_SINKS_GRPC_RECONNECT_INTERVALInitial wait before reconnecting the gRPC trace sink after a failure
AGENTVISOR_TRACE_SINKS_GRPC_TLS_CA_DATABase64-encoded PEM CA certificate for verifying the gRPC trace sink server (alternative to ca_file)
AGENTVISOR_TRACE_SINKS_GRPC_TLS_CA_FILEPath to PEM CA certificate for verifying the gRPC trace sink server
AGENTVISOR_TRACE_SINKS_GRPC_TLS_CERT_DATABase64-encoded PEM client certificate for mTLS to the gRPC trace sink (alternative to cert_file)
AGENTVISOR_TRACE_SINKS_GRPC_TLS_CERT_FILEPath to PEM client certificate for mTLS authentication to the gRPC trace sink
AGENTVISOR_TRACE_SINKS_GRPC_TLS_KEY_DATABase64-encoded PEM client private key for mTLS to the gRPC trace sink (alternative to key_file)
AGENTVISOR_TRACE_SINKS_GRPC_TLS_KEY_FILEPath to PEM client private key for mTLS authentication to the gRPC trace sink
AGENTVISOR_TRACE_SINKS_GRPC_TLS_MODETLS verification mode: verify-full, verify-ca, require, or disable. Unset with no other TLS options means TLS is off. require needs AGENTVISOR_TLS_ALLOW_INSECURE=true
AGENTVISOR_TRACE_SINKS_GRPC_TLS_SERVER_NAMETLS SNI server name override for the gRPC trace sink
AGENTVISOR_TRACE_SINKS_GRPC_TLS_TRUST_SYSTEM_ROOTSAppend the configured CA to the system root pool instead of replacing it (default: false)
AGENTVISOR_TRACE_SINKS_GRPC_AUTH_ENV_VAREnvironment variable containing the bearer token for gRPC trace sink authentication
AGENTVISOR_TRACE_SINKS_GRPC_AUTH_TYPEAuthentication for the gRPC trace sink: none or bearer_token
trace:
sinks:
grpc:
auth:
env_var: ""
type: "none"
buffer_size: 1000
enabled: false
endpoint: ""
max_reconnect_backoff: "1m"
reconnect_interval: "5s"
tls:
ca_data: ""
ca_file: ""
cert_data: ""
cert_file: ""
key_data: ""
key_file: ""
mode: ""
server_name: ""
trust_system_roots: false

Webhook Sink

Env varDescription
AGENTVISOR_TRACE_SINKS_WEBHOOK_BATCH_SIZENumber of events to batch before sending to the webhook endpoint
AGENTVISOR_TRACE_SINKS_WEBHOOK_ENABLEDEnable webhook sink for streaming trace events to SIEM or security dashboards
AGENTVISOR_TRACE_SINKS_WEBHOOK_FLUSH_INTERVALMaximum time to wait before flushing a partial batch to the webhook
AGENTVISOR_TRACE_SINKS_WEBHOOK_HEADERSCustom HTTP headers for webhook requests. Config file only (YAML map) -- this env var is not bound; values are used verbatim, with no ${VAR} substitution
AGENTVISOR_TRACE_SINKS_WEBHOOK_TIMEOUTHTTP request timeout for webhook deliveries
AGENTVISOR_TRACE_SINKS_WEBHOOK_URLWebhook endpoint URL for trace event delivery
AGENTVISOR_TRACE_SINKS_WEBHOOK_RETRY_BACKOFFInitial backoff for webhook retry attempts (exponential with jitter)
AGENTVISOR_TRACE_SINKS_WEBHOOK_RETRY_MAX_ATTEMPTSMaximum retry attempts for failed webhook deliveries
AGENTVISOR_TRACE_SINKS_WEBHOOK_RETRY_MAX_BACKOFFMaximum backoff for webhook retry attempts
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_CA_DATABase64-encoded PEM CA certificate for verifying the webhook HTTPS endpoint (alternative to ca_file)
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_CA_FILEPath to PEM CA certificate for verifying the webhook HTTPS endpoint
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_CERT_DATABase64-encoded PEM client certificate for mTLS to the webhook endpoint (alternative to cert_file)
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_CERT_FILEPath to PEM client certificate for mTLS authentication to the webhook endpoint
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_KEY_DATABase64-encoded PEM client private key for mTLS to the webhook endpoint (alternative to key_file)
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_KEY_FILEPath to PEM client private key for mTLS authentication to the webhook endpoint
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_MODETLS verification mode: verify-full, verify-ca, require, or disable. Unset with no other TLS options means TLS follows the URL scheme with the default verify-full posture. require needs AGENTVISOR_TLS_ALLOW_INSECURE=true
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_SERVER_NAMETLS SNI server name override for the webhook endpoint
AGENTVISOR_TRACE_SINKS_WEBHOOK_TLS_TRUST_SYSTEM_ROOTSAppend the configured CA to the system root pool instead of replacing it (default: false)
AGENTVISOR_TRACE_SINKS_WEBHOOK_CIRCUIT_BREAKER_ENABLEDEnable circuit breaker protection for the webhook trace sink
AGENTVISOR_TRACE_SINKS_WEBHOOK_CIRCUIT_BREAKER_FAILURE_THRESHOLDConsecutive failures before the webhook circuit breaker opens
AGENTVISOR_TRACE_SINKS_WEBHOOK_CIRCUIT_BREAKER_RESET_TIMEOUTWait time before the webhook circuit breaker attempts to close
trace:
sinks:
webhook:
batch_size: 100
circuit_breaker:
enabled: true
failure_threshold: 5
reset_timeout: "30s"
enabled: false
flush_interval: "5s"
headers: {}
retry:
backoff: "1s"
max_attempts: 3
max_backoff: "30s"
timeout: "10s"
tls:
ca_data: ""
ca_file: ""
cert_data: ""
cert_file: ""
key_data: ""
key_file: ""
mode: ""
server_name: ""
trust_system_roots: false
url: ""

Persistent Store Sink

Env varDescription
AGENTVISOR_TRACE_SINKS_STORE_ENABLEDEnable persistent file/SQLite storage sink for trace events (audit trail)
AGENTVISOR_TRACE_SINKS_STORE_FLUSH_INTERVALHow often to flush buffered trace events to the store
AGENTVISOR_TRACE_SINKS_STORE_MAX_FILE_SIZEMaximum size per trace storage file before rotation (bytes)
AGENTVISOR_TRACE_SINKS_STORE_PATHBase directory for persistent trace event storage
AGENTVISOR_TRACE_SINKS_STORE_PRUNE_INTERVALHow often to run the retention pruning job for stored trace events
AGENTVISOR_TRACE_SINKS_STORE_RETENTIONHow long to retain stored trace events before automatic pruning
AGENTVISOR_TRACE_SINKS_STORE_TYPEStorage backend for trace events: file or sqlite
trace:
sinks:
store:
enabled: false
flush_interval: "5s"
max_file_size: 104857600
path: "/var/lib/agentvisor/trace"
prune_interval: "1h"
retention: "168h"
type: "file"

Example Configuration

trace:
enabled: true
categories:
- file_access
- process
- network
context_fields:
- container_id
- process_name
sinks:
log:
enabled: true
level: info
metrics:
enabled: true
grpc:
enabled: true
endpoint: "trace-collector.example.com:9090"
tls:
mode: verify-full
ca_file: /etc/agentvisor/trace-ca.crt

AgentVisor Identity

AgentVisor ID provides a unique identifier for this AgentVisor instance, used in:

  • Policy Enforcement: Added as the outermost act.sub claim per RFC 8693
  • Telemetry: Used as the OTEL service name
  • Logging: Included in all log messages as agentvisor_id
  • Authorization Enrichment: Surfaced to enrichment providers as agentvisor_id (see Authorization Enrichment)
Naming Distinction

"AgentVisor ID" identifies the AgentVisor instance itself, distinct from the LangGraph Agent Protocol's agent_id which refers to graph/agent names within the system.

Env varDescription
AGENTVISOR_ID_TYPEAgentVisor instance identity provider: string (literal), env (from environment variable), or empty to disable

Provider-specific options use env var patterns AGENTVISOR_ID_<TYPE>_<KEY>:

VariableDescription
AGENTVISOR_ID_STRING_VALUELiteral ID value (string provider)
AGENTVISOR_ID_ENV_VAREnvironment variable name (env provider)
AGENTVISOR_ID_ENV_DEFAULTFallback value when env var is not set (env provider)

Examples

# Literal string
id:
type: string
string:
value: production-agent-1

# From environment variable
id:
type: env
env:
var: HOSTNAME
default: unknown-agent

RFC 8693 Delegation Chain

When AgentVisor ID is configured, authorization requests include the agent as an actor in the delegation chain:

{
"sub": "user@example.com",
"act": { "sub": "my-agent", "act": {"sub": "api-gateway"} }
}

Analytics

PostHog product analytics are enabled by default in official release builds. Development builds never report.

Env varDescription
AGENTVISOR_ANALYTICS_ENABLEDEnable PostHog product analytics; set to false to opt out
AGENTVISOR_ANALYTICS_ENDPOINTCustom PostHog ingestion endpoint (empty = PostHog cloud default)
analytics:
enabled: true
endpoint: ""

What is transmitted

A single runtime_started event is emitted per startup. The event is keyed by a distinct_id that is an HMAC-SHA256 of the machine hostname (or of the configured AgentVisor ID when set), keyed by a random secret generated once and persisted under the cache directory (<cache_dir>/analytics-id.key) — the raw hostname and AgentVisor ID never leave the process, and without the local key the ID cannot be reversed by dictionary attack even though hostnames come from a guessable namespace. Server-side IP geolocation (GeoIP enrichment) is disabled. No security-posture configuration (authorization provider, API authentication, TLS, or payload-codec settings) is transmitted, and gateway counts are coarsened into range buckets (0, 1-5, 6+) rather than exact values.

The complete property list is below. This table is pinned by a test (TestAnalyticsPayload_MatchesDocumentedPayload), so any change to what is transmitted must be reflected here.

PropertyDescription
sandbox_modeConfigured sandbox mode (none, docker, gvisor)
openapi_enabledWhether the OpenAPI/REST transport is enabled
mcp_transport_enabledWhether the MCP transport is enabled
a2a_transport_enabledWhether the A2A transport is enabled
mcp_gateway_serversNumber of configured MCP gateway servers, bucketed (0, 1-5, 6+)
a2a_gateway_agentsNumber of configured A2A gateway agents, bucketed (0, 1-5, 6+)
telemetry_tracing_enabledWhether OpenTelemetry tracing is enabled
telemetry_metrics_enabledWhether OpenTelemetry metrics are enabled
store_providerConfigured store backend (sqlite, postgresql, or empty)
exec_modeWhether the runtime is in exec mode
agentvisor_id_configuredWhether an AgentVisor ID is configured (boolean, not the ID itself)
versionAgentVisor release version
osOperating system (GOOS)
archCPU architecture (GOARCH)
customer_idOpaque Cryptolens customer record ID (licensed deployments only; never the license key)
license_idOpaque Cryptolens license record ID (licensed deployments only; never the license key)

License

Some AgentVisor distributions require a license key to run.

Env varDescription
AGENTVISOR_LICENSE_KEYLicense key — set via AGENTVISOR_LICENSE_KEY env var only; rejected if present in YAML
AGENTVISOR_LICENSE_MACHINE_CODEOptional machine identifier for node-locked licenses
AGENTVISOR_LICENSE_STORAGE_BACKENDKeyring backend: auto, keychain (macOS), secret-service (Linux/GNOME), pass, kwallet, wincred
AGENTVISOR_LICENSE_STORAGE_SERVICEKeyring service namespace for scoping entries
license:
key: ""
machine_code: ""
storage:
backend: "auto"
service: "com.manetu.agentvisor"
Container Deployments

OS-native keyring backends are not available inside OCI containers. Always set AGENTVISOR_LICENSE_KEY as an environment variable in container deployments.

The refresh interval and grace period are baked into the binary at build time and cannot be overridden at runtime.

See Licensing for activation, container deployment patterns, and troubleshooting.


Config File Locations

If AGENTVISOR_CONFIG is set, the host runtime uses that exact file path and skips the default search. Otherwise, it searches for agentvisor.yaml in:

  1. ./agentvisor.yaml (current directory)
  2. $HOME/.config/agentvisor/agentvisor.yaml
  3. /etc/agentvisor/agentvisor.yaml

Multi-Config Files

AgentVisor supports layered configuration from multiple sources merged in order. This makes it easy to share a base config across environments and override only what differs.

Three mechanisms

MechanismHow to useError if missing?
Base configDefault search paths or AGENTVISOR_CONFIGNo (silently skipped)
conf.d/ fragmentsPlace .yaml/.yml files in conf.d/ beside the base configNo (directory is optional)
Overlay files--config /path/to/overlay.yaml (repeatable) or AGENTVISOR_CONFIG_FILES=a.yaml,b.yamlYes (hard error)

Merge semantics

  • Maps are deep-merged: keys in later configs are added or overridden, other keys are preserved
  • Scalars and arrays are replaced entirely by the later value

conf.d/ fragments

AgentVisor automatically scans a conf.d/ directory adjacent to whichever base config file was found. Files are sorted alphabetically and merged in order after the base config:

./agentvisor.yaml ← base config
./conf.d/
10-temporal.yaml ← merged first
20-authz.yaml ← merged second
50-proxy-credentials.yaml ← merged third

Each fragment only needs to contain the keys it overrides:

# conf.d/10-temporal.yaml
temporal:
target: my-namespace.account-id.tmprl.cloud:7233
namespace: my-namespace.account-id
auth:
type: api_key

--config overlays

--config flags and AGENTVISOR_CONFIG_FILES are two spellings of the same mechanism. The base config search happens independently — overlays layer on top.

agentvisor serve . --config /etc/agentvisor/temporal-cloud.yaml

AGENTVISOR_CONFIG_FILES is the environment-variable equivalent (comma-separated). When both are provided, AGENTVISOR_CONFIG_FILES entries come first, then --config flags — so --config takes precedence.

note

Overlay files must exist — a missing overlay is a hard error. Use conf.d/ or environment variables for optional overrides.

Path resolution

Paths in AGENTVISOR_CONFIG_FILES and --config are resolved relative to the current working directory at startup. Use absolute paths in production and Docker deployments.

Common usage patterns

Docker / Kubernetes:

AGENTVISOR_CONFIG=/etc/agentvisor/base.yaml
AGENTVISOR_CONFIG_FILES=/etc/agentvisor/overlays/temporal-cloud.yaml,/etc/agentvisor/overlays/authz-prod.yaml

Local development:

# ~/.config/agentvisor/agentvisor.yaml sets temporal target and auth
agentvisor serve . --config ./dev-credentials.yaml

Full precedence example

Sourcetemporal.target value
Built-in defaultlocalhost:7233
Base configbase.tmprl.cloud:7233
conf.d/ fragmentconfd.tmprl.cloud:7233
AGENTVISOR_CONFIG_FILES overlayenvfiles.tmprl.cloud:7233
--config overlayflag.tmprl.cloud:7233
AGENTVISOR_TEMPORAL_TARGET env varenvvar.tmprl.cloud:7233

The effective value is envvar.tmprl.cloud:7233 — environment variables always win.


Duration Values

Duration values: 30s, 5m, 1h, 1m30s, 100ms.


Proxy Credentials

The HTTP proxy supports symbolic token substitution for secure credential management. Agents use auto-generated placeholder tokens (e.g., mav-tok-a1b2c3d4e5f6a7b8c9d0e1f2a3b4) which the proxy replaces with real credentials before making upstream requests. Real credentials never enter the guest sandbox.

How It Works

  1. Host configuration: Define credential rules with resolvers
  2. Token generation: Unique tokens are auto-generated at startup
  3. Guest environment: Tokens are injected as environment variables
  4. Agent requests: Agent uses the token in HTTP headers (from env var)
  5. TLS termination: Guest proxy terminates TLS to inspect headers
  6. Token substitution: Host replaces tokens with real credentials
  7. Upstream request: Host makes HTTPS request with real API key

Configuration

Proxy credentials are configured in agentvisor.yaml under proxy.credentials (YAML only — not expressible as flat env vars):

proxy:
credentials:
- name: anthropic-key
guest_env_var: ANTHROPIC_API_KEY # Token auto-injected here
header: "Authorization" # Optional: restrict to specific header
destinations: # Required: restrict to these hostnames
- "api\\.anthropic\\.com" # Regex, auto-anchored for full-match
resolver:
type: bearer_token
source: env
env_var: ANTHROPIC_API_KEY

- name: openai-key
guest_env_var: OPENAI_API_KEY
destinations:
- "api\\.openai\\.com"
resolver:
type: api_key
source: env
env_var: OPENAI_API_KEY
header_name: "Authorization"

- name: internal-api
guest_env_var: INTERNAL_API_TOKEN
destinations:
- "internal\\.example\\.com"
resolver:
type: principal_passthrough

Credential Rule Fields

FieldRequiredDescription
nameYesIdentifier for logging and debugging
patternNoToken pattern (auto-generated: mav-tok-...)
token_formatNoFormat for auto-generated symbolic tokens. {random} expands to 32 random hex characters. Default: mav-tok-{random}
guest_env_varNoEnv var injected into guest with the token
headerNoRestrict matching to a specific header (e.g., Authorization)
destinationsConditionalRegex patterns matched against request hostname (auto-anchored ^(?:...)$), case-insensitive. Required when resolver.type is set.
allow_insecureNoAllow substitution over plaintext http://. Default false — requests must use https:// or the real credential is not substituted.
resolverNoCredential resolver configuration (bearer_token, api_key, principal_passthrough, token_exchange, response_intercept).

Destination Filtering

Destination filtering prevents credential exfiltration — a compromised agent sending a placeholder token to an unauthorized host receives the worthless placeholder, not the real credential.

Patterns are auto-anchored (^(?:...)$) and matched case-insensitively — anthropic\.com won't match evil-anthropic.com.attacker.com, but does match Anthropic.com.

Matching is on the full origin, not just the hostname: the request must use https:// (unless the rule sets allow_insecure: true) and the standard port for that scheme (443 for https, 80 for http) — a non-standard port under a matching hostname never matches, and a plaintext http:// request never receives credentials configured for the https:// endpoint.

Upgrade note — behavior change from hostname-only matching

Earlier releases matched credential rules on hostname alone. A rule destined for api\.example\.com used to substitute credentials for https://api.example.com:8443/; it no longer does — only the scheme-default port (443 for https, 80 for http) matches. If your upstream listens on a non-standard port, the symbolic token now reaches it as-is, without substitution, and requests fail authentication at the upstream. There is currently no configuration knob to match a non-standard port; front the upstream on the standard port (e.g. via a reverse proxy) or expose it on 443/80 directly.

Resolver Types

TypeDescriptionPrincipal-Bound
bearer_tokenStatic bearer token from environment variableNo
api_keyAPI key injected into custom headerNo
principal_passthroughForward caller's JWT to upstreamYes
token_exchangeRFC 8693 token exchange for scoped tokensYes
response_interceptIntercept real tokens in HTTP response bodies and replace with symbolic tokensNo

Response Interception

Response interception extends credential brokering to HTTP response bodies. When an OAuth token endpoint returns real tokens in a JSON response, AgentVisor replaces them with symbolic tokens before they reach the guest sandbox. The real-to-symbolic mapping is cached host-side for automatic substitution on subsequent requests.

This is useful for OAuth flows (device code, authorization code) where real tokens arrive in response bodies rather than being injected from the host environment.

Use resolver.type: response_intercept on a credential rule. The rule's destinations restricts which hosts are eligible for interception.

credentials:
- name: github-oauth
destinations:
- "github\\.com"
resolver:
type: response_intercept
url_patterns:
- "https://github.com/login/oauth/access_token"
# methods: ["POST"] # Default: POST only
token_fields:
- field: access_token
token_format: "gho_mav{random}"
- field: refresh_token
token_format: "ghr_mav{random}"

Response Intercept Resolver Fields

FieldRequiredDescription
typeYesMust be response_intercept
url_patternsYesGlob patterns matched against the request URL path (query string is stripped before matching). * matches a single path segment (no slashes), ** matches any number of segments. Example: https://platform.claude.com/*/oauth/token
methodsNoHTTP methods to intercept. Default: ["POST"]
token_fieldsYesList of JSON fields to intercept in the response body
token_fields[].fieldYesTop-level JSON field name (e.g., access_token, refresh_token)
token_fields[].token_formatNoSymbolic token format. Use {random} for 32 random hex characters. Should mimic the real token prefix to pass client-side validation (e.g., sk-ant-oat01-mav-{random} for Anthropic). Default: mav-tok-{random}

The intercepted tokens are automatically substituted in both outbound request headers and request bodies. To also broker outbound credentials for the same OAuth flow, add a separate rule with a bearer_token or token_exchange resolver targeting the API's hostname.

Security Notes

  • Real credentials never enter the guest sandbox — they stay on the host
  • TLS termination uses an ephemeral CA generated at guest startup
  • Static credentials are resolved once at startup; principal-bound credentials are resolved per-request
  • Destination filtering ensures credentials are only substituted for configured hostnames

Credentials

Global policy settings for credential resolution behavior.

Env varDescription
AGENTVISOR_CREDENTIALS_ON_MISSING_ENV_VARStartup behavior when a proxy credential env var is missing: fail aborts startup; warn logs a warning and skips the rule
credentials:
on_missing_env_var: "fail"
SDLC-uniform configs

Set on_missing_env_var: warn when using a single agentvisor.yaml across dev / staging / prod stages where some credential env vars are intentionally absent in non-production environments. Startup succeeds and a structured warning names the missing env var and rule. Rules with a successfully resolved credential are unaffected.


Environment Variable Index

Finding any env var

All AGENTVISOR_* environment variables appear in their concept section alongside the YAML key, default value, and description. Use your browser's Find (⌘F / Ctrl+F) to search this page by variable name.