Your provenance expectation pins the source repository but not the ref. What still passes?
answer
- the repository is not the branch
- who can push versus who can merge
- true provenance, unreviewed code
- pin ref and entry point too
- build track says nothing about source review
basics
~20 sAny build from any branch or tag in that repository. A low-privilege contributor who can push an unprotected branch and trigger the trusted builder gets an artifact whose provenance names the right repository, the right builder, and code nobody reviewed.
solid answer
~50 sA repository-only expectation admits every ref in the repository. Someone with just enough access to push a branch — a contributor, an automation account, anyone whose commits do not go through review — triggers the trusted build system on that branch. The resulting provenance is completely truthful: correct builder identity, correct repository URI, correct digest for those bytes. Your gate passes, and the artifact contains code that never went near the protected release branch. The fix is to make the ref and the build entry point part of the expectation: accept only the release ref or a narrow tag pattern, and require the specific build definition that produces releases, so a different workflow in the same repository and ref cannot produce an equally valid statement. Note what provenance cannot give you here: SLSA v1.0's Build track hardens the build platform, but source review and branch protection sit outside it, so an unforgeable statement can still describe unreviewed code.
go deeper
Know that a repository name is not a branch, and that push access to some branch is usually much easier to get than merge access to the release branch.
Explain why the resulting provenance is entirely truthful and which additional fields — ref and build entry point — turn a true statement into an acceptable one.
Demonstrate you have tightened one of these in production: enumerating the legitimate refs, running report-only, and refusing to widen the pattern when the gate fires.
Own the framing that assurance is platform strength multiplied by expectation specificity, and decide where the organisation spends next when both are weak.
## The gap An expectation of the form *"builder must be our trusted build system, source repository must be `example.org/acme/payments`"* looks complete and is quietly wide open. It authorizes **every commit that repository can ever build**, not the ones your release process blesses. The attacker position that exploits this is not the anonymous internet: it is an **authenticated, low-privilege contributor** — an intern, a contractor, a service account with push rights on non-protected refs, or an outside contributor on a project where any branch can trigger a build. That person cannot merge to `main`, cannot approve a review, cannot touch the release process. They can push `refs/heads/fix-typo-2` and cause the trusted builder to build it. The artifact that comes out carries provenance that is **true in every field**: - builder identity — genuinely the trusted build system; - source repository URI — genuinely yours; - revision — a real commit that really exists in that repository; - subject digest — genuinely the bytes produced. Nothing is forged. The provenance is doing its job perfectly. The **expectation** is what failed, and the asset at risk is audit truth: months later, the record says this artifact was built from your repository by your builder, and that record is used to conclude the code was reviewed. It was not. ## Tightening the expectation Three additions, in order of value: 1. **Pin the ref.** Accept only the refs your release process uses — a specific protected branch, or a tag pattern reserved for releases. Wildcards are fine as long as the wildcard cannot match a ref an unprivileged actor can create. `refs/heads/*` is not an expectation; `refs/tags/v*` is only an expectation if pushing such a tag is itself restricted. 2. **Pin the entry point.** The build definition matters independently of the ref: the same repository at the same commit can usually be built by more than one pipeline definition, and one of them may be far less controlled than the release one. Requiring the expected build type and the expected entry point closes that. 3. **Constrain the revision, not just the ref name.** A ref is a moving pointer. Where you can, require that the built commit is one that reached the protected ref through the process you believe in — for example by checking the revision against your own record of released commits, rather than trusting that a branch name implies review. ## What SLSA does and does not cover here This is the part senior candidates most often get wrong. SLSA v1.0 restructured the framework into **tracks**, and the levels people quote — Build L0 through L3 — belong to the **Build track**. That track is about the build platform: L1 means provenance exists and is distributed; L2 adds a hosted build platform signing the provenance so it is authenticated; L3 hardens the platform so the provenance is resistant to forgery by the build itself, with strong isolation between runs and secret material the build cannot reach. Every one of those is about **how the build ran**. None of them says the source was reviewed, that the branch was protected, or that two people looked at the change — source review and hermeticity were deliberately left outside the build track in v1.0. So an artifact built from an unreviewed branch on a Build L3 platform gets Build L3 provenance, and it is honest provenance. **The build track guarantees the statement is true; only your expectation decides whether a true statement is acceptable.** That reframing is the answer an interviewer is fishing for: verification strength is the product of the platform's assurance *and* the specificity of what you compare against. Raising the platform's level while leaving the expectation at "any ref" buys you a very trustworthy record of an untrustworthy build. ## Operational shape - Keep the expectation somewhere change-controlled with a named owner, and treat a change to it like a change to production access. - Expect real breakage when you tighten it — hotfix branches, release-candidate refs, a migration to a new default branch name. Enumerate the legitimate refs first, then narrow, rather than shipping a narrow rule and disabling it on the first incident. - When the check fails, the default must be *stop and explain*, not *widen the pattern*. A gate whose pattern is widened every time it fires is a log line with extra steps. ## Common wrong answers - "The builder identity covers it" — the builder is the same in both cases; that is exactly why it does not help. - "We're at SLSA Build L3, so the source is reviewed" — the build track makes no source claim. - "Any commit in our repo is our code" — repository membership is not review, and push rights are usually much wider than merge rights.
- Does moving to SLSA Build L3 close this gap?No. The Build track hardens the build platform and makes provenance resistant to forgery by the build itself; it makes no claim about whether the source revision was reviewed or the ref protected — source review sits outside the build track in v1.0. Build L3 provenance for an unreviewed branch is still valid Build L3 provenance. The gap is in your expectation, not the level.
- Once the ref is pinned, what does pinning the build entry point still add?It stops a different build definition in the same repository at the same ref from producing an equally authentic statement. Repositories usually carry several pipelines with different privileges and different review pressure; the release one is the only one whose output you meant to accept. Pinning the build type and entry point makes that explicit.
- How do you tighten a ref expectation without breaking legitimate releases?Enumerate first: pull the refs your last several dozen real releases were built from, and see what the honest set is — release branches, hotfix refs, tag patterns. Write the expectation to cover that set, run it in report-only mode for a cycle to catch the cases nobody remembered, then enforce. Narrowing blind and disabling on the first failure is worse than never starting.
saying these in an interview costs you the question
- Says the trusted builder identity is sufficient on its own
- Assumes a SLSA build level implies source review
- Treats any commit in the repository as reviewed code
- Widens the ref pattern whenever the gate fires
- Sets the ref expectation from whatever the attestation showed