Introduction

Supply Chain Security

Software supply chain attacks target the processes and tools used to build, package, and distribute software. High-profile incidents like SolarWinds and Codecov demonstrated that compromising a single trusted vendor can cascade into thousands of downstream victims. Defending the supply chain requires verifiable integrity, provenance, and policy enforcement at every stage.

Software Bill of Materials (SBOM)

An SBOM is a machine-readable inventory of all components in a software artifact. It enables consumers to quickly identify exposure when a vulnerability is disclosed.

{

"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",

"bomFormat": "CycloneDX",

"specVersion": "1.5",

"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",

"version": 1,

"metadata": {

"component": {

"name": "my-application",

"version": "1.2.3",

"type": "application",

"supplier": {

"name": "ACME Corp"

}

}

},

"components": [

{

"type": "library",

"name": "lodash",

"version": "4.17.21",

"purl": "pkg:npm/lodash@4.17.21",

"licenses": [{"license": {"id": "MIT"}}]

},

{

"type": "library",

"name": "express",

"version": "4.18.2",

"purl": "pkg:npm/express@4.18.2"

}

],

"vulnerabilities": []

}

Generate SPDX SBOM with syft

syft packages ./myapp:latest -o spdx-json > sbom.spdx.json

Generate CycloneDX SBOM

cyclonedx-bom -o bom.xml -t file

Compare SBOMs for change detection

diff <(jq '.components[].purl' bom-v1.json | sort) \

<(jq '.components[].purl' bom-v2.json | sort)

Sigstore and Artifact Signing

Sigstore simplifies code signing and verification through ephemeral key material and transparency logs.

Sign a container image with cosign

cosign sign --key gcpkms://projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key/my-version \

myregistry.io/myapp:latest

Keyless signing (OIDC-based)

cosign sign myregistry.io/myapp:latest

Verify a signed image

cosign verify --key pubkey.pem myregistry.io/myapp:latest

Verify keyless signature

cosign verify myregistry.io/myapp:latest

Cosign keyless verification policy

cosign_policy:

identity:

subject: "developer@acme.com"

issuer: "https://accounts.google.com"

signatures:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- hash: "sha256:abc123..."

bundle: "sigstore-bundle.json"

Generating provenance with SLSA

Generate SLSA provenance for a build

gitsign --sign-commits HEAD

Attest provenance

cosign attest --predicate slsa-provenance.json --type slsa.dev/provenance/v1 \

myregistry.io/myapp:latest

in-toto: Framework for Supply Chain Integrity

in-toto defines a framework to protect the integrity of the software supply chain by verifying that each step in the build and release pipeline was performed by authorized actors.

in-toto layout definition

layout = Layout(

keys={

'developer': load_key('developer.pub'),

'builder': load_key('builder.pub'),

'tester': load_key('tester.pub'),

},

steps=[

Step(name='write-code',

materials=[MaterialRule('ALLOW', '*')],

products=[ProductRule('ALLOW', 'src/**')],

pubkeys=['developer']),

Step(name='build',

materials=[MaterialRule('MATCH', 'src/**', ['write-code'])],

products=[ProductRule('ALLOW', 'build/**')],

pubkeys=['builder']),

Step(name='test',

materials=[MaterialRule('MATCH', 'build/**', ['build'])],

products=[ProductRule('ALLOW', '*')],

pubkeys=['tester']),

Inspection(name='verify-signature',

expected_command=['gpg', '--verify', 'build/signed-artifact'])

]

)

Dependency Confusion

Dependency confusion attacks exploit package manager behaviors where internal package names are also available in public registries. If a package manager prefers higher version numbers or public registries over private ones, attackers can publish malicious packages with the same name.

Detect potential dependency confusion

import requests

def check_dependency_confusion(requirements_file):

vulnerable = []

with open(requirements_file) as f:

for line in f:

if '==' not in line:

continue

pkg_name = line.split('=')[0].strip().lower()

Check if package exists on PyPI

resp = requests.get(f"https://pypi.org/pypi/{pkg_name}/json")

if resp.status_code == 200:

vulnerable.append({

'package': pkg_name,

'risk': 'Package exists on public registry',

'mitigation': 'Scope pip to private index with --index-url'

})

return vulnerable

SLSA Framework

Supply-chain Levels for Software Artifacts (SLSA, pronounced "salsa") provides a security framework with four levels of increasing trust.

slsa_levels:

level_1:

description: "Build process must be scripted and automated"

requirements:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- provenance_exists: true

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- provenance_authentic: false

level_2:

description: "Build service generates and signs provenance"

requirements:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- provenance_authentic: true

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- provenance_generated_by_build_service: true

level_3:

description: "Hardened build service resists tampering"

requirements:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- build_service_hardened: true

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- provenance_non_falsifiable: true

level_4:

description: "Two-party review and hermetic builds"

requirements:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- build_hermetic: true

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- provenance_has_reproducible_info: true

Conclusion

Supply chain security is no longer optional. Generate SBOMs for all artifacts, sign them with Sigstore, define in-toto layouts for pipeline integrity, protect against dependency confusion with scoped registries, and target SLSA Level 3+ for critical builds. Build verification into your deployment pipeline so that unsigned or unverified artifacts are automatically rejected.