supply-chain-security

Supply Chain Security

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "supply-chain-security" with this command: npx skills add melodic-software/claude-code-plugins/melodic-software-claude-code-plugins-supply-chain-security

Supply Chain Security

Comprehensive guidance for securing the software supply chain, including dependency management, SBOM generation, vulnerability scanning, and protection against supply chain attacks.

When to Use This Skill

  • Generating Software Bill of Materials (SBOM)

  • Implementing SLSA framework compliance

  • Setting up dependency vulnerability scanning

  • Protecting against dependency confusion attacks

  • Configuring lock files and integrity verification

  • Implementing code signing with Sigstore

  • Verifying software provenance

  • Evaluating project security with OpenSSF Scorecard

Quick Reference

Supply Chain Attack Types

Attack Type Description Prevention

Dependency Confusion Attacker publishes malicious package with internal package name Namespace scoping, private registries

Typosquatting Malicious packages with similar names (lodash vs 1odash ) Lockfiles, careful review, tools

Compromised Maintainer Legitimate package hijacked Pin versions, verify signatures

Build System Attack CI/CD pipeline compromised SLSA compliance, hermetic builds

Malicious Dependency New dependency contains malware SCA scanning, SBOM review

SLSA Levels Quick Reference

Level Requirements Protection

SLSA 1 Documentation of build process Basic transparency

SLSA 2 Authenticated provenance, hosted build Tampering after build

SLSA 3 Hardened build platform, non-falsifiable provenance Tampering during build

SLSA 4 Two-person review, hermetic builds Insider threats

Essential Tools by Ecosystem

Ecosystem Vulnerability Scanning Lock File SBOM Generation

npm/Node.js npm audit , Snyk package-lock.json

@cyclonedx/cyclonedx-npm

Python pip-audit , Safety requirements.txt

  • hashes, poetry.lock

cyclonedx-python

Go govulncheck , Snyk go.sum

cyclonedx-gomod

.NET dotnet list package --vulnerable

packages.lock.json

CycloneDX NuGet

Java/Maven OWASP Dependency-Check pom.xml with versions cyclonedx-maven-plugin

Rust cargo audit

Cargo.lock

cargo-cyclonedx

SBOM (Software Bill of Materials)

SBOM Formats

Format Standard Best For

CycloneDX OASIS Security-focused, VEX support

SPDX Linux Foundation License compliance, legal

SWID ISO/IEC 19770-2 Software asset management

CycloneDX SBOM Generation

Node.js:

Install CycloneDX CLI

npm install -g @cyclonedx/cyclonedx-npm

Generate SBOM

cyclonedx-npm --output-file sbom.json cyclonedx-npm --output-file sbom.xml --output-format xml

Python:

Install CycloneDX

pip install cyclonedx-bom

Generate from requirements.txt

cyclonedx-py requirements -i requirements.txt -o sbom.json --format json

Generate from Poetry

cyclonedx-py poetry -o sbom.json --format json

Generate from pip environment

cyclonedx-py environment -o sbom.json

.NET:

Install CycloneDX tool

dotnet tool install --global CycloneDX

Generate SBOM

dotnet CycloneDX myproject.csproj -o sbom.json -j

Go:

Install cyclonedx-gomod

go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@latest

Generate SBOM

cyclonedx-gomod mod -json -output sbom.json

SBOM in CI/CD

GitHub Actions - Generate and upload SBOM

name: Generate SBOM on: release: types: [published]

jobs: sbom: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5

  - name: Generate SBOM
    uses: CycloneDX/gh-node-module-generatebom@v1
    with:
      output: sbom.json

  - name: Upload SBOM to release
    uses: actions/upload-release-asset@v1
    with:
      upload_url: ${{ github.event.release.upload_url }}
      asset_path: sbom.json
      asset_name: sbom.json
      asset_content_type: application/json

  - name: Submit to Dependency Track
    run: |
      curl -X POST \
        -H "X-Api-Key: ${{ secrets.DTRACK_API_KEY }}" \
        -H "Content-Type: multipart/form-data" \
        -F "project=${{ github.repository }}" \
        -F "bom=@sbom.json" \
        "${{ secrets.DTRACK_URL }}/api/v1/bom"

