Config Reference

Every field in wardline.yaml, grouped by section. Config maps 1:1 to this shape (internal/platform/config/config.go).

Top level

FieldTypePurpose
listenstringAddress Wardline binds to, e.g. 0.0.0.0:8080.
upstreamstringUpstream MCP server URL.
policy_filestringPath to the policy file.
policy_backendstringyaml (default), opa, or cedar.
grpc_listenstringhost:port for the gRPC listener — required when features.grpc_transport is true. See gRPC Transport.
grpc_upstreamstringUpstream gRPC target (host:port, plaintext) — required when features.grpc_transport is true.
grpc_upstream_tlsboolDial the gRPC upstream over TLS instead of plaintext. Default false. See gRPC Transport.
shutdown_delay_secondsintHow long a replica keeps serving requests normally after receiving SIGTERM/SIGINT before it begins its own drain sequence. Zero (the default) preserves current shutdown behavior exactly: draining begins the instant the signal arrives. An in-process substitute for a Kubernetes preStop hook — see High Availability.
featuresmap[string]boolFeature flags — see each feature’s own page.

audit

FieldTypePurpose
outputstringstdout or a file path.
postgres_dsnstringOnly used when features.postgres_storage is true. Shared by every Postgres-backed feature (audit, credential revocation/refresh, budget, job/cost budget, SCIM, anomaly baselines/blocks/tenant aggregates) — not audit-specific despite living here.
postgres_max_open_connsintSize of the ONE connection pool shared by every Postgres-backed feature (see postgres_dsn above). Default 25 when unset/zero. See Budget Enforcement’s “Known limitations” for the fail-open behavior under sustained load beyond this.
retention_daysintAge past which audit entries are purged by the retention job. Only meaningful when features.log_retention is true; see retention.

budget

FieldTypePurpose
requests_per_windowintSee Budget Enforcement.
window_secondsintWindow length in seconds.
tenants.<name>.requests_per_window / .window_secondsint×2Per-tenant override of the two global fields above, keyed by tenant name. A tenant absent from this map uses the global default unchanged. Only one level deep — a nested tenants.acme.tenants.* is silently ignored, not an error.
tools.<name>.requests_per_window / .window_secondsint×2Per-tool override, same shape and same one-level-deep caveat as tenants above.

tracing

FieldTypePurpose
otlp_endpointstringhost:port, no scheme.
service_namestringDefaults to "wardline".

credential

FieldTypePurpose
identities_filestringPath to the identities file.
signing_key_filestringOptional PEM RSA key path — see HA Deployment. Mutually exclusive with kms.key_id.
previous_signing_key_fileslist of stringPEM RSA private keys whose public halves are accepted for verification only — the key-rotation window. Empty (default) means no rotation in progress.
access_token_ttl_secondsintHow long an issued access token is valid for. 0 (default) uses 900s (15m). Negative is a validation error.
refresh_token_ttl_secondsintHow long an issued refresh token remains redeemable. 0 (default) uses 86400s (24h). Negative is a validation error.
kms.key_id / .regionstring×2AWS KMS-backed signing key instead of a local PEM file — the private key never leaves KMS. region optional (defaults to the AWS SDK’s own region resolution). Mutually exclusive with signing_key_file. See HA Deployment.
bootstrap_sourcestringpresharedsecret (default), oidc, or mtls. See SSO and mTLS/SPIFFE Bootstrap.
oidc.issuer / .jwks_uri / .audience / .identity_claim / .tenant_claimstring×5Single-IdP OIDC bootstrap. jwks_uri optional (resolved via discovery when unset). See SSO.
oidc_providerslistMulti-IdP OIDC bootstrap — a list of the same 5 fields oidc above has, one entry per issuer, routed by the token’s own iss claim. Mutually exclusive with oidc. See SSO’s “More than one IdP” section.
spiffe_workload.socket_pathstringUnix socket of the local SPIFFE Workload API (a SPIRE agent). Optional — defaults to the SPIFFE_ENDPOINT_SOCKET env var when unset. Requires features.spiffe_workload_identity. See mTLS/SPIFFE Bootstrap.
spiffe_workload.upstream_peer_idstringThe exact SPIFFE ID Wardline requires the gRPC upstream to present. Optional but recommended — without it, any SPIFFE-authenticated peer is accepted.
mtls.headerstringThe header name Wardline trusts to carry an already-verified SPIFFE ID from a terminating mTLS proxy/mesh. No default — required when bootstrap_source: mtls. See mTLS/SPIFFE Bootstrap.

dashboard

FieldTypePurpose
allow_insecure_session_cookieboolDefault false (Secure). Set true only for a genuinely plaintext-HTTP deployment (local dev, loopback-only) — a Secure cookie is never sent over plain HTTP. See Web Dashboard’s login flow.

rbac

FieldTypePurpose
config_filestringPath to the roles/bindings file.

anomaly

