My dotfiles use the macOS Keychain for all credentials — nothing plaintext in the repo. When you run `chezmoi apply`, secrets are pulled directly from Keychain and injected into config files. In `chezmoi`, you can reference values through templates: ``` {{ output "security" "find-generic-password" "-s" "<service>" "-a" "<account>" "-w" | trim }} ``` This runs `security` at apply-time, fetches the password, and puts it wherever you need it. ## Adding a Secret Let's say you need to add credentials for a new email account. **1. Add it to Keychain:** ```bash security add-generic-password -s "my-service" -a "[email protected]" -w # Type your password when prompted ``` **2. Reference it in a template:** ```bash chezmoi edit ~/.config/mbsync/mbsyncrc # note: use the target path, not the source ``` Then add the template snippet where the password goes. **3. Apply:** ```bash chezmoi diff # preview changes chezmoi apply # write files with secrets injected ``` ## Examples ### Git SMTP Password ```toml # dot_gitconfig.tmpl [sendemail] smtpserver = smtp.mailbox.org smtpuser = [email protected] smtppass = {{ output "security" "find-generic-password" "-s" "mailbox-smtp" "-a" "[email protected]" "-w" | trim }} ``` Add the secret: ```bash security add-generic-password -s "mailbox-smtp" -a "[email protected]" -w ``` ### Newsboat (NewsBlur) ``` # private_dot_newsboat/config newsblur-passwordeval "security find-generic-password -s newsblur-login -a kglitchy -w" ``` Add the secret: ```bash security add-generic-password -s "newsblur-login" -a "kglitchy" -w ``` ### Neomutt (FastMail IMAP) ``` # private_dot_config/neomutt/accounts/fastmail.muttrc set imap_pass = "{{ output "security" "find-generic-password" "-s" "fastmail-imap" "-a" "[email protected]" "-w" | trim }}" ``` Add the secret: ```bash security add-generic-password -s "fastmail-imap" -a "[email protected]" -w ``` ## Naming Conventions I try to keep service names descriptive: | Purpose | Service (`-s`) | Account (`-a`) | | ---------------- | ------------------- | ---------------------------- | | Mailbox.org SMTP | `mailbox-smtp` | `[email protected]` | | FastMail IMAP | `fastmail-imap` | `[email protected]`| | NewsBlur | `newsblur-login` | `kglitchy` | | CalDAV | `vdirsyncer-fastmail` | `[email protected]`| ## Managing Existing Secrets **Update a password:** ```bash security delete-generic-password -s "service-name" -a "account-name" security add-generic-password -s "service-name" -a "account-name" -w ``` **Check if a secret exists:** ```bash security find-generic-password -s "service-name" -a "account-name" -w ``` Returns the password if it's there, errors if not. **List all your service names:** ```bash security dump-keychain 2>&1 | grep '"svce"<blob>=' | sed -E 's/.*<blob>="([^"]+)".*/\1/' | sort -u ``` ## When Things Go Wrong > [!Error] "item could not be found in the keychain" You forgot to add the secret, or the service/account names don't match exactly. Check what you named it: ```bash security find-generic-password -s "your-service" -a "your-account" -w ``` > [!Error] Template renders empty string The `security` command ran but returned nothing. Double-check your names match exactly (they're case-sensitive). > [!Error] Secret works in terminal but not chezmoi Make sure you're using the right syntax: ``` {{ output "security" "find-generic-password" "-s" "service" "-a" "account" "-w" | trim }} ``` Note: `output` not `.chezmoi.output`, and don't forget the `| trim` at the end. ## Security Notes - Secrets only exist in memory during `chezmoi apply` — nothing gets written to disk in plaintext - Use the `private_` prefix on sensitive source files — chezmoi sets them to mode 0600 - Only commit the `.tmpl` templates, never the rendered files with actual secrets