YAML Configuration Interpolation#
Tinyauth's YAML loader intentionally does not resolve ${...} environment variable references inside YAML configuration files. If you write secret: ${MY_SECRET} in a config file, the literal string "${MY_SECRET}" will be stored in the config field β no substitution occurs.
This is a deliberate design boundary: YAML files and environment variables are fully separate configuration sources that never cross-interpolate.
How the Loader Works#
The YAML (and TOML/JSON) loading path in paerser is a pure parse-and-map pipeline:
- File read β raw map β
decodeFileToNodereads the file withyaml.Unmarshaldirectly into amap[string]interface{}. No string pre-processing happens before or after this step. - Raw map β node tree β
decodeRawToNodewalks the map and copies string values verbatim intoparser.Nodestructs viagetSimpleValue, which performs only type coercion (int, bool, float β string) β not template expansion. - Node tree β typed struct β
parser.Fillmaps node values onto theConfigstruct fields.
There is no step in this pipeline that scans values for ${...} patterns or calls os.Getenv .
In Tinyauth itself, FileLoader.Load resolves the config file path from either the --traefik.configfile flag or TINYAUTH_CONFIGFILE env var, then hands off to file.Decode() β again with no interpolation of the file's contents.
Why This Matters#
Tinyauth runs three loaders in sequence at startup :
FileLoader β FlagLoader β EnvLoader
EnvLoader runs last and therefore has the highest priority, overriding values from YAML. This layered override model is the intended way to inject runtime secrets or environment-specific values: set them as environment variables (e.g., TINYAUTH_SERVER_SECRET), not as ${...} references inside YAML.
Practical consequence: Do not use shell-style variable interpolation in Tinyauth YAML files. Secrets and per-environment overrides belong in environment variables, which are loaded independently by EnvLoader via paerser/env.
Key Source Files#
| File | Role |
|---|---|
paerser/file/file.go | Top-level Decode / DecodeContent entry points |
paerser/file/file_node.go | File-to-node parsing (calls yaml.Unmarshal verbatim) |
paerser/file/raw_node.go | Node tree construction; getSimpleValue shows no env expansion |
internal/utils/loaders/loader_file.go | Tinyauth's FileLoader; wires file path resolution β file.Decode |
paerser/cli/loader_file.go | paerser's generic FileLoader (same pipeline) |
For the full configuration source model (priority order, env var naming conventions, available options), see the Configuration Sources knowledge base article.