FieldTypePurpose
outputstringAnomaly log output.
buffer_capacityintRing buffer size.
gc_interval_secondsintState garbage-collection interval.
window_secondsintDetection window.
rate_spike.enabled / .rate_multiplier / .min_callsbool/float/intRate-spike heuristic.
novel_tool.enabledboolNovel-tool heuristic.
deny_rate_spike.enabled / .threshold / .min_callsbool/float/intDeny-rate-spike heuristic.
ml_score.enabled / .score_threshold / .min_callsbool/float/intCombined z-score heuristic (min_calls must be ≥ 2). See Anomaly Detection.
auto_block.enabled / .score_threshold / .block_duration_secondsbool/float/intRejects a flagged identity’s calls for a bounded TTL. Requires ml_score.enabled.
drift_detection.enabled / .k / .h / .min_callsbool/float/float/intCUSUM control chart over call_rate and tool_diversity, catching sustained drift a per-window z-score test misses. k/h are in units of the scored feature’s own baseline standard deviation (Montgomery’s SPC defaults: k: 0.5, h: 4.05.0). Requires ml_score.enabled. See Anomaly Detection’s “Drift detection” section.
drift_detection.h_jitter_fraction / .jitter_secret_filefloat/stringOptional moving-target defense: perturbs each identity’s own effective h by up to this fraction, keyed by HMAC-SHA256 of a per-deployment secret (jitter_secret_file, required whenever the fraction is > 0). Raises the cost of an attack calibrated to the public default h — does not defeat an adaptive attacker who can probe the live system repeatedly, and in isolation remains vulnerable to an attacker minting disposable identities to re-roll for a favorable draw; identity_churn (below) is the actual defense against that specific rotation exploit. See “Adversarial scenarios” in the same doc.
tenant_anomaly.enabled / .rate_multiplier / .min_callsbool/float/intDetects a coordinated call-volume spike aggregated across every identity in a tenant — closes the gap no per-identity heuristic can (see “Adversarial scenarios”). Logs only, never auto-blocks: there is no single identity to block for a tenant-level signal. HA-safe when features.postgres_storage is also on: window totals merge atomically across replicas; falls back to per-replica, in-memory-only aggregation otherwise.
identity_churn.enabled / .rate_multiplier / .min_new_identitiesbool/float/intDetects a burst of never-before-seen identities aggregated across a tenant, per window — the fingerprint of an attacker discarding identities caught by per-identity heuristics (including h_jitter_fraction’s own per-identity jitter) and retrying fresh ones. Logs only, same “no single identity to block” reasoning as tenant_anomaly. HA-safe when features.postgres_storage is also on: window totals merge atomically across replicas; falls back to per-replica, in-memory-only aggregation otherwise. See “Adversarial scenarios” in the same doc.
identity_churn.cusum_enabled / .k / .hbool/float/floatOptional CUSUM (cumulative-sum) extension over identity_churn’s own window totals, closing the slow-trickle gap rate_multiplier alone can’t: one new disposable identity every many windows, individually always below rate_multiplier, still accumulates toward and crosses h. Same cusumStep mechanics drift_detection.k/.h already use for call_rate/tool_diversity — a separate, independent k/h pair, not a reuse of drift_detection’s (no single identity to jitter here).
retention_daysintAge past which anomaly-log entries are purged. Only meaningful when features.log_retention is true.

scim

FieldTypePurpose
bearer_token_envstringEnv var holding the SCIM bearer token (never inline) — required when features.scim is true. See SCIM.
persist_postgresboolPersist provisioned group→member bindings in Postgres (requires features.postgres_storage). Default in-memory.

federation

Only meaningful when features.federation is true (which itself requires features.anomaly_detection). See Federation.

FieldTypePurpose
instance_idstringUnique instance identifier. Defaults to os.Hostname() — set explicitly when co-locating instances.
peers_filestringPath to the peers file (id, endpoint, public_key_file per peer) — required.
signing_key_filestringPEM RSA private key this instance signs its summaries with — required.
shared_secret_filestringShared secret (byte-identical across peers) for pseudonymizing fingerprints — required.
publish_interval_secondsintHow often signed anomaly summaries are published to peers.
min_instances_for_correlationintDistinct instances that must see a fingerprint before an alert (must be ≥ 2).
correlation_window_secondsintWindow over which fingerprints from peers are correlated.
gc_interval_secondsintStale correlation-state eviction interval.

compliance

Only meaningful when features.compliance_scheduled_export is true. See Compliance Evidence Export.

FieldTypePurpose
scheduled_export_interval_secondsintHow often a scheduled evidence bundle is exported.
scheduled_export_output_dirstringDirectory each tick’s bundle is written to — required when the flag is on.
signing_key_filestringOptional PEM RSA private key to sign each scheduled bundle. "" (default) produces unsigned bundles.

retention

Only meaningful when features.log_retention is true. A single shared cadence for both the audit and anomaly retention checks (whichever of audit.retention_days / anomaly.retention_days is non-zero).

FieldTypePurpose
check_interval_secondsintHow often the retention purge job runs.

taint

Only meaningful when features.taint_tracking is true. See Taint Tracking.

FieldTypePurpose
untrusted_sourceslist of stringTool names whose invocation taints the calling (tenant, identity, session).
declassify_sourceslist of stringTool names that clear an existing taint.
ttl_secondsintHow long a taint persists before expiring on its own.
session_window_secondsintFallback session-window width used when a call carries no session header.
session_headerstringHeader name carrying an explicit agent session ID.

approval

Only meaningful when features.approval_workflow is true. See Approval Workflow.

FieldTypePurpose
grant_ttl_secondsintHow long an approved grant remains valid before requiring re-approval.

job_budget

Only meaningful when features.job_budget is true. See Job Budget.

FieldTypePurpose
requests_per_jobintPer-job request ceiling.
session_window_secondsintFallback session-window width used when a call carries no X-Wardline-Session header.

job_cost_budget

Only meaningful when features.job_cost_budget is true. See Cost Budget.

FieldTypePurpose
ceilingintPer-job cost/token ceiling.
tool_costsmap[string]intPer-tool cost override, keyed by tool name.
default_costintCost charged for a tool with no entry in tool_costs.
session_window_secondsintFallback session-window width, same role as job_budget.session_window_seconds.