Vulnerability Scanning

npm/Node.js

Built-in audit

npm audit npm audit --json > audit-results.json npm audit fix # Auto-fix where possible

Check for outdated packages

npm outdated

Use better-npm-audit for CI

npx better-npm-audit audit --level moderate

Python

pip-audit (recommended)

pip install pip-audit pip-audit pip-audit --fix # Auto-fix pip-audit -r requirements.txt pip-audit --format json > audit.json

Safety (alternative)

pip install safety safety check safety check -r requirements.txt

.NET

Built-in vulnerability check

dotnet list package --vulnerable dotnet list package --vulnerable --include-transitive

Output as JSON for CI

dotnet list package --vulnerable --format json > vulnerabilities.json

Go

govulncheck (official Go tool)

go install golang.org/x/vuln/cmd/govulncheck@latest govulncheck ./... govulncheck -json ./... > vuln.json

Rust

cargo-audit

cargo install cargo-audit cargo audit cargo audit --json > audit.json cargo audit fix # Auto-fix (with cargo-audit-fix)

Lock Files and Integrity

Lock File Best Practices

using System.Security.Cryptography; using System.Text.Json; using System.Text.Json.Serialization;

/// <summary> /// Lock file verification utilities for supply chain security. /// </summary> public static class LockFileVerification { /// <summary> /// Verify npm package-lock.json integrity hashes. /// </summary> public static Dictionary<string, PackageIntegrityResult> VerifyNpmIntegrity(string packageLockPath) { var json = File.ReadAllText(packageLockPath); var lockData = JsonSerializer.Deserialize<NpmPackageLock>(json)!;

    var results = new Dictionary&#x3C;string, PackageIntegrityResult>();

    foreach (var (name, info) in lockData.Packages ?? new())
    {
        if (string.IsNullOrEmpty(name)) continue;  // Root package

        if (!string.IsNullOrEmpty(info.Integrity))
        {
            var parts = info.Integrity.Split('-', 2);
            results[name] = new PackageIntegrityResult(
                HasIntegrity: true,
                Algorithm: parts[0]);
        }
        else
        {
            results[name] = new PackageIntegrityResult(HasIntegrity: false, Algorithm: null);
        }
    }

    return results;
}

/// &#x3C;summary>
/// Verify NuGet packages.lock.json integrity.
/// &#x3C;/summary>
public static Dictionary&#x3C;string, PackageIntegrityResult> VerifyNuGetLockFile(string lockFilePath)
{
    var json = File.ReadAllText(lockFilePath);
    var lockData = JsonSerializer.Deserialize&#x3C;NuGetPackagesLock>(json)!;

    var results = new Dictionary&#x3C;string, PackageIntegrityResult>();

    foreach (var (framework, dependencies) in lockData.Dependencies ?? new())
    {
        foreach (var (packageName, info) in dependencies)
        {
            var key = $"{packageName}@{info.Resolved}";
            results[key] = new PackageIntegrityResult(
                HasIntegrity: !string.IsNullOrEmpty(info.ContentHash),
                Algorithm: !string.IsNullOrEmpty(info.ContentHash) ? "SHA512" : null);
        }
    }

    return results;
}

}

public sealed record PackageIntegrityResult(bool HasIntegrity, string? Algorithm);

public sealed record NpmPackageLock( [property: JsonPropertyName("packages")] Dictionary<string, NpmPackageInfo>? Packages);

public sealed record NpmPackageInfo( [property: JsonPropertyName("integrity")] string? Integrity);

public sealed record NuGetPackagesLock( [property: JsonPropertyName("dependencies")] Dictionary<string, Dictionary<string, NuGetDependencyInfo>>? Dependencies);

public sealed record NuGetDependencyInfo( [property: JsonPropertyName("resolved")] string? Resolved, [property: JsonPropertyName("contentHash")] string? ContentHash);

pip with Hash Verification

requirements.txt with hashes (most secure)

requests==2.31.0
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1

certifi==2024.2.2
--hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1
--hash=sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8

Generate Hashes Automatically

pip-tools for hash generation

pip install pip-tools

