Environment Variables and .kl.toml

This page covers the CLI-facing configuration layer for kl.

It focuses on variables that affect command behavior, state discovery, auth, planning, refresh, and scratch workspace handling.

The important precedence rules

State selection precedence

In the CLI, state selection commonly follows this order:

  1. explicit flag such as --state-url
  2. KL_STATE_URL
  3. backend discovery from the current Terraform working directory

Auth precedence

For admin/API-style commands:

  1. explicit --token
  2. KL_TOKEN
  3. backend auth / TF_HTTP_*
  4. KL_USERNAME / KL_PASSWORD when set

Provider path precedence

For kl refresh:

  1. --provider-search-path
  2. KL_PROVIDER_PATH
  3. built-in defaults including Terraform plugin cache paths

Core CLI environment variables

KL_STATE_URL

Use a full state URL directly.

Useful when:

  • you do not want backend auto-discovery
  • you are operating outside the Terraform directory
  • you are targeting one exact workspace/environment/state path

KL_API_URL

Override the API base URL directly.

Useful when:

  • you want to point the CLI at a specific KiloLock API endpoint
  • backend discovery is not available locally

KL_TOKEN

Bearer token for cloud/admin API auth.

Useful for:

  • automation
  • admin/API workflows
  • state/resource/history queries against authenticated deployments

KL_USERNAME and KL_PASSWORD

Explicit basic-auth credentials for CLI HTTP calls.

Useful when:

  • your backend auth should not come from Terraform backend config
  • you want CLI-only overrides

TF_HTTP_USERNAME and TF_HTTP_PASSWORD

Terraform HTTP backend credentials also influence CLI auth fallback.

This matters because many kl workflows intentionally reuse the same backend identity the Terraform working directory already uses.

KL_PROTOCOL

Selects CLI protocol behavior.

Common values:

  • terraform-http
  • state-engine

Use state-engine when you want native exact-address state operations and slice-aware behavior where supported.

KL_IAC_BIN

Preferred IaC CLI binary.

Useful when:

  • the repo uses tofu instead of terraform
  • you manage multiple IaC binary versions

KL_IAC_VERSION

Desired IaC CLI version hint used with the binary resolution flow.

KL_DATA_DIR

Overrides scratch/temp workspace location for kl plan and kl apply.

Useful when:

  • CI runners need a controlled writable path
  • you want reproducible temporary workspace placement

KL_PROVIDER_PATH

Colon-separated provider search paths for kl refresh.

KL_TARGET_MAX_WRITES

Safety guard for targeted plan/apply fanout.

Useful in CI when --target should fail if the actual write set grows beyond an agreed limit.

KL_TARGET_MAX_RESERVATIONS

Safety guard for reservation fanout during targeted plan/apply.

Terraform-adjacent inputs

TF_VAR_*

Terraform input variables still matter during kl plan and implicit kl apply planning.

By default, kl plan snapshots the effective variable set into the plan spec unless you use --no-pin-vars.

TF_DATA_DIR

Influences Terraform’s own working data path and is respected by the KiloLock planning/apply flow.

TF_PLUGIN_CACHE_DIR

Used as one of the provider search defaults for refresh workflows.

.kl.toml

KiloLock walks upward from the current directory looking for .kl.toml.

Supported file settings are intentionally small:

[database]
url = "postgres://..."

[backend]
address = "http://localhost:8080/v1/states/example"
protocol = "state-engine"

Top-level shortcuts are also accepted:

database_url = "postgres://..."
backend_address = "http://localhost:8080/v1/states/example"
protocol = "state-engine"

When to prefer env vars vs .kl.toml

Prefer env vars when:

  • the value is secret
  • CI injects it
  • you want one-off overrides

Prefer .kl.toml when:

  • the backend address is stable for the repo
  • the protocol choice is part of the project’s normal workflow
  • you want fewer repeated flags in local development

Practical examples

Point the CLI at one exact state

export KL_STATE_URL="https://api.example/v1/states/ws_123/env_456/big-state"
export KL_TOKEN="kl_..."
kl history

Run state-engine exact-address operations

export KL_PROTOCOL=state-engine
kl state rm big-state --address time_sleep.slow_b

Put scratch work under a known directory

export KL_DATA_DIR="$PWD/.kl-data"
kl plan -f slow_a.tf