Go to file
2025-07-20 12:12:14 +02:00
test initial 2025-07-20 12:12:14 +02:00
AGENTS.md initial 2025-07-20 12:12:14 +02:00
go.mod initial 2025-07-20 12:12:14 +02:00
go.sum initial 2025-07-20 12:12:14 +02:00
interpolate.go initial 2025-07-20 12:12:14 +02:00
LICENSE initial 2025-07-20 12:12:14 +02:00
main_test.go initial 2025-07-20 12:12:14 +02:00
main.go initial 2025-07-20 12:12:14 +02:00
Makefile initial 2025-07-20 12:12:14 +02:00
README.md initial 2025-07-20 12:12:14 +02:00

smartconfig

smartconfig is a go library that reads a configuration file from the filesystem and interpolates variables in it from several sources, then parses the config file as yaml.

This was inspired by Ryan Smith and one of his config file formats/parsers. It struck me as very clever and I wanted to begin using it.

concept

Configuration files often need to store secrets, and these secrets come from various sources such as environment variables, cloud provider secrets managers, or other secret management systems. Instead of having to implement all of these APIs in your application, tightly binding it to your platform (and locking you in to that vendor), this allows your config file to serve as pointers to the various sources of secrets, supporting pluggable secret management sources.

Yes, it supports shelling out to external commands to get values. This equates being able to write your config file with arbitrary code execution, which may not be the case in your environment, but is a baked-in assumption here (and one I think will be fine/correct for 99% of users).

It has only one magic property other than the interpolation: anything specified under the top level key "env" will be interpolated and added, to the environment of the process that reads the config file. This allows a config file to serve as a bridge between fancy backend secret management services and "traditional" configuration via env vars.

Usage

# config.yaml

name: ${ENV:APPLICATION_NAME}
host: ${EXEC:"hostname -s"}
port: ${ENV:PORT}

vhost:
    tls_sni_host: "${JSON:/etc/config/hosts.json:'.tls_sni_host[0]'}"

machine:
    id: "${FILE:/etc/machine-id}"
    temperature: "${FILE:/sys/class/thermal/thermal_zone0/temp}"
    num_cpus: "${EXEC:nproc}"

api:
    root_user: "admin"
    root_password: "${AWSSM:root_password}"

db:
    host: "${GCPSM:${ENV:APPLICATION_NAME}_DB_HOST}"
    user: "${GCPSM:${ENV:APPLICATION_NAME}_DB_USER}"
    password: "${GCPSM:${ENV:APPLICATION_NAME}_DB_PASSWORD}"

external:
    google_api_key: "${CONSUL:secret:google_api_key}"
    twilio_api_key: "${VAULT:secret:twilio_api_key}"

env:
    ENCRYPTION_PUBLIC_KEY: "${EXEC:secret get myapp/encryption_public_key}"
    SLACK_WEBHOOK_URL: "${FILE:/etc/config/slack_webhook_url.txt}"

Supported Providers

  • ENV - environment variables
  • EXEC - shell out to an external command
  • AWSSM - AWS Secrets Manager
  • GCPSM - Google Cloud Secret Manager
  • VAULT - HashiCorp Vault
  • CONSUL - HashiCorp Consul KV Store
  • AZURESM - Azure Key Vault
  • K8SS - Kubernetes Secrets
  • FILE - read from a file
  • JSON - read from a JSON file (supports json5)
  • YAML - read from a YAML file

License

WTFPL

Author

sneak <sneak@sneak.berlin>