Read config value from file (similar to `env.*`)
Using environment variables has several security drawbacks and special care has to be taken to not expose them. Such pitfalls are subprocesses inheriting the environment (e.g. by means of plugins), being inspectable by external IPC (e.g. systemctl show caddy.service shows the env even if the unit file itself is unreadable), or by system logging facilities which annotate log lines with the execution context (e.g. journald).
Due to these and other pitfalls it is preferable to read secrets from files. This is the approach taken by Docker Secrets, K8s secrets, and systemd credentials. It would be great if caddy added some way to expand config files using secrets from one of these means. This could be done by e.g. some abstract way to read from any file such as ... acme_dns cloudflare {fs./run/secrets/api_token} or {fs.$CREDENTIALS_DIRECTORY/token}, or using a more specialized facility which detects the desired secretstore (e.g. if running under Docker, use /run/secrets, and use $CREDENTIALS_DIRECTORY if running under systemd) and can be accessed as foobar {secret.api_token}
This already exists, there's the {file.*} placeholder https://github.com/caddyserver/caddy/pull/5463
This already exists, there's the
{file.*}placeholder #5463
Thanks for the pointer. Is that documented somewhere besides in the code?
And I guess mixing them is not supported? I.e. {file.$CREDENTIALS_DIRECTORY/token}?
Here https://caddyserver.com/docs/conventions#placeholders
It might work to nest, but the syntax is {$ENV}, not $ENV. See https://caddyserver.com/docs/caddyfile/concepts#environment-variables. That would be because Caddyfile env placeholders are replaced at config-adapt time, not at runtime.
Okay, thank you very much. I tested it and {file.{$XDG_RUNTIME_DIR}/20250520-151741-jJ7/Caddyfile} seems to work. {env.XDG_RUNTIME_DIR} does not but I guess that was expected with the nesting.
Is the support for nesting with {$ENV} officially supported or does it just happen to luckily work out and might break in future releases? There do seem to be no tests for it under caddytest/. Would you be okay with accepting a PR to add such an test to prevent this from regressing?
It happens to work. But there's no plan to change that. It's unlikely to ever break though because the config is read character by character looking for {$ followed by the next }. We don't plan on ever allowing {$ for any other purpose (i.e. runtime placeholders) so it should always work.
Sure, tests are always welcome 👍