Skip to content

Secrets

Never put a credential in a config file. Reference it instead:

~/.agentsync/mcp/github.toml
[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.

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.

  1. Install age (for age-keygen): brew install age, apt install age, …

  2. Generate a keypair:

    Terminal window
    mkdir -p ~/.config/agentsync
    age-keygen -o ~/.config/agentsync/age.key # prints "Public key: age1…" to stderr
    chmod 600 ~/.config/agentsync/age.key # agentsync refuses a group/other-readable identity
  3. Point agentsync.toml at it — recipient is the age1… public key that age-keygen printed:

    ~/.agentsync/agentsync.toml
    [secrets]
    backend = "age"
    recipient = "age1…"
    identity_file = "${env:HOME}/.config/agentsync/age.key"

[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:

~/.agentsync/agentsync.toml
[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.

agentsync secret set accepts the value three ways:

Terminal window
agentsync secret set github.token --stdin # from stdin (best for scripts / 1Password CLI)
agentsync secret set github.token # interactive prompt, echo off
agentsync secret set github.token=ghp_… # back-compat; warns — argv is visible to ps(1)
Terminal window
agentsync secret edit # open the whole vault in $EDITOR
agentsync 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.

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.