Chapter 7 — Application and software supply chain security: controls and verification
Lesson map
Lesson 07 published. Map, example, EX031.
flowchart TD
N0["Learning outcomes"]
N1["7.1 Controls chosen"]
N2["7.2 Provenance"]
N3["7.3 Verifying controls"]
N4["7.4 Recording results"]
N5["7.5 Ongoing checks"]
N6["7.6 SSDF mapping"]
N7["Rolling out controls"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Worked example"]
EX --> Q["Exercise EX031"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["7.1 Controls chosen"]
N2["7.2 Provenance"]
N3["7.3 Verifying controls"]
N4["7.4 Recording results"]
N5["7.5 Ongoing checks"]
N6["7.6 SSDF mapping"]
N7["Rolling out controls"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX031"]
[Learning outcomes]
|
v
[7.1 Controls chosen]
|
v
[7.2 Provenance]
|
v
[7.3 Verifying controls]
|
v
[7.4 Recording results]
|
v
[7.5 Ongoing checks]
|
v
[7.6 SSDF mapping]
|
v
[Rolling out controls]
|
v
[Worked example] --> [Exercise EX031]
Learning outcomes
You will (1) put build and dependency controls in place; (2) verify each with safe tests; (3) record provenance for releases; (4) check controls stay effective.
7.1 Controls chosen
Internal-prefix rule in the build service; lock files with hashes; build failure on mismatch; dependency review notes; pinned build actions; least-privilege build tokens; and provenance for each TrackPort release. Together the controls cover the path from source to release. The prefix rule, lock files, hash checks and review notes protect what goes into the build. Pinned build actions stop a build step changing without review, and least-privilege tokens limit what a compromised build could do. Provenance records how each release was built. Priya records each control with its owner and how it is tested.
7.2 Provenance
The build service produces a signed provenance statement naming the source commit, builder and inputs. SLSA v1.0 build level 2 requires provenance signed by a hosted build platform. Tools such as in-toto (Torres-Arias et al., 2019) and Sigstore (Newman et al., 2022) support creating and verifying such statements. For TrackPort, provenance means the deployment system can check that a release came from Harbourline's build service and a known commit. A release built elsewhere, or with unexpected inputs, can be refused. Priya records which SLSA level the build meets and how verification is done at deployment.
7.3 Verifying controls
Each control gets a safe test using synthetic internal packages: a test project naming a fake internal package confirms the build refuses to resolve it publicly; a lock file with an altered hash confirms the build fails; a release without provenance is refused by deployment. Each test uses synthetic packages and releases, so no real system or public registry is touched. A control that passes the test has shown it works, not only that it is configured. Priya records each test with its date and result, and the tests become the weekly checks.
7.4 Recording results
Tests and results are stored with dates; failures become tickets. Storing results gives auditors and Marcus evidence that controls worked on a given date. When a test fails, a ticket goes to the control's owner with the result and date, so the failure is fixed rather than noted. Two months after the controls were introduced, a build service upgrade reset the registry configuration, and the weekly test failed the next morning. The platform team restored the internal-prefix rule the same day.
7.5 Ongoing checks
The tests run automatically each week, so a configuration change that weakens a control is caught quickly. Configuration can change without anyone intending to weaken a control, for example when a build service upgrade resets settings to defaults. Running the tests automatically each week means such a change is noticed within days. When the registry rule was reset, the test caught it before any build used the default. The platform team receives the results, and Priya reviews them each month.
7.6 SSDF mapping
These controls address SSDF practices for protecting all forms of code and verifying third-party software. The prefix rule, hashes and provenance protect code and builds from tampering, while review notes and the source check support verifying third-party software before it is used. Mapping controls to SSDF practices shows Marcus and auditors which practices Harbourline now follows and where gaps remain. Priya records the mapping in her portfolio, with the evidence for each control. Gaps, such as manual reachability checks, are listed beside the mapped practices.
Rolling out controls
Controls are introduced one at a time with a week's notice to developers, starting with lock-file hash checks in warning mode. Once warnings are cleared, the check becomes blocking, which avoids surprising teams with failed builds.
Worked example
Two months later, a build service upgrade resets the registry configuration to defaults. The weekly test fails the next morning, and the platform team restores the internal-prefix rule the same day, before any build used the default.
Synthetic case. Controls and events are synthetic.
Errors and limits
Provenance shows how a release was built; it does not show the code is free of flaws.
Exercises
- EX031 — Controls. List four controls. Rubric: 3 = prefix rule, hashes, mismatch failure, review notes, pinned actions, tokens, provenance; 2 = three; 1 = one; 0 = none.
- EX032 — SLSA L2. What does SLSA build L2 require? Rubric: 3 = provenance signed by hosted platform; 2 = partial; 1 = vague; 0 = none.
- EX033 — Prefix test. How is the prefix rule tested? Rubric: 3 = fake internal package must not resolve publicly; 2 = partial; 1 = vague; 0 = none.
- EX034 — Upgrade catch. What did the weekly test catch? Rubric: 3 = upgrade reset registry config; 2 = partial; 1 = vague; 0 = none.
- EX035 — Provenance limit. What does provenance not prove? Rubric: 3 = code free of flaws; 2 = partial; 1 = vague; 0 = none.
Synthesis
Controls need tests that keep running.
Continue studying — chapter 07 of 12
← Chapter 06 (draft) · Course chapter index · Chapter 08 (draft) →