Skip to content

Latest commit

 

History

History
322 lines (226 loc) · 9.43 KB

File metadata and controls

322 lines (226 loc) · 9.43 KB

Supply Chain Security

This package includes cryptographically signed build provenance attestations using Sigstore, achieving SLSA Build Level 2 compliance.

Table of Contents

What are Attestations?

Build provenance attestations are cryptographically signed documents that prove:

  • Where the package was built (GitHub Actions)
  • When it was built (timestamp)
  • How it was built (workflow file reference)
  • What source code was used (commit SHA)

Think of it as a tamper-proof certificate of authenticity for the NuGet package.

Why Attestations Matter

Protection Against Supply Chain Attacks

Attestations protect you from:

  • Compromised packages - Verify the package came from the official repository
  • Malicious builds - Confirm the package was built in a trusted environment
  • Tampered artifacts - Detect if the package was modified after building
  • Impersonation - Ensure you're using the genuine package, not a fake

Trust, but Verify

Instead of blindly trusting a package, you can verify:

# Verify this package was built from the official repository
gh attestation verify --repo jeppestaerk/JeppeStaerk.OnePasswordConnect \
    JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.nupkg

If verification succeeds, you know the package is authentic.

What's Included

Every package published from this repository includes:

1. SLSA Build Provenance Attestation

Generated by GitHub's attest-build-provenance action.

Contains:

  • Builder identity (GitHub Actions)
  • Repository URL
  • Commit SHA
  • Workflow reference
  • Build timestamp
  • Artifact digest (SHA-256 hash)

2. Sigstore Signature Bundle

Generated by Sigstore Cosign.

Contains:

  • Cryptographic signature
  • Certificate chain
  • Transparency log entry

Both attestations are:

  • Signed with ephemeral keys
  • Timestamped in transparency logs
  • Verifiable using public tools

Verifying Package Attestations

Prerequisites

Install the GitHub CLI:

# macOS
brew install gh

# Windows (using winget)
winget install --id GitHub.cli

# Linux
# See https://github.com/cli/cli#installation

Verification for GitHub Packages

GitHub Packages can be verified directly:

# Download the package
dotnet nuget add source https://nuget.pkg.github.com/jeppestaerk/index.json \
    --name github \
    --username YOUR_GITHUB_USERNAME \
    --password YOUR_GITHUB_PAT \
    --store-password-in-clear-text

dotnet nuget install JeppeStaerk.OnePasswordConnect.Sdk \
    --version 1.8.1 \
    --source github \
    --output-directory ./packages

# Verify the attestation
gh attestation verify \
    --repo jeppestaerk/JeppeStaerk.OnePasswordConnect \
    ./packages/JeppeStaerk.OnePasswordConnect.Sdk.1.8.1/JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.nupkg

Verification for NuGet.org Packages

NuGet.org adds its own signature to packages, which must be removed before verifying the build attestation:

On macOS/Linux (using zip)

# Download the package
dotnet nuget install JeppeStaerk.OnePasswordConnect.Sdk \
    --version 1.8.1 \
    --output-directory ./packages

cd ./packages/JeppeStaerk.OnePasswordConnect.Sdk.1.8.1

# Remove NuGet.org signature
zip -d JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.nupkg .signature.p7s

# Verify the attestation
gh attestation verify \
    --repo jeppestaerk/JeppeStaerk.OnePasswordConnect \
    JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.nupkg

On Windows (using PowerShell)

# Download the package
dotnet nuget install JeppeStaerk.OnePasswordConnect.Sdk `
    --version 1.8.1 `
    --output-directory ./packages

cd ./packages/JeppeStaerk.OnePasswordConnect.Sdk.1.8.1

# Remove NuGet.org signature
$pkgPath = "JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.nupkg"
$zipPath = "JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.zip"

# Rename to .zip
Rename-Item $pkgPath $zipPath

# Load the zip file
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::Open($zipPath, 'Update')

# Remove the signature
$signatureEntry = $zip.Entries | Where-Object { $_.FullName -eq '.signature.p7s' }
if ($signatureEntry) {
    $signatureEntry.Delete()
}

