Command Palette

Search for a command to run…

ZarynZaryn
Code hosting and version control·4 min read·

Signed commits

zev signs every new commit on your computer with the repository's Ed25519 key. Add the key to your account once and Zaryn shows those commits as Verified, with your name.

A commit says who wrote it, but anyone can type any name into their zev config. A **signature** proves which key made the commit. zev signs every new commit on your computer, and Zaryn shows a commit as **Verified** only when the key that signed it is on the account it names. ```diagram type: cards title: What each label means --- ✓ | Verified | a good signature by a key on an account; the commit list names that account ✍ | Signed | a good signature by a key no account has added yet · | No label | no signature, for example a commit made with commit.sign false ``` ## How it works ```diagram type: sequence title: From zev commit to Verified lanes: Your computer | Zaryn alt: zev commit signs the commit hash with the repository's key and keeps the signature in .zev/signatures; zev push uploads the commit and then the signatures; Zaryn checks each signature against its commit and shows it as Verified when the key is on an account --- note Your computer : zev commit: sign "zev commit <hash>" with .zev/identity | accent Your computer -> Zaryn : zev push: the commit's objects, then its signatures note Zaryn : check each signature against its commit hash; keep the first one | good Zaryn --> Your computer : how many it kept, and how many are Verified on your account ``` - The signature covers the commit's hash, and the hash covers the files, the message, the author and the parent. Change one byte and the signature no longer fits. - Each repository has its own key, in `.zev/identity`. `zev signing-key` prints it. - zev keeps the signatures in `.zev/signatures` and sends them after the commits on the next push. A signature the server already has is not sent again. - The server checks every signature before keeping it. A commit keeps its first signature: a later one can't replace it. ## Show your commits as Verified Run this once in each repository you push from: ```bash zev signing-key add --label laptop ``` zev sends the repository's public key to your account. From then on, every commit it signed shows as **✓ Verified** in the commit list and on the commit page, with your name. Commits signed before you added the key count too. You can also add a key on the web: **Security → Commit signing keys**. Run `zev signing-key` in the repository and paste the key it prints. ```diagram type: flow title: Why Zaryn never links a key by itself --- Pushing is not proof | a push token can leak; it says nothing about who owns a key | warn | 🔑 ~ zev signing-key add Only you link it | a key counts once its account adds it | good | ✓ ~ first come One account per key | even after removal, nobody else can claim it | accent | 🔒 ``` ## Merge only Verified commits A repository's admins can require it: **⚙ Settings → Merge only Verified commits**. A pull request then merges only when every commit it brings is Verified. The pull request's checklist says how many aren't, and nobody can force the merge past it, not even an admin. ```diagram type: flow title: A pull request under the rule --- Unsigned commits | the checklist: 2 commits aren't Verified; Merge is off | warn | ✍ ~ zev sign-commits, zev push Every commit Verified | the check turns green | good | ✓ ~ Merge Merged | the target branch only ever gets Verified commits | accent | 🔒 ``` The rule also guards one branch against direct pushes, `main` unless you name another in the same settings. A push that would bring it a commit that isn't Verified is refused, and zev says how many and what to run. Other branches take anything, so you can push work in progress and open a pull request; its check covers those commits. zev hands signatures over before it moves a branch, so a signed push goes through in one step. ```bash zev push-api origin main # Push refused: 1 new commit(s) on main aren't Verified, and this repository takes only Verified commits there zev sign-commits 1 zev push-api origin main # Push complete ``` Scripts and agents can read and set it too: `GET` and `PUT /v1/repos/<owner>/<repo>/signing-rule` with `{"require_verified": true, "branch": "main"}`. The commit list (and the `zaryn_commits` tool of `zev mcp`) shows each commit's signature. ## Commands ```bash zev signing-key # this repository's key, and whether new commits are signed zev signing-key add [--label x] # add it to your account: its commits show as Verified zev signing-key ls # the signing keys on your account, with how many commits each signed zev signing-key rm <id> # remove one: its commits show as Signed, not Verified zev verify <commit> # check a commit's signature here (a short hash is enough) zev sign-commits [N] # sign the last N commits that have no signature (default 100) zev config set commit.sign false # stop signing new commits in this repository ``` ## Questions **I lost the computer.** Remove the key with `zev signing-key rm <id>` or on the Security page. Its commits stop showing as Verified, and nobody else can add that key to their account. **I cloned on a new computer.** The new copy gets its own key the first time it signs. Run `zev signing-key add` there too. **Commits from before signing existed.** `zev sign-commits` signs them with the repository's key. Push, and they show up. **How is this different from `zev sign <cid>`?** `zev sign` signs any object with your identity, for proofs you hand to someone. Commit signing is automatic and shows on Zaryn. See also [Advisories and lineage](/docs/en/advisories) for marking commits as compromised, and [Verified storage](/docs/en/verified-storage) for proof that Zaryn keeps what you pushed.