Providers
what providers do
Providers evaluate scheme:// URIs into real values by running shell commands. After {ref} interpolation, confit scans the result for URIs that match a declared provider and calls the provider’s command to get the final value.
declaring providers
Add a [providers] section to confit.toml:
[providers.op]
cmd = "op read {uri}"
[providers.tf]
cmd = "terraform -chdir=iac/stages/{stage} output -raw {path}"
[providers.aws]
cmd = "aws ssm get-parameter --name {path} --with-decryption --query Parameter.Value --output text"
The key after providers. is the scheme name. A value starting with op:// dispatches to providers.op, tf:// dispatches to providers.tf, and so on.
template variables
Provider cmd templates have access to:
| Variable | Description |
|---|---|
{uri} |
The full original value (e.g. op://vault/item/field) |
{path} |
Everything after scheme:// (e.g. vault/item/field) |
| Any runtime var | Set via --set, CONFIT_VAR_*, or [vars] in TOML |
how evaluation works
Given this config:
[providers.op]
cmd = "op read {uri}"
[vaults]
prod = "my-vault"
[credentials]
api_key = "op://{vaults.prod}/api-key/credential"
When you run confit resolve credentials.api_key:
- Raw:
"op://{vaults.prod}/api-key/credential" - Interpolate:
"op://my-vault/api-key/credential" - Provider match:
op://matchesproviders.op - Template:
cmd = "op read {uri}"becomesop read op://my-vault/api-key/credential - Execute: runs the shell command, captures stdout
- Result: the secret value
runtime vars in providers
Provider templates can reference runtime variables. This is how you parameterize providers for different environments:
[providers.tf]
cmd = "terraform -chdir=iac/stages/{stage} output -raw {path}"
[infra]
server_ip = "tf://server_ip"
$ confit --set stage=production resolve infra.server_ip
# runs: terraform -chdir=iac/stages/production output -raw server_ip
65.108.67.19
If a provider template uses a variable that isn’t set, confit errors with a clear message:
Error: Provider 'tf' requires '{stage}' but it was not set
(resolving 'tf://server_ip'). Pass --set stage=VALUE or set CONFIT_VAR_STAGE
working directory
Provider commands always run from the directory containing confit.toml, not from your shell’s current directory. This means relative paths in provider cmd templates work correctly no matter where you invoke confit from:
[providers.tf]
cmd = "terraform -chdir=stages/{stage} output -raw {path}"
# Both of these resolve identically — terraform sees stages/ relative to confit.toml
$ cd ~/myproject && confit --set stage=prod resolve infra.ip
$ cd ~/myproject/src/deep/nested && confit --set stage=prod resolve infra.ip
confit finds confit.toml by walking up from your current directory through every parent. So you can run it from any subdirectory of your project.
no providers = no evaluation
If there’s no [providers] section in your TOML, values with scheme:// prefixes are left as literal strings. You opt in to provider evaluation by declaring them.
If a value has a scheme:// prefix but no matching provider is declared, it’s also left as-is. This is not an error.
built-in schemes
file://
The file:// scheme reads a file’s contents as the value. No provider declaration needed:
[credentials.ssh]
private_key = "file://keys/deploy_ed25519"
The path is relative to the directory containing confit.toml.
secret://
The secret:// scheme is a wrapper that marks a value as sensitive. It doesn’t change how the value is resolved – it just flags it so display commands (resolve, env, yaml) mask it as *** by default.
[credentials]
api_key = "secret://op://{vaults.prod}/api-key/credential"
db_password = "secret://vault://secret/myapp/db_pass"
plain_secret = "secret://my-literal-secret"
The secret:// prefix is stripped, and the inner value is resolved normally (interpolation, shell eval, provider eval). The value is then tracked as sensitive.
Use --reveal on display commands to see real values:
$ confit resolve credentials.api_key
***
$ confit resolve credentials.api_key --reveal
sk-abc123
Commands that pass values to processes (run, ssh) always use real values – masking only applies to display output.
adding a new provider
To add a new secret backend or data source:
- Add the provider declaration to
confit.toml:[providers.vault] cmd = "vault kv get -field=value {path}" - Use the scheme in your config values:
[credentials] db_password = "vault://secret/data/myapp/db_password" - That’s it. No code changes needed.