- OCaml 81%
- Perl 17%
- Shell 1%
- <1%
- Dune <1%
warrant #
Short-lived signing certificates for Git, issued down a chain of authority.
warrant issues OpenSSH user certificates to the people, seats and lanes that
sign Git commits. Each certificate names its holder down a chain of
authority, thomas then thomas:apollo, and its key id names the UCAN
delegation from the root's did:key to the holder's key. Git verifies every
commit a holder signs against one cert-authority line, so neither Git nor a
merge queue changes. The holder's key lives in an ssh-agent for the
certificate's window and is never written to disk; revocation is a record in
warrant's log and a key revocation list Git reads, derived from that log.
A session #
warrant init thomas --dir store draws the root key, writes the
allowed-signers line thomas:* cert-authority,namespaces="git", an empty
revocation list and an empty log, and sets gpg.format,
gpg.ssh.allowedSignersFile, gpg.ssh.revocationFile,
gpg.ssh.defaultKeyCommand, gpg.ssh.program and commit.gpgSign in the
global Git configuration. The root key is a file on disk, the weakest custody, and
init says so. warrant init thomas --root ca.pub --dir store takes instead
the root an ssh-agent already holds, a security key's or a token's, writes its
public key alone, and has the agent sign every certificate and delegation.
The root is Ed25519 or P-256, the two curves UCAN's delegation signature
takes; P-256 is the one a Mac's Secure Enclave holds, through an agent such
as Secretive.
warrant issue apollo --for 8h --repo repo --dir store draws a key into the
agent for eight hours, signs the delegation and the certificate, and records
both in the log. The delegation grants /git/ref/update on one repository,
named by the id of the root commit its HEAD's first parents lead to, which no
clone or forge changes, and on the refs a like pattern matches,
refs/heads/* unless --ref PATTERN says otherwise; --repo takes the
repository's path or that id, and a seat is never issued without one. Git runs warrant key --dir store as its default key command and
signs with the certificate; git log --format='%G? %GS' prints
G thomas:apollo. When several seats hold a certificate, WARRANT_SEAT
names the one Git signs with.
warrant verify HEAD -C repo --dir store reads the certificate out of the
commit's signature and prints its window at the committer date, the chain its
key id names with what the delegation grants, and the log record that holds
it; --at TIME judges the window at a time the reader trusts more than the
committer's. The commit is judged as an update of the branch HEAD points at,
or of the ref --ref REF names, in the repository it is read from, and a ref
or a repository the delegation does not cover is refused. warrant revoke 1
records the revocation and rewrites the revocation list, after which Git
reports the commit as B. warrant show lists the log.
A seat is rotated by issuing it again before its certificate's window ends:
warrant key then hands Git the new certificate, and the old one, superseded,
still verifies the commits it signed inside its window. warrant show apollo --dir store lists the seat's certificates, each with its state at the clock,
derived from its window, the log and the agent: active, superseded, pending
(no key in the agent), expired or revoked. A seat with no active certificate
is refused by warrant key, which names the warrant issue command that
issues it a new one.
The fleet's agent #
A sandboxed session reaches Unix sockets under its own temporary directory
alone, and on macOS launchd binds the login's ssh-agent under /var/run, at
a path that changes at every login. warrant agent runs one ssh-agent at a
fixed socket every session and the queue runner reach,
/tmp/claude-UID/warrant.sock unless --socket or WARRANT_SOCKET names
another, as a child it supervises in a process group of its own; it refuses
a path longer than a socket address holds and a socket another agent already
answers at, and ends with its child's status. warrant agent install writes
the launchd job that keeps it across logins and reboots and prints the
launchctl bootstrap command that loads it, which the operator runs.
warrant issue, key and show use that agent whenever its socket is
there, and the one at SSH_AUTH_SOCK otherwise or with --agent; a root an
agent holds still signs through SSH_AUTH_SOCK. gpg.ssh.program is
store/ssh-keygen, which runs ssh-keygen with SSH_AUTH_SOCK set to the
same socket by the same rule, so Git signs through the fleet's agent
whatever the caller's SSH_AUTH_SOCK says.
warrant issue prints the socket of the agent that received the key, and
says so when --agent puts it in an agent other than the fleet's, which Git
does not sign through. A restart of the fleet's agent drops every key while
the certificates stay inside their windows; warrant key then refuses,
naming the seat, the agent's socket and the warrant issue command, and Git
prints that refusal after gpg.ssh.defaultKeyCommand failed. Git signs with
user.signingKey whenever a configuration sets it and never runs the
default key command, so a certificate pinned there outlives its key and
every rotation: warrant issue names each configuration that sets it for
the repository, the global one or the repository's own, with the
git config --unset command that removes it.
The log #
The log is a transparency log the root signs. Each issue and revocation is
a SCITT signed statement of the root's did:key, whose subject is the
certificate's key id, registered in an RFC 9162 Merkle tree kept as C2SP
tlog-tiles under store/log: a checkpoint the root signs, the tiles, a
receipt per record proving its inclusion, and the delegations by CID. Every
file is named by its place in the tree or by its digest and none is edited,
so the directory can be served as it is or kept in Git, and warrant verify
checks a record's receipt under the checkpoint with nothing from a server.
Related work #
- gitsign issues short-lived certificates from Sigstore's Fulcio after an OIDC sign-in and records each signature in the public Rekor log. It needs an identity provider and a public log at signing time, and Git verifies its signatures only through gitsign. warrant works offline, keeps its log as tiles a reader checks offline, and is verified by Git's own SSH signature check.
- OpenSSH certificates
and
ssh-keygen -sare what warrant issues;ssh-keygensigns one certificate at a time, with no record of why it was issued and no derived revocation list. warrant adds the chain of authority, the log and the revocation list, and keeps the holder's key out of every file. - gittuf adds TUF-style policy on which keys may write which refs, stored in the repository. It is a policy layer over signatures and does not issue them; warrant issues the certificates such a policy could name.
Licence #
ISC. See LICENSE.md.