# Save and close
$zip.Dispose()

# Rename back to .nupkg
Rename-Item $zipPath $pkgPath

# Verify the attestation
gh attestation verify `
    --repo jeppestaerk/JeppeStaerk.OnePasswordConnect `
    $pkgPath

Successful Verification Output

When verification succeeds, you'll see:

Loaded digest sha256:abc123... for file://JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.nupkg
Loaded 1 attestation from GitHub API
✓ Verification succeeded!

sha256:abc123... was attested by:
REPO                PREDICATE_TYPE          WORKFLOW
jeppestaerk/JeppeStaerk.OnePasswordConnect  https://slsa.dev/provenance/v1  .github/workflows/build-and-publish.yml@refs/heads/main

Failed Verification

If verification fails, you'll see an error:

✗ Verification failed!

The package does not match the attestation or was not built from the official repository.
DO NOT USE THIS PACKAGE.

If verification fails:

  1. Do not use the package
  2. 🔍 Investigate where you obtained it
  3. ⚠️ Report the issue to the maintainer
  4. ✅ Download from official sources only

SLSA Compliance

SLSA Build Level 2

This package achieves SLSA Build Level 2 compliance:

Requirement Status Implementation
Build service GitHub Actions
Build as code .github/workflows/build-and-publish.yml
Provenance generated actions/attest-build-provenance@v3
Provenance authenticated Signed with ephemeral keys
Provenance service generated Generated by GitHub, not the build script

What This Means for You

Trustworthy builds:

  • Built in an isolated environment (GitHub Actions)
  • Build process is defined in version control
  • Can't be tampered with during build

Verifiable provenance:

  • Cryptographically signed
  • Timestamped in transparency logs
  • Can be verified by anyone

Traceable:

  • Know exactly which commit was built
  • Know when it was built
  • Know which workflow built it

Best Practices

For Package Consumers

  1. Always verify packages before use (especially in production)
  2. Pin package versions to specific versions
  3. Review release notes before upgrading
  4. Use official sources (NuGet.org or GitHub Packages)
  5. Monitor security advisories for the repository

For CI/CD Pipelines

# Example: Verify in CI before using
- name: Verify Package Attestation
  run: |
    dotnet nuget install JeppeStaerk.OnePasswordConnect.Sdk \
        --version 1.8.1 \
        --output-directory ./packages

    cd ./packages/JeppeStaerk.OnePasswordConnect.Sdk.1.8.1

    # Remove NuGet.org signature
    zip -d JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.nupkg .signature.p7s

    # Verify attestation
    gh attestation verify \
        --repo jeppestaerk/JeppeStaerk.OnePasswordConnect \
        JeppeStaerk.OnePasswordConnect.Sdk.1.8.1.nupkg

- name: Use Package
  run: dotnet add package JeppeStaerk.OnePasswordConnect.Sdk --version 1.8.1

FAQ

Why do I need to remove .signature.p7s from NuGet.org packages?

NuGet.org signs all packages with its own signature for package integrity. This signature is separate from the build attestation. To verify the build attestation, NuGet.org's signature must be removed temporarily (it doesn't affect the verification process).

Is verification required?

No, but highly recommended for:

  • Production environments
  • Security-sensitive applications
  • Compliance requirements

What if verification fails?

Do not use the package. Either:

  1. The package was tampered with
  2. The package didn't come from the official repository
  3. There's a technical issue with the verification

Report the issue and download from official sources.

Can I verify older package versions?

Yes, as long as they were built with attestations enabled (v1.8.1 and later). Older versions may not have attestations.

Where are attestations stored?

  • GitHub Packages: Stored in GitHub's artifact attestation API
  • NuGet.org: Attestations are submitted during publish but must be verified via GitHub's API

Additional Resources

Reporting Security Issues

If you discover a security vulnerability related to package integrity or supply chain security:

  • 🔒 Do NOT open a public GitHub issue
  • 📧 Email security concerns to the maintainer
  • 🛡️ Provide details about the vulnerability
  • ⏱️ Allow time for a fix before public disclosure

See the repository's SECURITY.md file for the complete security policy.