Claude Code Plugins

Community-maintained marketplace

Feedback

Software supply chain security guidance covering SBOM generation, SLSA framework, dependency scanning, SCA tools, and protection against supply chain attacks like dependency confusion and typosquatting.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name supply-chain-security
description Software supply chain security guidance covering SBOM generation, SLSA framework, dependency scanning, SCA tools, and protection against supply chain attacks like dependency confusion and typosquatting.
allowed-tools Read, Glob, Grep, Task

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@v4

      - 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<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;
    }

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

        var results = new Dictionary<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<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;
    }

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

      - 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