Git merge driver & SSH
.murk is a single JSON-ish file with encrypted values, which means a naive
git merge on it doesn’t work the way it would for plaintext: git has no
idea two different encrypted blobs might represent non-conflicting changes
to different keys. murk ships its own merge driver to handle this correctly,
plus first-class support for SSH keys as recipients so you don’t need a
separate age key at all.

Setting up the merge driver
Section titled “Setting up the merge driver”murk setup-merge-driverThis configures git to use murk merge-driver for .murk files by writing
the driver definition to .git/config and pointing .murk at it via
.gitattributes. Run it once per clone (it’s local git config, not
something that travels with the repo automatically; everyone who works on
the vault needs to run it in their own checkout).
Once configured, git invokes murk merge-driver ANCESTOR OURS THEIRS
automatically during a merge or rebase that touches .murk, instead of
falling back to a text-based three-way merge on the raw file. It merges
non-conflicting secret changes (different keys added or changed on each
side) automatically. It does not decide to vouch for the merged content:
the result is left unsigned (sig: null), carrying the existing signer
registry forward. Re-sign it by running any write command (e.g. murk add,
murk rotate) with a signing-capable key after reviewing what actually
changed:
murk diff HEAD@{1} # or whatever ref makes sense for your mergemurk diff [REF] shows which secrets changed relative to a git ref
(defaults to HEAD) without printing values, unless you pass
--show-values. Use it to sanity-check a merge before you trust it.
SSH keys as recipients
Section titled “SSH keys as recipients”You don’t need a separate age keypair if you already have an SSH key. murk
accepts SSH public keys directly as recipients, right alongside age1...
keys in the same recipient list:
murk circle authorize ssh:~/.ssh/id_ed25519.pub --name you@example.comcircle authorize also accepts bare ssh: (defaulting to
~/.ssh/id_ed25519.pub), or github:username to pull SSH keys straight
from a GitHub account. See working in teams for the
GitHub-based flow and its pinning behavior.
ssh-ed25519 keys are accepted by default. ssh-rsa keys are rejected
unless you pass --allow-ssh-rsa: ed25519 is recommended, and this default
nudges teams away from the weaker key type.
Signing behavior differs by key type
Section titled “Signing behavior differs by key type”ssh-ed25519keys are themselves Ed25519 signing keys, so murk signs directly with them. The verifying key is embedded in the recipient string itself, so the signature is self-authenticating: no separate registry entry needed.ssh-rsakeys cannot sign (age exposes no signing scalar for RSA), so writes made with anssh-rsaidentity leave the vault unsigned: a warning on next load, not a hard failure. This is the same “sign when capable” behavior hardware-backed identities have; see hardware keys and the threat model for the full signing story.
Related
Section titled “Related”- CLI reference:
murk setup-merge-driverandmurk circle authorizefor the full flag surface. - Recipients & signatures for how the recipient list and signer registry fit together.