Configuration

Tuning runed for real workloads — addresses, storage limits, runners, registries.

This page is the operational counterpart to the runefile reference. Same fields, more "why."

Addresses and exposure

Default config binds to all interfaces:

server:
  grpc-addr: ":7863"
  http-addr: ":7861"

For a single-host setup with no remote API consumers, lock to localhost and let the CLI tunnel via SSH:

server:
  grpc-addr: "127.0.0.1:7863"
  http-addr: "127.0.0.1:7861"

Then:

ssh -L 7863:localhost:7863 host
rune login local --server localhost:7863 --token-file ./tok

For remote API consumers, enable TLS:

auth:
  tls:
    enabled: true
    cert-file: /etc/rune/tls/server.crt
    key-file:  /etc/rune/tls/server.key

Without TLS, every bearer token crosses the wire in plaintext.

Auth posture

auth:
  enabled: true
  allow_remote_admin: false
  • Set enabled: false only on a single-developer laptop. It disables every bearer-token check.
  • allow_remote_admin: true removes the localhost gate on admin/* RPCs. Don't enable on a public network without TLS plus an aggressive firewall.

Storage limits

storage:
  secret-limits:
    max-keys-per-secret: 64
    max-value-size: 65536    # bytes

These cap pathological secret writes — useful when handing tokens to less-trusted CI bots. Tune up only if you actually need bigger payloads (e.g., larger TLS certs).

KEK source

crypto:
  kek:
    source: file              # file | env | generated
    file-path: /var/lib/rune/kek
    env-var: RUNE_MASTER_KEY
    generate-if-missing: true

In order of operational preference:

  1. source: env with env-var: RUNE_MASTER_KEY — load from a secret manager (Vault, AWS Secrets Manager, systemd credential) at boot.
  2. source: file — KEK on disk with mode 0600. Easiest. Back it up.
  3. source: generated — only for ephemeral test setups. Dies with the process.

Always back up the KEK separately from the database. Lose the KEK, lose all secrets — there's no recovery.

Runners

runner:
  docker:
    enabled: true
    socket: /var/run/docker.sock
  process:
    enabled: true

Disable the process runner if you're running in a hardened environment where native processes shouldn't be allowed. Disable Docker if you're running on a host without it.

Registries

Two ways to manage:

# Static — in the runefile
docker:
  registries:
    - name: ghcr-private
      registry: ghcr.io
      auth:
        type: basic
        username: ${GHCR_USER}
        password: ${GHCR_PAT}

Or dynamic at runtime:

rune admin registry add --name ghcr-private \
  --registry ghcr.io --type basic \
  --username "$GHCR_USER" --password "$GHCR_PAT"

Runtime registries don't require a runed restart. Static ones do. See Pull from GHCR for the end-to-end GitHub Container Registry walkthrough.

Logging

server:
  log-level: info        # debug | info | warn | error
  log-format: json       # text | json

For production, use json and ship to your log collector. For local debugging, text is easier on the eyes.

Common tuning recipes

"I'm seeing slow rune cast."

Probably docker pull latency. Pre-pull images on the host or check registry network reachability. The server itself is rarely the bottleneck for single-node workloads.

"Secrets feel risky."

  • Move crypto.kek.source from file to env and load via systemd LoadCredential.
  • Tighten storage.secret-limits so accidental large writes are caught.
  • Restrict the secret resource in policies — only on-call gets get for * namespace.

"I want minimal blast radius for the gRPC port."

  • Bind to localhost.
  • Run a reverse proxy (Caddy, nginx) with mTLS on a public port.
  • Set auth.allow_remote_admin: false (default).

See also