Quickstart
Get attest recording and verifying provenance in under a minute. attest stores attestations in
git notes (refs/notes/attest), so there is no service to run and nothing to configure beyond an
optional policy file.
Requirements
- Swift 6 and
gitonPATH. - macOS and Linux: attest supports macOS and Linux. Windows is out of scope.
- Signing uses Apple’s
swift-crypto; the CLI usesswift-argument-parser.
Install
swift build -c release
install -m 0755 .build/release/attest /usr/local/bin/attest
# or, with fledge:
fledge run install
Try it instantly (no setup)
This builds the binary, records an attestation against a throwaway /tmp repo, and reads it
back. It touches nothing of yours:
bash examples/01-basic-attestation.sh
Nine more runnable, self-contained examples (each against a throwaway repo) are catalogued in
examples/README.md.
1. Record an attestation (unsigned, zero setup)
Out of the box, attestations are unsigned but valid, with no key required.
attest sign --commit HEAD --reviewer agent:claude --confidence 0.92 --tests-passed
A confidence value must come from somewhere: pass --confidence, --human-approved, or
--from-augur.
2. Read the ledger
attest log # all attested commits
attest log --commit HEAD --json # one commit, machine-readable
attest log --range main..HEAD
attest · ledger
commit 9f2c1a7b04 (1 attestation)
[·] agent:claude verdict:- conf:92% tests:ok human:- unsigned
On a terminal this is colorized by meaning: green for proceed/verified, amber for
review, red for block/violations, cyan reviewers, dim for unsigned/absent cues.
Control it with --color auto|always|never; piped or --json output stays plain, and
NO_COLOR disables colour. See the CLI reference.
3. Pipe augur straight in
attest sign --from-augur <file|-> reads augur check --json and merges it: augur’s verdict is
copied, and its riskScore (0…100) becomes confidence = 1 − riskScore/100.
augur check --range main..HEAD --json \
| attest sign --commit HEAD --reviewer agent:claude --from-augur - --tests-passed
4. Sign cryptographically (optional)
Generate a key once, then add --sign. keygen prints the public key to copy into a policy’s
trustedKeys / signerPinning.
attest keygen
# attest · wrote private key to ~/.config/attest/key (0600)
# public key: BASE64_PUBKEY <- copy into signerPinning / trustedKeys
attest sign --commit HEAD --reviewer human:leif --confidence 0.7 --human-approved --sign
See Signing & identity for the full model.
5. Gate a commit against a policy
Policy is plain JSON in .attest.json. Every rule is optional with permissive defaults, so an empty
{} still requires one attestation per commit and passes any commit that has one.
{
"requireAttestation": true,
"requireTestsPassed": true,
"minimumConfidence": 0.6,
"requireHumanApprovalWhenVerdictAtLeast": "review"
}
attest verify --range origin/main..HEAD --policy .attest.json
attest verify · [ok] PASS (3 commits checked)
attest verify’s exit code is its contract: it exits non-zero on any policy violation, so CI
and agent loops gate on it.
attest verify --commit HEAD || echo "trust policy not satisfied, escalating to a human"
See the Policy reference for all 11 rules.
6. Sync the notes
Attestations live in refs/notes/attest. They are not fetched or pushed by a plain
checkout/push, so move them explicitly:
git push origin "refs/notes/*"
git fetch origin "refs/notes/*:refs/notes/*"
Next steps
- Policy reference: all 11 rules.
- CLI reference: every command and flag.
- CI integration: the
attest-verifyaction and the augur → attest pipeline.