Skip to content

Secrets

Config files often need a token, a password, or an API key. dotfix lets a template reference one by name:

machine = "example.com"
password = {{ secret("smtp_password") }}

The repository stores the name. The value is looked up on the machine when the file is rendered. dotfix never holds it, never writes it to the repository, and redacts it from its own output.

Each machine decides for itself, so the same repository works on a Mac with 1Password and one without.

ProviderWhat it needs
macOS KeychainThe default. Nothing to install.
1PasswordThe op command-line tool, and a vault name recorded for this machine.
ageThe age tool and an identity file at ~/.config/dotfix/age.key.

The choice is made during setup and recorded in machines/<name>.toml. Setting a machine up again does not change a provider already recorded there — the repository knows how that machine works, and a setup screen asking the question again is not newer information.

dotfix doctor checks the tooling for whichever provider a machine uses, and the setup screen checks it before writing anything, so choosing 1Password on a Mac without op is caught immediately rather than at the first apply.

A rendered file containing a secret is written with 0600 permissions — readable by you and nobody else.

The same file will not be written back into the repository. The copy on disk holds the real value, so writing it back would commit the secret and replace the {{ secret("name") }} placeholder with it, destroying the template in the same stroke. dotfix refuses and points at the template instead.

Adopting is also refused for files whose name suggests they are the credential — an SSH private key, a .netrc, an .aws/credentials. The suggestion is to add a template referencing a secret instead.