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)Control-plane endpoints
Section titled “Control-plane endpoints”| 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. |
Identity
Section titled “Identity”| Variable | Default | Notes |
|---|---|---|
RUNNER_INSTANCE_ID |
random UUID | Identifies the instance in logs and in Fleet. |
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 | Development shortcut. Inline PEM, not a path. |
RUNNER_KEY_PEM |
none | Its pair. Together they skip enrollment. |
RUNNER_CA_PEM |
none | CA chain, optional in the shortcut. |
RUNNER_CERT_RENEWAL |
on |
off disables rotation, and gives the runner a one-hour shelf life. |
Secret store
Section titled “Secret store”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_ADDRvault auth requires RUNNER_VAULT_TOKEN (token) or RUNNER_VAULT_ROLE_ID+RUNNER_VAULT_SECRET_ID (approle)Connectors
Section titled “Connectors”| 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. |
Learned state
Section titled “Learned state”| 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. |
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 is watermark-safe: it marks as synced only the snapshot that was actually pushed, so a re-flush after reconnecting doesn’t double-count.
Behavior and timing
Section titled “Behavior and timing”| 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 |
Tunnel heartbeat interval. |
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.
Outside the runner’s schema
Section titled “Outside the runner’s schema”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.