TILLFORGE · SOURCE TRACK

Prove how a commit reached your branch.

GA

Build provenance says what was built from a commit. The source track says how that commit got onto the branch: under which protection rule, after which review, and for how long the rule has held without a break. TillForge grades each update against the SLSA Source track and signs the result, so a deploy, an auditor or another organisation can check it.

01Recorded

Which updates get a record

The default branch, and every branch a protection rule covers, gets one record each time it moves: by a push, a merged pull request, an edit in the web editor, an agent, or a recovery from the ref log. Tags and branch deletions are not recorded. Each record keeps the rule as it was at that moment, so changing a rule later never rewrites what an earlier update was held to.

02Policy

Levels, version 1

LevelWhen an update reaches it
L1The commit is in version control. Every update, and every record that is not signed yet.
L2A rule protects the branch, refuses force pushes and deletions, and this update did not rewrite history. A force push or a recovery stays at L1.
L3L2, and the rule enforces at least one technical control: required checks, signed commits, required approvals, or MFA to push.
L4L3, and the update is a merged pull request approved on its final head by someone other than its author, under a rule that requires approvals and dismisses them when new commits arrive.

For each control that held, the record names the commit and time since which it has held without a break. The run continues only while each update starts from the commit the previous record ended on. A force push, a recovery, or a move TillForge has no record of starts it again. Every record lists what stands between it and the next level.

03Provenance

Source provenance, version 1

https://tilldev.dev/docs/tillforge/source-track#provenance-v1. An in-toto Statement v1 whose subject is the commit, with the repository and the branch, and whose predicate holds the facts the level is graded from.

FieldWhat it holds
recordThe TillForge record id.
repositoryThe repository URL, and ref, the branch.
previousThe commit the branch moved from, empty when it was created.
operationcreate, update, or force_update when history was rewritten.
viapush, merge, web, agent or recover, and the actor that moved the branch.
controlsThe protection rule in force, field by field.
controlsSinceFor each control that held, the commit and time it has held since.
reviewFor a merge: the pull request, its author, the head that was merged, and who other than the author approved that head.
04Verifier

The verification summary

https://tilldev.dev/docs/tillforge/source-track#verifier is TillSecrets acting for your workspace. Before it signs, it grades the stored facts again and refuses a record whose level does not follow from them. It then signs the provenance, and a SLSA Verification Summary v1 that names the level and points at the provenance by digest:

json
{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [{
    "uri": "git+https://git.tilldev.dev/acme/acme-api.git",
    "digest": { "gitCommit": "3f9c2e1…" },
    "annotations": { "source_refs": ["refs/heads/main"] }
  }],
  "predicateType": "https://slsa.dev/verification_summary/v1",
  "predicate": {
    "verifier": { "id": "https://tilldev.dev/docs/tillforge/source-track#verifier" },
    "timeVerified": "2026-10-05T10:01:00Z",
    "resourceUri": "git+https://git.tilldev.dev/acme/acme-api.git",
    "policy": { "uri": "https://tilldev.dev/docs/tillforge/source-track#policy-v1" },
    "inputAttestations": [{ "uri": "…", "digest": { "sha256": "<digest of the provenance payload>" } }],
    "verificationResult": "PASSED",
    "verifiedLevels": ["SLSA_SOURCE_LEVEL_3"]
  }
}

Both are DSSE envelopes of type application/vnd.in-toto+json, signed by the same workspace key as build provenance: ECDSA P-256 and ML-DSA-65. The private halves never leave TillSecrets.

What it vouches for
The summary records what TillForge enforced on its own branches. A commit that reached the branch in a way TillForge did not see, for example on a mirror you push to elsewhere, has no record and does not verify.
05Verify

Check a commit

verify accepts a commit prefix. It needs both signatures on each envelope to check out under one of your keys, both envelopes to name the same commit, and the summary to point at the provenance. With --keys it works offline.

bash
# Each protected branch's level, and its recent updates.
tilldev forge source acme-api

# One update: the rule in force, since when each control held, what the next level needs.
tilldev forge source show acme-api <record-id>

# Is this commit verified source? Exits 1 when it isn't, or is below --level.
tilldev forge source verify acme-api 3f9c2e1 --level 3

# The same check with no network and no login.
tilldev forge provenance keys --out tillforge-keys.json
tilldev forge source download acme-api <record-id>
tilldev forge source verify --bundle acme-api-1a2b3c4d.source.intoto.jsonl --keys tillforge-keys.json --commit 3f9c2e1

The same records are in each repository’s Source tab and on the API: GET /api/forge/repos/{repo}/source and GET /api/forge/repos/{repo}/source/{id}/attestations. Anyone with write access can sign a record again from its stored facts; a workspace may ask 30 times an hour, and each request is in the audit log.

06Deploy

Gate deployments on it

The deploy policy check supply-0005 passes when a protected branch pointed at the deployed commit at SLSA Source Level 3 or above and the summary is signed. It starts at warn; set it to block in the deploy policy. The coverage map shows each default branch’s level in its Source column.


Next: branch protection to raise a branch’s level, or build provenance. Back to the TillForge overview.