Start with the decision object
A release is a decision about a particular object and context. In the fictional example, the requirement calls for org/ledger at commit C9, mandatory tests completed successfully and origin evidence that job steps cannot alter. The work table starts with the received artifact’s digest, approved origin and commit, identified build and acceptance criteria. Then bind each piece of evidence to the same object. A C8 test does not become a C9 test because the command is unchanged; a signature for the wrong file does not answer the question. If a binding is missing, report insufficient evidence for the criterion without inventing that the artifact is vulnerable or that somebody falsified the record.
Signature, authorized identity and expectations
A verifier can confirm a signature and digest while still accepting an unapproved producer. For payroll-core, the exercise allows only org/payroll. A valid statement from org/demo identifies a different origin; belonging to the same administrative organization does not satisfy the criterion. Separate authenticity, artifact matching and comparison with controlled expectations. Also identify who can change those expectations and with what approval. Otherwise, an artifact producer may simultaneously change the rule accepting it. The report should show the requirement and observed value instead of compressing all these conditions into one “signature OK” state. Trust assigned to the platform still needs a basis.
Inventory is distinct from vulnerability analysis
A signed application SBOM may identify archive libraries while omitting the base image used in the release. Signing does not add absent components. Before accepting a conclusion about the executable image, confirm the inventoried object and include relevant base components. Then connect vulnerability analysis to that inventory, its versions and the analysis time. Even an adequate inventory is not itself a scanner result. In a project review, request a demonstration with a synthetic image containing distinct application and base components. The learner should explain which evidence identifies components, which evidence assesses known exposure and which limitations prevent an absolute guarantee that vulnerabilities are absent.
Pin a dependency without forgetting subsequent ones
The workflow references an action by full commit, but that action downloads helper/latest.sh. The outer reference is fixed; bytes supplied by the next dependency may change. Draw the resolution chain through executed components and look for the immutable identity matching the reviewed version. A valid TLS certificate authenticates a channel but does not demonstrate that today’s response is the approved tool. In a safe exercise, use two local files with the same logical name and different contents. Calculate their digests and show that repeating the caller’s identifier does not detect the called file’s change. Define where the implementation should check that binding before executing the tool.
Choose a dependency within the window
A reviewed tool identity is only one criterion. In migration planning, connect version to the consumed format, tests of the particular artifact and the available window. If H1 produces still-required F1 while H2 produces F2 accepted only later, pinning H2 does not establish compatibility. Add sequential stages: 35 build minutes and 20 test minutes fit within 90; adding 80 adaptation minutes does not. Reusing another commit’s test result differs from reusing a tool whose digest was checked. These times and formats are training premises.
Field origin and external parameters
Protecting a signing key does not prevent a job from supplying false statements if the service signs received JSON without validating fields. The fictional requirement says origin and command must be observed by the control plane; test who actually determines those values. Separately, a verifier that compares mode=release but ignores disable_checks=true leaves an external influence without an acceptance decision. Enumerating parameters and assessing their values are distinct operations. Define permitted values and explicit handling of unknown parameters. When using SLSA 1.2, read field exceptions and each level’s scope: do not automatically transfer externalParameters requirements to resolvedDependencies or interpret a signature as a guarantee of every declared fact.
Migrate expectations without creating a gap
The same release label can have different semantics across buildType versions. Define version-specific expectations before emitting artifacts of the new version. Retaining an authorized previous version does not require ignoring new parameters; rejecting every extra field can also break inputs already analyzed as safe. Distinguish value type, behavior activated by its value and handling of unknown parameters. Test both legitimate paths, the option that skips controls and an unrecognized field. A scheduling parameter warrants less restrictive handling only after its effect is analyzed; the signature does not perform that analysis.
Caches and disks can connect separate jobs
In the fictional pipeline, an external pull-request job writes to a cache consumed by the release. Signing output afterwards does not remove that input’s influence. With authorization, replace only harmless data in an isolated fixture and observe whether release output changes; compare with an independent cache. Also distinguish runner registration from the mounted disk’s lifetime. Removing a registration after one job does not erase files reused by the next. An isolation conclusion should follow persistent resources. A reproducible result with the same cache may merely reproduce the same influence. This lesson’s lab uses local bytes and rules: it is not an isolation test of GitHub, containers or a cloud platform.
Find paths bypassing review
The normal workflow uses the prod environment, which requires review before releasing its secrets. A maintenance workflow does not reference that environment and uses a repository-level credential. To assess “all deliveries receive review”, follow the second credential to its permitted operation and look for an equivalent mandatory gate. More samples from the normal workflow do not automatically cover maintenance. If the alternative operation is necessary, the accountable owner can design appropriate approval for that path; audit assesses alignment with the requirement and demonstrated effectiveness. Also record emergency paths and authorized exception decisions. Identical secret names do not establish identical scope or protection.
Retain an authorized recovery path
A credential held outside a gate may retain an alternative path even after one workflow references prod. When full migration cannot fit a recovery window, assess a bounded path that applies already-issued approval to the digest and destination actually used. Custody outside the job, expiry and one-time consumption address different properties. Test legitimate operations and requests with wrong digest, destination, validity or reuse. Audit communicates scope and limits; the responsible authority still decides. The broker and window are exercise constructions, not universal GitHub or IAM features. In the exercise, the shared credential remains valid until revoked; deleting the repository secret does not invalidate earlier copies. The 13 minutes include revocation, a replacement broker credential and testing. Confirm rejection of the old credential and continuity of the normal flow, which has its own credential.
Keep data outside code interpretation
A change-ticket webhook supplies maintenance_window, an operator-editable label that a job inserts into shell text to select a maintenance window. There are two conditions: the value must remain data and identify an approved window. Passing it as an argument or variable to a parser without eval addresses the first; comparing it with a controlled list of windows addresses the second. Quoting and later use of the value still matter. Prepare one permitted label, an unknown label and harmless inputs containing spaces and quotes. Confirm data interpretation and the authorization decision. A safely handled input may still represent an unauthorized window. The test uses synthetic data and performs no deployments.
Missing execution and error are not success
The fictional scanner returns CLEAN, FINDINGS or ERROR. Internal policy requires CLEAN; an implementation blocking only FINDINGS lets ERROR through even though analysis did not finish. A discriminating test includes all three states and preserves distinct blocking reasons. Another gate computes SUCCESS from executed jobs and ignores SKIPPED. If a mandatory test was SKIPPED because of a branch condition, aggregate status does not demonstrate compliance. Require presence, completed execution and an acceptable result for the mandatory test on the artifact under decision. A test file in the repository shows that a procedure exists; it does not show that it was applied to the release. These states belong to the fictional orchestrator and do not universally describe all CI products.
Re-evaluate results when criteria change
In this second exercise, policy decides from finding severity in a complete report against a defined threshold. A changed decision rule does not automatically invalidate all earlier observations. If complete data remain bound to the same artifact, detector and scale are unchanged, and policy permits reuse, a new threshold may be applied with an explicit record. A finding of 8 that passed a threshold of 9 no longer passes 7; a maximum of 6 may still pass. If the detector added checks, an earlier CLEAN does not cover that new population, and ERROR does not fill it. Separate confirmed findings, incomplete analysis and promotion decisions. Allocate scarce tests to missing evidence, including subsequent decision time. Scales, validity and reuse rules are local premises, not SLSA-prescribed criteria.
Guided case: combine conditions in a new build
B1 uses C9 and has PASS tests, but the signer accepts job-written origin fields without comparing them with execution, and its cache is shared with external pull requests. B2 observes origin outside the job and has PASS tests but produced C8. Neither set establishes all criteria for C9. Because there is time and capacity for a new B2 execution with C9 and isolated cache, recommend that execution and collection of new results bound to the new artifact. Do not transfer C8 tests or combine B2 provenance with B1 tests. Then present the release authority with observed criteria and remaining limitations. The final decision remains with that authority. The audit recommendation seeks adequate evidence; it does not approve the future result in advance.
Use an assurance level within its scope
An exercise contract requires a complete inventory of everything fetched during the build. The supplier presents SLSA Build L3. The consulted specification keeps resolvedDependencies completeness on a best-effort basis even at that level; the contractual requirement needs additional evidence. This does not make demonstrated properties useless. Create a matrix containing the contractual requirement, property supported by the framework, evidence examined and remaining work. Also distinguish isolation from hermeticity: do not automatically convert the level into a claim of no network access. Use proportionate report wording, for example “the examined evidence supports the declared origin within this scope; contractual inventory completeness has not yet been established”.
Local practice: follow bytes, inputs and executions
After extracting the ZIP, read README.md and run the commands below from the extracted directory. Each execution creates a new directory and preserves the earlier one. First predict which of the 15 scenarios meet the fictional contract. Inspect each scenario’s observed-build.json, actual-jobs.json, submitted-jobs.json and gate-result.json. C8 passes both functional examples but fails the authorized-revision criterion; stale-C8-tests has no new tests; wrong-input-same-total returns 1000 using data different from the required input. In the shared cache, a harmless tool actually changes the artifact marker while business totals remain correct. Explain each hold using its criterion and observed bytes. SHA-256 compares local files; the JSON records are unsigned and processes use the same user. This exercise does not establish vendor isolation, protected identity or production readiness.
Exercise files
exercises with code and synthetic data. Requires Python 3.9 or later; no Docker, Internet or cloud account is needed.
# Run from the extracted lab directory.
python3 run.py --output./my-run-1
python3 run.py --output./my-run-2
python3 test_lab.py --run-a./my-run-1 --run-b./my-run-2Compare B1, B2 and proposed B3 in a matrix: commit, digest, mandatory tests, field origin and cache influence. Explain why every column must concern the same execution.
Common pitfalls
Valid signature as authorized producer; SBOM as scanner; pinned commit as all dependencies pinned; environment secrets as protection for every workflow; SUCCESS as proof of mandatory execution; SLSA level as automatic contractual compliance.
Related topics: Tracing artifacts and approvals · Re-execution and provenance · Version-specific retesting
Assess the whole chain: criterion, artifact, statement origin, test execution and authorized decision. Each missing binding limits the conclusion the evidence supports.
References
- Build: Verifying artifacts · SLSA specification v1.2, approved Build verification guidance
- CISA Exam Content Outline · Current public CISA outline; effective August 1, 2024 edition confirmed against official announcement
- Artifact attestations · GitHub Actions current web documentation consulted 2026-10-08; overview still describes its SLSA v1.0 level framing
- Secure use reference · GitHub Actions current web documentation consulted 2026-10-08
- Build: Provenance · SLSA specification v1.2; build provenance predicate URI remains https://slsa.dev/provenance/v1
- Build: Requirements for producing artifacts · SLSA specification v1.2, approved Build track requirements
- Deployments and environments · GitHub Actions current web documentation consulted 2026-10-08