◇ OpenCyber Academy
Engineering · Chapter 27 · English

Chapter 27 — Application and software supply chain security: control design

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Chapter 27 — Application and software supply chain security: control design

Lesson map

Lesson 27 published. Map, example, EX079.

flowchart TD
  N0["Learning outcomes"]
  N1["27.1 Source controls"]
  N2["27.2 Dependency controls"]
  N3["27.3 Build controls"]
  N4["27.4 Deployment controls"]
  N5["27.5 Failure behaviour"]
  N6["27.6 Exceptions"]
  N7["Policy testing"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Worked example"]
  EX --> Q["Exercise EX079"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["27.1 Source controls"]
  N2["27.2 Dependency controls"]
  N3["27.3 Build controls"]
  N4["27.4 Deployment controls"]
  N5["27.5 Failure behaviour"]
  N6["27.6 Exceptions"]
  N7["Policy testing"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX079"]
[Learning outcomes]
    |
    v
[27.1 Source controls]
    |
    v
[27.2 Dependency controls]
    |
    v
[27.3 Build controls]
    |
    v
[27.4 Deployment controls]
    |
    v
[27.5 Failure behaviour]
    |
    v
[27.6 Exceptions]
    |
    v
[Policy testing]
    |
    v
[Worked example] --> [Exercise EX079]

Learning outcomes

You will (1) design specific controls for source, dependencies, build and deployment; (2) define policies as code; (3) specify failure behaviour of controls; (4) plan exceptions.

27.1 Source controls

Branch protection requires review by one engineer and passing checks; signed commits for release branches; no direct pushes to main.

Review by one engineer prevents a single person from changing ticket-web alone. Passing checks ensures tests and the dependency gate ran. Signed commits on release branches tie each change to a verified author, so a stolen password alone cannot inject code. Blocking direct pushes means every change goes through the same path, including those from senior engineers and administrators, who could otherwise skip review in a hurry. The repository settings that enforce these rules are themselves protected, so changing them needs approval from two administrators.

27.2 Dependency controls

The CI dependency gate fails a build if: a lockfile hash does not match, a new name is within edit distance 1 of a popular name without an approved review, or a critical advisory applies without an exception.

Each condition corresponds to an earlier finding: hash mismatches to the mirror incident, lookalike names to the name-similarity lab and critical advisories to the tmpl case. The approved-review clause matters, because some legitimate packages have names close to popular ones; a reviewer can approve them once, and the gate then remembers the decision. Messages name the failing rule so developers can fix the cause quickly.

27.3 Build controls

Builds run on hosted runners with pinned tool versions; production secrets are not available to builds from forks; the platform generates provenance.

Pinned tool versions mean a build uses exactly the compiler and packaging tools the team tested, not whatever was latest that morning. Keeping secrets away from fork builds closes the threat ranked highest in the threat analysis. Platform-generated provenance records the builder, source and inputs in a way the build steps cannot alter, which the deployment policy then checks. Tool versions are updated deliberately in reviewed changes, so a new compiler is never introduced silently.

27.4 Deployment controls

The deploy policy allows an artifact only if built by the approved builder from the approved repository from reviewed commits, with a valid signature and matching digest. Policies are written as code, version-controlled and reviewed like application code.

Writing policy as code means a change to the rules is visible in a pull request, with a reviewer and history. Each condition in the policy maps to evidence produced earlier: the provenance names the builder and repository, branch protection records the review, and the signing log holds the signature. If any piece is missing, the artifact is refused, even when everything else looks correct.

27.5 Failure behaviour

Controls fail closed: if the advisory service is unreachable, the build waits and retries rather than skipping the check; after one hour, the on-call engineer is paged.

Failing open would mean an outage of the advisory service silently disables the check, which an attacker could exploit by causing the outage. Failing closed costs availability: releases wait until the service returns. Paging after an hour keeps that delay short. For a true emergency, the exception process allows a release with a recorded approval, so failing closed does not trap the team indefinitely.

27.6 Exceptions

Exceptions need an owner, a reason, an expiry date and approval by Ingrid. Expired exceptions block builds again.

An exception without an expiry tends to become permanent and forgotten. The owner is responsible for removing the cause before expiry or requesting renewal with a new reason. Requiring Ingrid's approval keeps exceptions visible to someone accountable for overall risk. A weekly list of active exceptions shows the trend; a rising count suggests a control is too strict or a team needs help. Each exception records exactly which check it suspends and for which component, so it cannot be stretched to cover other problems.

Policy testing

Policies are code, so they have tests: for each rule, a synthetic input that should pass and one that should fail. A change to the deploy policy that accidentally allowed any builder would fail the test suite before review.

Worked example

In the first week, the dependency gate blocks 6 builds: 4 for a critical advisory in a test-only library (exception granted for 14 days because it never ships), 1 for a lookalike name (a typo, corrected) and 1 for a hash mismatch caused by a developer editing the lockfile by hand.

Synthetic case. Policies and events are synthetic.

Errors and limits

Strict controls create pressure for exceptions; track the exception count as a health signal.

Exercises

Synthesis

Write controls as reviewed policy, make them fail closed and govern exceptions.

Continue studying — chapter 27 of 50

← Chapter 26 (draft) · Course chapter index · Chapter 28 (draft) →