From 5257e72396463bfd4e7ef46a38353361dff5d6ee Mon Sep 17 00:00:00 2001 From: vtian <1074025714@qq.com> Date: Tue, 9 Jun 2026 01:11:40 +0800 Subject: [PATCH] improve(pipeline-security): bind artifact integrity evidence --- skills/devsecops/pipeline-security/SKILL.md | 31 ++++++++++++++- .../benign/artifact-verified-before-deploy.md | 39 +++++++++++++++++++ .../artifact-generated-not-enforced.md | 29 ++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 skills/devsecops/pipeline-security/tests/benign/artifact-verified-before-deploy.md create mode 100644 skills/devsecops/pipeline-security/tests/vulnerable/artifact-generated-not-enforced.md diff --git a/skills/devsecops/pipeline-security/SKILL.md b/skills/devsecops/pipeline-security/SKILL.md index 66de2470..c2e7553a 100644 --- a/skills/devsecops/pipeline-security/SKILL.md +++ b/skills/devsecops/pipeline-security/SKILL.md @@ -392,6 +392,8 @@ docker.sock - No SBOM (Software Bill of Materials) generation in the build pipeline. - Downloaded dependencies or tools without checksum verification. - Missing provenance attestation (SLSA provenance, in-toto, Sigstore). +- Signatures, SBOMs, or provenance generated for one artifact while deployment pulls a different mutable tag or unverified package. +- Deployment steps that reference image tags, package names, or release assets without verifying the digest, signing identity, provenance subject, and SBOM subject match the build output. **Grep patterns:** @@ -414,7 +416,23 @@ image: nginx@sha256:abcdef... # GOOD image: nginx:latest # BAD ``` -**Finding format:** Report whether artifacts are signed, whether provenance is generated, whether SBOMs are produced, and whether container images use digest pinning. +**Artifact integrity evidence gate:** Before marking CICD-SEC-9 as passing, capture evidence that the exact artifact deployed is the same artifact that was built, signed, attested, and described by the SBOM. + +| Artifact | Build run | Immutable digest | Signature / attestation | Signing identity | Provenance subject | SBOM subject | Verification command/policy | Deployment reference | Result | +|----------|-----------|------------------|-------------------------|------------------|--------------------|--------------|-----------------------------|---------------------|--------| +| `` | `` | `` | `` | `` | `` | `` | `` | `` | `Pass/Fail/Unknown` | + +**Finding format:** Report whether artifacts are signed, whether provenance is generated, whether SBOMs are produced, whether container images use digest pinning, and whether deployment verifies that the digest, signature, provenance subject, and SBOM subject all refer to the same artifact. + +**Review checklist:** + +- [ ] Build output is recorded with an immutable digest. +- [ ] Signature or attestation verifies against an expected trust root and signing identity. +- [ ] Provenance subject digest matches the build output digest. +- [ ] SBOM subject digest or package URL matches the build output digest. +- [ ] Deployment references the immutable digest, not only a mutable tag such as `latest`, `main`, or a semver tag. +- [ ] A CI verification step, deployment admission policy, or release gate enforces signature/provenance/SBOM verification before deployment. +- [ ] Evidence comes from the same build run and artifact, not from a different branch, rebuild, architecture, or release asset. --- @@ -488,6 +506,7 @@ Produce the final report using the following structure: - **File:** - **Line(s):** - **Description:** +- **Evidence:** - **Remediation:** ### Prioritized Remediation Plan @@ -513,6 +532,16 @@ The final deliverable is a structured assessment report as shown in Step 4 above --- +## Common Pitfalls + +1. **Generated-but-not-enforced attestations.** Producing a provenance file, signature, or SBOM does not protect the deployment if the deploy job never verifies it. +2. **Mutable deployment references.** A pipeline can sign `my-app@sha256:abc...` and still deploy `my-app:latest`, allowing tag drift or registry replacement. +3. **Mixed artifact evidence.** Do not combine a signature from one build, an SBOM from another build, and a deployment reference from a third build when scoring CICD-SEC-9. +4. **Unverified signing identity.** A valid cryptographic signature is incomplete evidence unless the signer identity, issuer, repository, workflow, and branch/ref are expected. +5. **Architecture or platform mismatch.** Multi-arch images and package bundles need per-platform digest evidence; one signed manifest does not automatically prove every deployed platform artifact is verified. + +--- + ## Constraints - Only use the allowed tools: Read, Grep, Glob. diff --git a/skills/devsecops/pipeline-security/tests/benign/artifact-verified-before-deploy.md b/skills/devsecops/pipeline-security/tests/benign/artifact-verified-before-deploy.md new file mode 100644 index 00000000..eced6f1e --- /dev/null +++ b/skills/devsecops/pipeline-security/tests/benign/artifact-verified-before-deploy.md @@ -0,0 +1,39 @@ +# Benign: artifact digest, signature, provenance, SBOM, and deployment are bound + +```yaml +name: release +on: + push: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + outputs: + image_digest: ${{ steps.build.outputs.digest }} + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - id: build + run: | + docker build -t ghcr.io/example/api:${GITHUB_SHA} . + docker push ghcr.io/example/api:${GITHUB_SHA} + echo "digest=sha256:0123456789abcdef" >> "$GITHUB_OUTPUT" + - run: cosign sign --yes ghcr.io/example/api@${{ steps.build.outputs.digest }} + - run: syft ghcr.io/example/api@${{ steps.build.outputs.digest }} -o spdx-json > sbom.json + - uses: actions/attest-build-provenance@3d6433db5e00a34f33760f318dc53946bca6da92 + with: + subject-name: ghcr.io/example/api + subject-digest: ${{ steps.build.outputs.digest }} + + deploy: + runs-on: ubuntu-latest + needs: build + steps: + - run: cosign verify ghcr.io/example/api@${{ needs.build.outputs.image_digest }} --certificate-identity-regexp '^https://github.com/example/api/' + - run: kubectl set image deploy/api api=ghcr.io/example/api@${{ needs.build.outputs.image_digest }} +``` + +Expected skill behavior: + +- Do not flag CICD-SEC-9 merely because the pipeline generates artifacts. +- Treat as passing evidence when the same immutable digest is signed, used as the provenance subject, described by the SBOM, verified, and deployed by digest. diff --git a/skills/devsecops/pipeline-security/tests/vulnerable/artifact-generated-not-enforced.md b/skills/devsecops/pipeline-security/tests/vulnerable/artifact-generated-not-enforced.md new file mode 100644 index 00000000..4cace14b --- /dev/null +++ b/skills/devsecops/pipeline-security/tests/vulnerable/artifact-generated-not-enforced.md @@ -0,0 +1,29 @@ +# Vulnerable: artifact evidence generated but deployment uses mutable tag + +```yaml +name: release +on: + push: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - run: docker build -t ghcr.io/example/api:${{ github.sha }} . + - run: docker push ghcr.io/example/api:${{ github.sha }} + - run: cosign sign --yes ghcr.io/example/api:${{ github.sha }} + - run: syft ghcr.io/example/api:${{ github.sha }} -o spdx-json > sbom.json + + deploy: + runs-on: ubuntu-latest + needs: build + steps: + - run: kubectl set image deploy/api api=ghcr.io/example/api:latest +``` + +Expected skill behavior: + +- Flag CICD-SEC-9 because signature and SBOM evidence are generated for one tag while deployment uses a mutable `latest` reference. +- Require immutable digest evidence and a verification step or admission policy before deployment.