Generate requirements with hashes

pip-compile --generate-hashes requirements.in -o requirements.txt

Poetry with hash export

poetry export --format requirements.txt --with-hashes > requirements.txt

Dependency Confusion Prevention

Private Registry Configuration

npm (.npmrc):

Scope packages to private registry

@mycompany:registry=https://npm.mycompany.com/ //npm.mycompany.com/:_authToken=${NPM_TOKEN}

Always use exact versions

save-exact=true

Python (pip.conf):

[global] index-url = https://pypi.mycompany.com/simple/ extra-index-url = https://pypi.org/simple/ trusted-host = pypi.mycompany.com

[install]

Prefer private packages

prefer-binary = true

Preventive Measures:

using System.Net.Http.Json; using System.Text.Json.Serialization;

/// <summary> /// Dependency confusion detection and prevention utilities. /// </summary> public sealed class DependencyConfusionChecker(HttpClient httpClient) { /// <summary> /// Check if internal NuGet package names exist on nuget.org. /// </summary> public async Task<Dictionary<string, ConfusionCheckResult>> CheckNuGetConfusionAsync( IEnumerable<string> internalPackages, CancellationToken cancellationToken = default) { var results = new Dictionary<string, ConfusionCheckResult>();

    foreach (var package in internalPackages)
    {
        try
        {
            var response = await httpClient.GetAsync(
                $"https://api.nuget.org/v3/registration5-semver1/{package.ToLowerInvariant()}/index.json",
                cancellationToken);

            if (response.IsSuccessStatusCode)
            {
                var registration = await response.Content.ReadFromJsonAsync&#x3C;NuGetRegistration>(
                    cancellationToken: cancellationToken);

                var latestVersion = registration?.Items?.LastOrDefault()?.Upper;

                results[package] = new ConfusionCheckResult(
                    ExistsPublicly: true,
                    PublicVersion: latestVersion,
                    Risk: ConfusionRisk.High,
                    Recommendation: "Register placeholder on nuget.org or use package prefix reservation");
            }
            else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                results[package] = new ConfusionCheckResult(
                    ExistsPublicly: false,
                    PublicVersion: null,
                    Risk: ConfusionRisk.Low,
                    Recommendation: "Consider registering placeholder package");
            }
        }
        catch (Exception ex)
        {
            results[package] = new ConfusionCheckResult(
                ExistsPublicly: false,
                PublicVersion: null,
                Risk: ConfusionRisk.Unknown,
                Recommendation: $"Check failed: {ex.Message}");
        }
    }

    return results;
}

/// &#x3C;summary>
/// Generate placeholder .csproj for NuGet package reservation.
/// &#x3C;/summary>
public static string GeneratePlaceholderProject(
    string packageId,
    string description = "Internal package - not for public use")
{
    return $"""
        &#x3C;Project Sdk="Microsoft.NET.Sdk">
          &#x3C;PropertyGroup>
            &#x3C;TargetFramework>netstandard2.0&#x3C;/TargetFramework>
            &#x3C;PackageId>{packageId}&#x3C;/PackageId>
            &#x3C;Version>0.0.1&#x3C;/Version>
            &#x3C;Description>{description}&#x3C;/Description>
            &#x3C;Authors>Security Team&#x3C;/Authors>
            &#x3C;PackageTags>placeholder;internal;reserved&#x3C;/PackageTags>
            &#x3C;IncludeSymbols>false&#x3C;/IncludeSymbols>
            &#x3C;IncludeSource>false&#x3C;/IncludeSource>
          &#x3C;/PropertyGroup>
        &#x3C;/Project>
        """;
}

}

public sealed record ConfusionCheckResult( bool ExistsPublicly, string? PublicVersion, ConfusionRisk Risk, string Recommendation);

public enum ConfusionRisk { Low, Medium, High, Unknown }

public sealed record NuGetRegistration( [property: JsonPropertyName("items")] List<NuGetCatalogPage>? Items);

public sealed record NuGetCatalogPage( [property: JsonPropertyName("upper")] string? Upper);

Code Signing with Sigstore

Sigstore Overview

Sigstore provides keyless signing using OIDC identity:

Install cosign

