Skip to content

How configuration works ​

Hephaisto uses standard .NET configuration. Every key has three interchangeable spellings, and knowing the mapping between them is most of what you need.

FormExample
Config keyLlm:Model
Environment variableLlm__Model
Helm valuellm.model, where the chart exposes one

A colon becomes a double underscore. Array elements are indexed: Policy__AllowedNamespaces__0, Policy__AllowedNamespaces__1. Nested objects keep nesting: Notifications__Routes__0__Channel.

Where a value can come from ​

In increasing order of precedence:

  1. appsettings.json baked into the image
  2. appsettings.{Environment}.json
  3. Environment variables — which is how the chart sets everything
  4. The kill-switch arms, for mode only, where the most restrictive arm wins rather than the last one read

The escape hatch ​

The chart deliberately does not expose every option as a Helm value — exposing all ~110 would mean a values file nobody reads and a schema that lags the code. Anything not exposed is set through extraEnv:

yaml
extraEnv:
  - name: Llm__Investigation__MaxSteps
    value: "16"
  - name: Policy__WorkloadCooldown
    value: "00:30:00"

extraEnv cannot shadow the four reserved variables, cannot half-override the OTEL_* block, and cannot widen the namespace allowlist behind RBAC's back. Those are enforced as chart render failures — see Reserved env and safety rails.

Types that are not what they look like ​

  • Durations are .NET TimeSpan strings, not Prometheus durations. "02:00:00" is two hours; "2h" is a parse failure. "7.00:00:00" is seven days.
  • Enums are their C# member names, case-insensitively: Observe, RestartPod, Enforce.
  • Llm:Pricing is a dictionary keyed by model id. An unpriced model is charged at zero, which switches the cost budget off rather than approximating it.

Restarts ​

Most options are read through IOptionsMonitor and take effect on the next use. Two groups do not, because they are captured at construction:

  • Llm:Provider, Llm:Model, Llm:Endpoint — the chat client factory captures these. Changing them needs a pod restart, not just a ConfigMap edit.
  • Anything the Kubernetes watcher stack reads at startup.

Where to look next ​

AGPL-3.0-only · Source