Secrets
Never put a credential in a config file. Reference it instead:
[server.env]GITHUB_TOKEN = "${secret:github.token}"${secret:…} is resolved at apply time from an age-encrypted vault and written
into native config. ${env:…} pulls from the environment. The resolved value is
never captured back into your source — agentsync diff even redacts it so a
piped diff can’t leak it.
Set up the vault
Section titled “Set up the vault”The vault is encrypted to a recipient (public key — safe to commit);
decryption needs the identity (private key — per-machine). agentsync embeds
age, but generating the key uses the age-keygen CLI.
-
Install age (for
age-keygen):brew install age,apt install age, … -
Generate a keypair:
Terminal window mkdir -p ~/.config/agentsyncage-keygen -o ~/.config/agentsync/age.key # prints "Public key: age1…" to stderrchmod 600 ~/.config/agentsync/age.key # agentsync refuses a group/other-readable identity -
Point
agentsync.tomlat it —recipientis theage1…public key thatage-keygenprinted:~/.agentsync/agentsync.toml [secrets]backend = "age"recipient = "age1…"identity_file = "${env:HOME}/.config/agentsync/age.key"
The env backend
Section titled “The env backend”[secrets].backend has two values, matched case-insensitively ("AGE" and
"age" are one value — the name is folded before the backend is selected, but
never trimmed). "age" — everything above — resolves ${secret:…} from the
encrypted vault. "env" resolves it from the process environment instead, the
same lookup ${env:…} performs:
[secrets]backend = "env"Use it when something else already puts credentials in the environment —
direnv, the 1Password CLI, a CI secret store. There is no vault and no
identity file, so recipient, identity_file and file are unused, and the
agentsync secret subcommands (which read and write the age vault) refuse with
a message naming the backend they need. agentsync check and agentsync doctor
both accept it.
Store and read secrets
Section titled “Store and read secrets”agentsync secret set accepts the value three ways:
agentsync secret set github.token --stdin # from stdin (best for scripts / 1Password CLI)agentsync secret set github.token # interactive prompt, echo offagentsync secret set github.token=ghp_… # back-compat; warns — argv is visible to ps(1)agentsync secret edit # open the whole vault in $EDITORagentsync secret get github.token # read one back (to verify)secret edit decrypts the vault to a temp file for $EDITOR, so there is a
window in which your secrets exist in cleartext on disk. Interrupting it
(Ctrl-C, or kill) is safe: agentsync signals the editor, removes the
decrypted copy, saves nothing, and exits 130 without printing anything. The one
exception to that is an interrupt that lands during the final re-encrypt itself:
that write is allowed to finish so the vault is never half-written, and the
command then reports the save and exits 0 as if it had not been interrupted. An
editor that ignores the interrupt is given a couple of seconds to exit on its own
and is then stopped, so the command can never hang waiting for it. The vault is
rewritten only when the editor exits normally and the edited file passes the
same validation apply uses.
Why it can’t leak
Section titled “Why it can’t leak”The dangerous bug class is a resolved cleartext secret being persisted back into your canonical source — often a committed dotfiles repo. agentsync makes this hard to do by accident with several tiers of defense, including a compile-time guarantee (the resolved model is a distinct type that source writers literally cannot accept) and a fail-closed backstop in the capture path that refuses to write rather than risk persisting a credential.