macOS

brew install cosign

Linux

curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64" chmod +x cosign-linux-amd64 sudo mv cosign-linux-amd64 /usr/local/bin/cosign

Sign Container Images

Sign with keyless (OIDC)

cosign sign ghcr.io/myorg/myimage:v1.0.0

Sign with key

cosign generate-key-pair cosign sign --key cosign.key ghcr.io/myorg/myimage:v1.0.0

Verify signature

cosign verify ghcr.io/myorg/myimage:v1.0.0
--certificate-identity=ci@myorg.com
--certificate-oidc-issuer=https://github.com/login/oauth

Sign Python Packages

Install sigstore

pip install sigstore

Sign a package

python -m sigstore sign dist/mypackage-1.0.0.tar.gz

Verify signature

python -m sigstore verify identity
--cert-identity ci@myorg.com
--cert-oidc-issuer https://github.com/login/oauth
dist/mypackage-1.0.0.tar.gz

Sign npm Packages

npm provenance (built-in since npm 9.5.0)

npm publish --provenance

Verify provenance

npm audit signatures

OpenSSF Scorecard

Running Scorecard

Install scorecard

macOS

brew install scorecard

Run on GitHub repo

scorecard --repo=github.com/myorg/myproject

Run with specific checks

scorecard --repo=github.com/myorg/myproject
--checks=Vulnerabilities,Dependency-Update-Tool,Pinned-Dependencies

Output as JSON

scorecard --repo=github.com/myorg/myproject --format=json > scorecard.json

GitHub Action for Scorecard

name: Scorecard Analysis on: push: branches: [main] schedule: - cron: '0 6 * * 1' # Weekly on Monday

permissions: security-events: write id-token: write contents: read actions: read

jobs: analysis: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5

  - name: Run Scorecard
    uses: ossf/scorecard-action@v2
    with:
      results_file: results.sarif
      results_format: sarif
      publish_results: true

  - name: Upload to Security tab
    uses: github/codeql-action/upload-sarif@v3
    with:
      sarif_file: results.sarif

Scorecard Checks Explained

Check What It Measures How to Improve

Vulnerabilities Known vulnerabilities in dependencies Enable Dependabot, fix vulns

Dependency-Update-Tool Automated dependency updates Enable Dependabot/Renovate

Pinned-Dependencies CI uses pinned dependencies Pin action versions, use hashes

Token-Permissions Minimal CI token permissions Use least-privilege tokens

Branch-Protection Main branch protection Require reviews, status checks

Code-Review PRs require review Enable required reviews

Signed-Releases Releases are signed Use Sigstore/GPG signing

Binary-Artifacts Repo contains binaries Remove binaries, use releases

Security Checklist

Pre-Release Checklist

  • Generate SBOM for release

  • Run vulnerability scan (npm audit, pip-audit, etc.)

  • Verify all dependencies have lock file entries

  • Check for dependency confusion risks

  • Sign release artifacts with Sigstore

  • Run OpenSSF Scorecard

  • Verify provenance generation is enabled

Repository Security

  • Enable Dependabot or Renovate

  • Configure branch protection rules

  • Pin CI/CD action versions with hashes

  • Use minimal token permissions

  • Enable secret scanning

  • Configure code owners for security files

Dependency Management

  • Use lock files in all projects

  • Enable integrity hash verification

  • Configure private registry for internal packages

  • Register placeholder packages on public registries

  • Review new dependencies before adding

  • Monitor for typosquatting attempts

References

  • SBOM Generation: See references/sbom-generation.md for advanced SBOM workflows

  • SLSA Framework: See references/slsa-levels.md for implementation guidance

  • Attack Prevention: See references/dependency-attacks.md for detailed attack patterns

Related Skills

  • secure-coding

  • Secure development practices

  • devsecops-practices

  • CI/CD security integration

  • container-security

  • Container image signing and scanning

Last Updated: 2025-12-26

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Security

api-security

No summary provided by upstream source.

Repository SourceNeeds Review
Security

agentic-layer-audit

No summary provided by upstream source.

Repository SourceNeeds Review
Security

container-security

No summary provided by upstream source.

Repository SourceNeeds Review