Templates¶
Templates let you reshape Vault secret data before it is written to a target file. They use Go's text/template syntax and receive the Vault KV data map as the dot (.) context.
When no template is specified, the raw Vault secret data is passed directly to the format handler.
Template functions¶
In addition to the standard Go template functions, dotvault provides:
| Function | Signature | Description |
|---|---|---|
env |
env(key) |
Look up an environment variable |
base64encode |
base64encode(s) |
Base64-encode a string |
base64decode |
base64decode(s) |
Base64-decode a string |
default |
default(fallback, val) |
Return val if non-empty, otherwise fallback |
quote |
quote(s) |
Shell-safe single quoting |
The default function follows the Sprig convention where the fallback comes first, enabling idiomatic piping:
Examples by format¶
YAML¶
Sync a GitHub CLI credential into ~/.config/gh/hosts.yml:
rules:
- name: gh
vault_key: "gh"
target:
path: "~/.config/gh/hosts.yml"
format: yaml
template: |
github.com:
oauth_token: "{{ .oauth_token }}"
user: "{{ .user }}"
git_protocol: https
If the user already has other entries in hosts.yml (e.g. for GitHub Enterprise), those entries are preserved. Only the github.com key is merged.
Vault secret (kv/data/users/jane/gh):
Result (merged with existing file):
github.com:
oauth_token: "ghp_xxxx"
user: "jane"
git_protocol: https
github.enterprise.com:
oauth_token: "gho_yyyy" # preserved from existing file
JSON¶
Sync database credentials into a JSON config file:
rules:
- name: db-config
vault_key: "db"
target:
path: "~/.myapp/config.json"
format: json
template: |
{
"database": {
"host": "{{ .host | default "localhost" }}",
"port": {{ .port | default "5432" }},
"username": "{{ .username }}",
"password": "{{ .password }}"
}
}
Vault secret:
Result (merged with existing file):
{
"database": {
"host": "db.internal",
"port": 5432,
"username": "jane",
"password": "s3cret"
},
"logging": {
"level": "info"
}
}
The logging section from the existing file is preserved.
TOML¶
Sync credentials into a TOML configuration:
rules:
- name: cargo-registry
vault_key: "cargo"
target:
path: "~/.cargo/credentials.toml"
format: toml
template: |
[registries.my-registry]
token = "{{ .token }}"
Vault secret:
Result:
[registries.my-registry]
token = "cargo_xxxxxxxxxxxx"
[registries.crates-io]
token = "existing_token" # preserved from existing file
INI¶
Sync AWS credentials into ~/.aws/credentials:
rules:
- name: aws-creds
vault_key: "aws"
target:
path: "~/.aws/credentials"
format: ini
template: |
[default]
aws_access_key_id = {{ .access_key }}
aws_secret_access_key = {{ .secret_key }}
Vault secret:
Result (merged with existing file):
[default]
aws_access_key_id = AKIAXXXXXXXX
aws_secret_access_key = wJalrXxxxxxxxx
[profile staging]
aws_access_key_id = AKIA_OTHER # preserved from existing file
aws_secret_access_key = other_key
Netrc¶
Sync machine credentials into ~/.netrc:
rules:
- name: netrc
vault_key: "netrc"
target:
path: "~/.netrc"
format: netrc
template: |
machine github.com
login {{ .user }}
password {{ .oauth_token }}
Vault secret:
Result (merged with existing file):
Entries are merged by machine name. The existing gitlab.com entry is preserved.
Text (plain)¶
Sync a private key or certificate:
rules:
- name: ssh-key
vault_key: "ssh"
target:
path: "~/.ssh/id_ed25519"
format: text
template: "{{ .private_key }}"
Vault secret:
Text format uses full replacement — the entire file content is overwritten. This is appropriate for opaque blobs like private keys and certificates where merging is not meaningful.
Templates without the template field¶
If no template is specified, dotvault passes the raw Vault KV data map to the format handler. For YAML and JSON, this means all fields from the Vault secret are written to the file:
If the Vault secret at kv/data/users/jane/myapp contains {"api_key": "xxx", "db_pass": "yyy"}, the resulting file would have both fields merged into it.
Tips¶
- Use
defaultto provide fallback values for optional fields - Use
base64encodefor credentials that need to be base64-encoded in the target format (e.g. Kubernetes secrets) - Use
quotewhen embedding values in shell scripts or contexts where quoting matters - Use
envsparingly — it reads from the dotvault process environment, not the user's shell