Skip to content

Environment variables

All runner configuration comes from the environment and is schema-validated at boot, fail-fast: if something doesn’t check out, the process dies with a readable error rather than coming up half-configured.

Invalid runner configuration:
RUNNER_TUNNEL_URL: String must contain at least 1 character(s)
Variable Default Notes
RUNNER_TUNNEL_URL none Required. e.g. wss://tunnel.rootpilot.sh:8443.
RUNNER_ENROLL_URL none Required unless a certificate is provisioned. e.g. https://app.rootpilot.sh.
RUNNER_ENROLL_PATH /api/enroll The enrollment route.
Variable Default Notes
RUNNER_INSTANCE_ID UUID drawn at every boot Identifies the instance in logs and in Fleet. Unrelated to persistence: the identity’s owner lives inside RUNNER_IDENTITY_DIR itself.
RUNNER_IDENTITY_DIR none Writable directory where the identity is persisted, so it survives container replacement. Enough on its own. One per Agent — two Agents on the same volume fight over it. See Identity and enrollment.
RUNNER_ATTESTATION_MODE bootstrap-token bootstrap-token, aws-sts, gke-oidc. eks-oidc is accepted by the schema and fails at boot.
RUNNER_BOOTSTRAP_TOKEN none Required when the mode is bootstrap-token.
AWS_REGION none Required when the mode is aws-sts. Also used by the AWS connectors.
RUNNER_GKE_TOKEN_PATH /var/run/secrets/tokens/gke-oidc/token Where to read the projected KSA token.
RUNNER_CERT_PEM none Your tenant’s certificate. Inline PEM, not a path — the entrypoint fills it from /certs.
RUNNER_KEY_PEM none Its pair. Together they skip enrollment.
RUNNER_CA_PEM none CA chain, optional.
RUNNER_CERT_RENEWAL on Turns on the renewal scheduler. Requires RUNNER_ENROLL_URL; without it, nothing renews.

Where your service credentials are read from. Detail in Secret stores.

Variable Default Notes
RUNNER_SECRET_STORE_MODE env env (development), aws, vault.
RUNNER_SECRETS_MANAGER_REGION none aws mode. Absent ⇒ SDK default resolution.
RUNNER_SECRETS_MANAGER_PREFIX '' aws mode. Prefixes the SecretId.
RUNNER_VAULT_ADDR none Required in vault mode.
RUNNER_VAULT_AUTH token token or approle.
RUNNER_VAULT_TOKEN none Required with token auth.
RUNNER_VAULT_ROLE_ID none Required with approle auth.
RUNNER_VAULT_SECRET_ID none Required with approle auth.
RUNNER_VAULT_NAMESPACE none Vault Enterprise.
RUNNER_VAULT_KV_MOUNT secret KV v2 mount.
RUNNER_VAULT_KV_FIELD value Which field of the secret to return.
RUNNER_VAULT_PREFIX '' Prefixes the logical path.

The schema validates the combinations and refuses early:

RUNNER_SECRET_STORE_MODE=vault requires RUNNER_VAULT_ADDR
vault auth requires RUNNER_VAULT_TOKEN (token) or RUNNER_VAULT_ROLE_ID+RUNNER_VAULT_SECRET_ID (approle)
Variable Default Notes
RUNNER_CONNECTORS synthetic synthetic, real, demo. See Connector modes.
RUNNER_OBSERVABILITY datadog datadog, grafana, none. Exclusive. See Observability.
RUNNER_CONNECTOR_MECHANISMS native CSV of enabled isolation mechanisms.
RUNNER_CONNECTOR_SIDECAR_TIMEOUT_MS 30000 Sidecar invoke deadline.
RUNNER_AWS_CRED_MODE static static or chain. See Cloud credentials.
RUNNER_GCP_CRED_MODE static static or chain.
RUNNER_DENY_POLICY_FILE — JSON artifact for the tool denylist.
RUNNER_DENIED_GROUPS — CSV of denied groups (network-posture, iam).
RUNNER_DENIED_CAPABILITIES — CSV of denied capabilities.
RUNNER_DENIED_CONNECTORS — CSV of denied connectors.
RUNNER_DENIED_OPS — CSV of denied operations.
Variable Default Notes
RUNNER_LEARNED_SYNC on off = strictly local: the store isn’t even instantiated and nothing leaves the runner.
RUNNER_LEARNED_STORE_PATH :memory: SQLite path. It is a cache, not a source of truth.
RUNNER_LEARNED_FLUSH_INTERVAL_MS 60000 Periodic flush. 0 disables it, leaving only the drain flush.
RUNNER_LEARNED_FLUSH_DEBOUNCE_MS 2000 Flush shortly after an extraction, debounced. 0 disables it.

The two delays measure different things. The periodic flush exists because the only flush used to be on drain, so a hard reclaim (SIGKILL, OOM, spot) lost everything since boot — it bounds the loss. The debounce bounds the latency: without it, an edge the agent just discovered could take a full interval to reach the control plane. It is a debounce rather than a per-operation flush because one wave fires several operations at once, and flushing per operation would mean N calls for the same result; the periodic flush still acts as the ceiling, so under continuous extraction it is the one that guarantees a flush. It is watermark-safe: it marks as synced only the snapshot that was actually pushed, so a re-flush after reconnecting doesn’t double-count.

Variable Default Notes
RUNNER_INVOKE_DEADLINE_MS 30000 Per-operation deadline, applied at enforcement.
RUNNER_IDEMPOTENCY_TTL_MS 300000 Idempotency cache TTL.
RUNNER_IDEMPOTENCY_MAX_ENTRIES 2000 Entry ceiling; evicts oldest. Bounds memory in a long-lived runner.
RUNNER_HEALTH_PROBE_TIMEOUT_MS 10000 Per-connector deadline for the boot credential self-check.
RUNNER_RECONNECT_MAX_MS 30000 Tunnel reconnect backoff ceiling.
RUNNER_HEARTBEAT_INTERVAL_MS 15000 Keepalive ping cadence on the tunnel. Holds the connection open through idle-timeout LBs/proxies; two intervals with no reply tear the socket down to reconnect.
RUNNER_DRAIN_TIMEOUT_MS 120000 Drain ceiling on SIGTERM. Size your orchestrator’s grace above this.
RUNNER_TLS_INSECURE_SKIP_VERIFY false Test only. See the warning below.
NODE_ENV development development, production, test.

HEALTH_PROBE_TIMEOUT_MS is 10 s rather than 5 s on purpose: several runners on one host firing probes in parallel, plus cold start, push a ~2 s call past 5 s and produce a false error.

These aren’t schema-validated, but they change behavior:

Variable Default Where it acts
ROOTPILOT_OTEL_ENABLED false Enables OpenTelemetry. See Telemetry.
ROOTPILOT_PII_REDACTION on off disables the structural redaction layer. See PII redaction.
EKS_CLUSTER none Without it, the EKS health check answers skipped: no cluster configured.
RUNNER_TENANT none From the fleet scripts, not the runner. Picks the vault folder and turns on RUNNER_CONNECTORS=real.

Per-connector credentials (DD_API_KEY, GITHUB_TOKEN, …) are also outside the runner’s schema: they’re declared in manifests and read from the secret store. The full list is in Connector credentials.