Skip to content

Gateway Configuration and Environment Interpolation

The Gateway Controller and Policy Engine read their configuration from a TOML file (config.toml) layered over built-in defaults. This page explains how configuration is delivered, how environment values are injected through interpolation tokens, and how the one-time setup script provisions the keys and certificates the gateway requires.

How configuration is loaded

Configuration is read from a TOML file mounted at /etc/gateway-controller/config.toml (controller) and /etc/policy-engine/config.toml (policy engine), layered over the built-in defaults.

Environment variables do not override config keys directly

There is no APIP_GW_* prefix that auto-maps environment variables onto config keys. An environment value reaches a setting only through an explicit interpolation token written into the config file, resolved when the file is loaded. A field with no token always takes its literal TOML value (or the built-in default).

This replaces the previous behavior, where an APIP_GW_-prefixed environment variable was mapped onto the matching config key and silently overrode the file. A bare APIP_GW_* variable with no matching token in config.toml is now ignored.

Interpolation tokens

Two functions are available inside config.toml:

Token Behavior
{{ env "NAME" "default" }} Substitutes the value of environment variable NAME. If the variable is unset or set-but-empty, the default is used.
{{ file "PATH" }} Reads a secret value from a mounted file at PATH — for injecting secrets from a mounted volume rather than an environment variable.

An example from the shipped config.toml:

[controller.controlplane]
host  = '{{ env "APIP_GW_CONTROLLER_CONTROLPLANE_HOST" "" }}'
token = '{{ env "APIP_GW_CONTROLLER_CONTROLPLANE_TOKEN" "" }}'

[controller.storage]
type = '{{ env "APIP_GW_CONTROLLER_STORAGE_TYPE" "sqlite" }}'

Every token in the shipped config carries a default, so an unset variable keeps the built-in value.

APIP_GW_ is a naming convention, not a prefix override

The shipped config.toml names its token arguments APIP_GW_<CONFIG_PATH> (for example, APIP_GW_CONTROLLER_STORAGE_TYPE for controller.storage.type). This is purely a convention that makes the token argument readable — it is the literal string passed to the interpolation function, not a prefix that the loader interprets. Renaming the environment variable also requires editing the matching token in the config file.

Common tokens

The shipped config.toml already carries interpolation tokens for the settings the sample deployments inject. The most common are:

Environment variable (token argument) Config key Description
APIP_GW_CONTROLLER_STORAGE_TYPE controller.storage.type sqlite, postgres, sqlserver, or memory
APIP_GW_CONTROLLER_STORAGE_SQLITE_PATH controller.storage.sqlite.path Path to the SQLite database file
APIP_GW_CONTROLLER_STORAGE_POSTGRES_PASSWORD controller.storage.postgres.password PostgreSQL password
APIP_GW_CONTROLLER_STORAGE_DATABASE_DSN controller.storage.database.dsn SQL Server DSN (when storage type is sqlserver)
APIP_GW_CONTROLLER_CONTROLPLANE_HOST controller.controlplane.host Control plane endpoint (host:port)
APIP_GW_CONTROLLER_CONTROLPLANE_TOKEN controller.controlplane.token Control plane registration token
APIP_GW_CONTROLLER_LOGGING_LEVEL controller.logging.level debug, info, warn, error

For the complete list of tokens and every configurable option, refer to the config template.

Distinct from artifact templating

The interpolation tokens described here apply to the gateway's own config.toml. API artifacts (RestApi, LLMProvider, and other resource files) support a separate, richer set of template functions (env, required, redact, default) applied to the artifact body. See Artifact Templating for that mechanism.

Delivering environment values

For Docker Compose deployments, the sample composes deliver these values to the container from an api-platform.env file via the Compose env_file: directive:

services:
  gateway-controller:
    env_file:
      - ./api-platform.env

api-platform.env is generated by the setup script. Add or edit variables there — for example, to connect to a control plane:

# api-platform.env
APIP_GW_CONTROLLER_CONTROLPLANE_HOST=your-control-plane-host:9443
APIP_GW_CONTROLLER_CONTROLPLANE_TOKEN=<registration-token>

For Kubernetes/Helm deployments, the chart renders config.toml into a ConfigMap and injects the runtime secrets (control plane token, database password) as interpolation tokens backed by Kubernetes Secrets — see Security Hardening and Database Configuration.

No development / demo mode

The gateway has no development or demo mode and never auto-generates keys or certificates. It fails closed with a descriptive error at startup if a required key or certificate is missing. Everything the gateway requires must be provisioned before it starts:

  • AES-256 at-rest encryption key — used to encrypt sensitive data at rest. Required; the controller will not start without it.
  • Router HTTPS listener certificate — the TLS certificate/key for the router's HTTPS listener.
  • api-platform.env — runtime settings read directly by the gateway-runtime entrypoint (for example, GATEWAY_CONTROLLER_HOST, LOG_LEVEL).

The setup script provisions all three.

One-time setup with setup.sh

The distribution ships scripts/setup.sh, which provisions everything a fresh gateway needs. Run it once before the first docker compose up:

./scripts/setup.sh
docker compose up -d

setup.sh provisions, idempotently:

Artifact Location Purpose
Router listener certificate listener-certs/default-listener.{crt,key} Self-signed cert for the router HTTPS listener (SANs include localhost, *.localhost, host.docker.internal, 127.0.0.1).
AES-256 encryption key aesgcm-keys/default-aesgcm256-v1.bin 32-byte at-rest encryption key, bind-mounted into the controller.
api-platform.env api-platform.env Runtime defaults loaded into the containers via env_file.

The script is idempotent — existing files are kept, not overwritten. Flags:

Flag Effect
--force Regenerate the certificate and encryption key (rotating them) and rewrite api-platform.env.
--certs-only Generate only the listener TLS certificate; skip the encryption key and api-platform.env.

Rotating the encryption key

Running setup.sh --force regenerates the AES-256 encryption key. Data encrypted with the previous key becomes unreadable. Only rotate the key deliberately.

Control plane connection is not configured by the script

Connecting to a control plane is optional and is not configured by setup.sh. To connect, add APIP_GW_CONTROLLER_CONTROLPLANE_HOST and APIP_GW_CONTROLLER_CONTROLPLANE_TOKEN to api-platform.env (both default to empty, which runs the gateway in standalone mode).


← Artifact Templating  |  Storage & Backends →