Skip to content

Audit trail policy

How TLSStress.Art makes the chain commit → tag → release → binary cryptographically verifiable. Every link in that chain has a signature an external party can re-verify without trusting us.

The chain

   ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
   │  Commit  │ →  │   Tag    │ →  │  Release │ →  │  Binary  │
   └──────────┘    └──────────┘    └──────────┘    └──────────┘
        │              │               │               │
        │              │               │               └── Cosign keyless OIDC
        │              │               └── SBOM + GHCR attest
        │              └── git tag -s (GPG or SSH)
        └── DCO sign-off + (recommended) signed commit

Each step has its own policy section below.

Developer Certificate of Origin

Every commit landing on main MUST carry a Signed-off-by: trailer matching the commit author. The trailer is an assertion of the DCO 1.1 text:

Signed-off-by: André Luiz Gallon <agallon@Cisco.com>

Add it automatically with git commit -s / git commit --signoff. Enforce it locally with a hook:

# .git/hooks/commit-msg
#!/bin/sh
if ! grep -qE '^Signed-off-by:' "$1"; then
  echo "ERROR: missing Signed-off-by. Use 'git commit -s'." >&2
  exit 1
fi

Enforcement: the dco-check workflow walks every commit in every PR and fails if the trailer is missing or doesn't match the author. PRs cannot merge without this check green.

Retroactive fix

If you've already pushed unsigned commits:

# Rebase the offending range, adding sign-off to each commit:
git rebase --signoff <last-good-commit>
git push --force-with-lease origin <branch>

Commit signing (GPG / SSH)

Strongly recommended in addition to DCO sign-off. Once configured, GitHub displays a "Verified" badge next to your commits and the signature can be re-verified by anyone cloning the repo.

SSH signing setup (recommended over GPG for simplicity):

# One-time:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true

# Tell GitHub about the public key:
gh ssh-key add ~/.ssh/id_ed25519.pub --type signing

After that, every git commit and git tag is auto-signed.

We don't currently enforce commit signing in CI (only DCO), because it would block first-time contributors before they configure. The maintainer enables it locally and it shows up as GitHub "Verified" badges on every release.

2. Tag-level — signed annotated tags

Every release tag (any tag matching v*) MUST be a signed annotated tag:

git tag -s v3.7.0 -m 'TLSStress.Art v3.7.0 — ZTP-prem 12/12 closes'
git push origin v3.7.0

Enforcement: the tag-signature-verify workflow fires on any pushed v* tag and fails if:

  • The tag is lightweight (not annotated) — lightweight tags cannot carry signatures
  • The annotated-tag object body has no signature block

If the workflow fails, recreate the tag signed:

git tag -d v3.7.0
git push --delete origin v3.7.0       # remove the unsigned remote tag
git tag -s v3.7.0 -m '...'            # recreate signed
git push origin v3.7.0

The current v1 workflow verifies signature presence, not identity. Full key-allow-list verification is a planned follow-up (needs the maintainer's public-key fingerprint imported into the GitHub Actions runner). That's tracked alongside the docs/runbooks/verify-release.md runbook.

Why annotated, not lightweight

A lightweight tag is just a pointer to a commit. An annotated tag is its own git object with author + date + message + an optional signature block. Only annotated tags can be signed. Release tags need the audit-trail attachment that lightweight tags can't provide.

3. Release-level — Cosign + SBOM (already shipping)

Covered by ADR 0005 and operationalised in .github/workflows/release.yml.

Summary:

  • Every multi-arch image gets a Cosign keyless OIDC signature bound to the workflow run + ref
  • A full SPDX SBOM is generated by Syft and attached to the GitHub release as an asset
  • A slim SBOM is attested via the GitHub Attestations API (subject to a 16 MiB cap)
  • The release-feed branch carries a signed manifest used by the self-upgrade flow
  • A tier-policy receipt (SHA-256 of platform/ztp-prem/tier-policy.yaml) is published so auditors can confirm the Tier B partition that defined moat-closed code at build time matches the public repo's policy file

4. Binary-level — verifiable by downstream

The docs/runbooks/verify-release.md runbook gives the 8-step procedure to verify a pulled binary end-to-end. Any downstream operator or auditor can re-establish the chain commit → tag → release → binary from public artefacts alone.

How to audit the chain

Walking the chain from binary backwards:

  1. Binarycosign verify <image> (see runbook step 2)
  2. Releasegh release view <tag> lists the SBOM and the tier-policy receipt (runbook step 4 + 8)
  3. Taggit verify-tag <tag> re-verifies the tag signature from the local clone
  4. Commitgit log --show-signature <tag> re-verifies every commit signature in the tag's history; git log --grep 'Signed-off-by' confirms the DCO trailer

If any step in that chain breaks, the binary is untrusted. The runbook's troubleshooting table covers the common cases (slim-SBOM cap, slim-SBOM attest failure, etc.) so the auditor knows which failures are tolerated vs which are show-stoppers.

What about external contributors

The project currently does not accept code contributions from external authors (noncommercial source-available licence; patent prosecution in progress — see AUTHORS.md). The DCO check still runs on RFC + discussion contributions because, when the contribution model opens up later, the infrastructure must already be in place.

When external contributions resume, the DCO check is the licence-clarity floor:

  • Contributor adds Signed-off-by: <name> <email> per commit
  • They assert (per DCO 1.1) they have the right to submit under PolyForm Noncommercial
  • The maintainer reviewing the PR has evidence of the assertion in the commit history — not in a separate CLA tracker

That's why we use DCO rather than a CLA: a CLA needs an out-of- band signing flow (DocuSign / CLA-assistant bot / etc.), DCO just needs git's existing trailer mechanism.

Audit-day handoff

When an auditor asks "show me the audit trail":

  1. Hand them this document
  2. Hand them docs/runbooks/verify-release.md
  3. Show the 4 enforcement workflows:
  4. .github/workflows/dco-check.yml — every PR commit signed-off
  5. .github/workflows/tag-signature-verify.yml — every tag signed
  6. .github/workflows/release.yml — Cosign + SBOM per release
  7. .github/workflows/scorecard.yml — OSSF Scorecard
  8. Pick a recent release tag and walk the 4-step verification together — they'll see signed commits → signed tag → Cosign- signed binary → SBOM-attested package manifest

That's what an enterprise valuation audit means by "auditable supply chain". Every claim ends in a public artefact a stranger can re-verify.


Last verified against shipping code: v3.7.0 (2026-05-12).