Documents
Supply Chain Security
Supply Chain Security
Type
Topic
Status
Published
Created
Feb 27, 2026
Updated
Apr 19, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Supply Chain Security#

Supply chain security for software projects encompasses the practices, tools, and processes used to protect software artifacts from development through deployment. The opnDossier project implements a comprehensive supply chain security approach following the EvilBit Labs Pipeline v2 Specification, combining build provenance, artifact signing, dependency management, and continuous security monitoring.

The project's supply chain security strategy employs multiple defense layers: SLSA Level 3 provenance via GitHub Actions attestations provides cryptographic proof of build integrity; Cosign v3 keyless signing through Sigstore ensures artifact authenticity; CycloneDX SBOM generation enables dependency tracking; and automated security scanning detects vulnerabilities before they reach production. All releases are built with hardened compilation settings (CGO_ENABLED=0, -trimpath, stripped binaries) for reproducibility and security.

The implementation emphasizes local/CI parity, allowing developers to run all security checks locally before pushing code. OSSF Scorecard provides continuous assessment of security practices, while Dependabot automates weekly dependency updates across four ecosystems (Go modules, GitHub Actions, Docker, Dev Containers). Security scanning uses gosec for static analysis. Continuous vulnerability scanning runs via .github/workflows/security.yml using govulncheck, CodeQL, and Trivy on push, pull requests, and weekly. FOSSA GitHub App integration provides license compliance monitoring.

Release Process and Build Security#

GoReleaser Configuration#

The project uses GoReleaser v2 for automated, reproducible releases. The configuration supports multi-platform builds targeting FreeBSD, Linux, macOS, and Windows across amd64 and arm64 architectures. For macOS, universal binaries combine both architectures into a single executable. The release pipeline generates native packages (.deb, .rpm, .apk, .pkg.tar.xz) for major Linux distributions and builds Docker images using goreleaser's dockers_v2 feature with Docker Buildx, supporting linux/amd64 and linux/arm64 platforms.

Each release archive includes LICENSE, README.md, CHANGELOG.md, and THIRD_PARTY_NOTICES files alongside binaries. The GoReleaser configuration handles shell completions (bash, zsh, fish, PowerShell) and man page generation dynamically using Cobra, ensuring documentation stays synchronized with the codebase. The release process includes an automated pre-hook that runs just notices to generate current license attribution before building artifacts.

Docker Image Configuration#

Docker images are pushed to ghcr.io/evilbit-labs/opndossier using the dockers_v2 configuration with native multi-platform support for linux/amd64 and linux/arm64. Images receive versioned tags (e.g., v1.2.3) for all releases, while floating tags (latest and v<major>) are applied only to stable releases, excluding pre-releases. Docker image manifests are signed with Cosign in keyless mode via the docker_signs configuration, providing cryptographic verification of image authenticity.

Build Hardening#

Security-focused build settings ensure artifact integrity and reproducibility. CGO_ENABLED=0 produces statically linked binaries with no external C dependencies, enhancing portability and reducing attack surface. The -trimpath flag removes filesystem-specific paths from compiled binaries, enabling reproducible builds across different development environments.

Link-time optimization flags (-s -w) strip debug information and symbol tables, reducing binary size and complicating reverse engineering. The build process injects version metadata (version, commit hash, build date) via ldflags, allowing runtime version verification. Commit timestamps ensure deterministic builds by using git commit time instead of current system time.

SLSA Provenance#

The release workflow implements SLSA Level 3 provenance using GitHub Actions' native attestation framework. The actions/attest-build-provenance@v4.0.0 action generates cryptographic attestations linking artifacts to their exact source code versions, build environment, and build process. Attestations are created for both checksum files and distribution archives (tar.gz, zip), providing a complete chain of custody from source to binary.

The workflow requires specific GitHub permissions: contents:write for release creation, id-token:write for OIDC authentication, attestations:write for provenance generation, and packages:write for pushing Docker images to GitHub Container Registry. Users can verify attestations using the GitHub CLI (gh attestation verify) to confirm artifact authenticity and build provenance before deployment.

Artifact Signing with Cosign#

Keyless Signing#

Cosign v3 provides keyless artifact signing via Sigstore's OIDC-based authentication. The signature format uses .sigstore.json bundles, replacing the older separate .sig and .pem files for improved convenience and security. The signing process executes cosign sign-blob with the --bundle flag during GoReleaser execution, automatically signing checksum files.

Keyless signing eliminates the need for long-term secret management by leveraging OIDC identity tokens from GitHub Actions. The signature binds the artifact to the workflow identity, creating a verifiable link between the release artifact and the authorized GitHub Actions workflow that produced it.

Verification Process#

Artifact verification requires matching the certificate identity (workflow path + git ref) and OIDC issuer (https://token.actions.githubusercontent.com). The release workflow includes automated verification to catch signing issues before publication. Users verify signatures with:

cosign verify-blob \
  --certificate-identity "https://github.com/EvilBit-Labs/opnDossier/.github/workflows/release.yml@refs/tags/v1.2.3" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  --bundle opnDossier_checksums.txt.sigstore.json \
  opnDossier_checksums.txt

Signatures are attached to GitHub releases alongside artifacts, providing a complete chain of trust from source code to distribution.

Software Bill of Materials (SBOM)#

SBOM Generation#

The project generates SBOMs in CycloneDX JSON format, not SPDX as initially documented. Two types of SBOMs are produced: binary SBOMs scan compiled binaries per platform/architecture, while module SBOMs analyze the Go module dependency tree including license information.

The cyclonedx-gomod tool performs the scanning, integrated into both the CI pipeline and release process. Developers generate SBOMs locally using the just sbom command, which first builds a release binary then scans both the binary and module dependencies.

SBOM Artifacts#

SBOM generation produces two files: sbom-binary.cyclonedx.json and sbom-modules.cyclonedx.json. These artifacts are available as GitHub Actions artifacts from CI workflow runs with 30-day retention (GitHub Actions default). A scheduled workflow generates fresh SBOMs weekly (Sunday midnight UTC) to track dependency changes over time.

Vulnerability Scanning#

Vulnerability scanning is handled by .github/workflows/security.yml, which runs on push to main, pull requests, and weekly (Monday 06:00 UTC). The workflow combines three tools:

  • govulncheck: Scans the module dependency graph against the Go vulnerability database
  • CodeQL: GitHub semantic code analysis for Go, results uploaded to Security tab
  • Trivy: Filesystem scan covering dependencies and misconfiguration, SARIF uploaded to code scanning

gosec Security Scanning#

gosec serves as the primary security scanner for Go code, detecting common security issues like hardcoded credentials, SQL injection, command injection, and insecure cryptographic practices. The tool scans all Go packages (gosec ./...) using default settings without a standalone configuration file. Developers run gosec locally via just scan before committing code.

gosec is also integrated into golangci-lint, running automatically during CI builds and PR checks. The configuration excludes specific rules: G301 (man page permissions require 755 for public access) and G304 (loading user-specified templates is expected CLI behavior). The tool is installed via mise or manually, forming part of the security-all command suite.

Vulnerability Response Timeline#

The SECURITY.md policy establishes a 90-day fix window for confirmed vulnerabilities. The response process includes acknowledgement within 1 week and initial assessment within 2 weeks. Vulnerability disclosure follows coordinated disclosure through GitHub Security Advisory, with credit provided to reporters unless anonymity is requested.

Static Application Security Testing (SAST)#

gosec functions as the primary SAST tool through dual integration: embedded in golangci-lint configuration for automated CI checks and run standalone via just scan for local development. The rule exclusions (G301 for man page permissions, G304 for user-specified template loading) reflect deliberate security decisions for specific CLI functionality. The tool operates with default settings without additional configuration files.

Dependency Management#

Dependabot#

Dependabot monitors four package ecosystems with weekly automated updates: Go modules, GitHub Actions, Docker, and Dev Containers. The rebase strategy is disabled for all ecosystems, preferring merge commits for update PRs. Each automated PR includes changelog information and compatibility assessments to inform review decisions.

Dependency Tracking#

The project uses Go 1.26 with toolchain go1.26.0, tracking 19 direct dependencies and 70 indirect dependencies. Key dependencies include Cobra (CLI framework), Viper (configuration), Charm libraries (terminal UI), and go-playground/validator (validation). go.mod and go.sum files ensure reproducible builds through version locking.

The project supports airgap builds using GOMODCACHE and vendor directories for offline compilation. Dependencies are continuously audited by the security.yml workflow (govulncheck, CodeQL, Trivy), providing real-time vulnerability alerts for the entire dependency tree.

License Compliance#

The project uses a dual approach to license compliance: machine-readable SBOMs (CycloneDX format) for automated tooling and human-readable attribution files (THIRD_PARTY_NOTICES) for user transparency. The project is licensed under Apache License 2.0, enforcing compatibility policies for all dependencies.

THIRD_PARTY_NOTICES Generation#

The project generates human-readable license attribution using go-licenses, a mise-managed tool that extracts license information from all Go dependencies. Developers generate attribution files locally using just notices, which executes go-licenses report with the notices.tpl template to format output consistently.

The template generates a structured document listing each dependency's package name, license type, URL, and full license text. The go-licenses tool excludes the project itself (--ignore github.com/EvilBit-Labs/opnDossier) to focus on third-party dependencies only.

Release Integration#

THIRD_PARTY_NOTICES is automatically generated before each release via a GoReleaser pre-hook that runs just notices, ensuring attribution information stays synchronized with dependency versions. The file is included in distribution archives (.tar.gz, .zip) alongside LICENSE, README.md, and CHANGELOG.md, and in Linux packages (.deb, .rpm, .apk) installed to /usr/share/doc/opndossier/THIRD_PARTY_NOTICES.

This ensures users receive complete license attribution information with every release artifact, supporting compliance requirements and transparency goals.

FOSSA Integration#

FOSSA provides automated license compliance and policy enforcement, scanning all dependencies and transitive dependencies. The project enforces an Apache License 2.0 compatibility policy, blocking dependencies with incompatible licenses. FOSSA integrates as a GitHub App for automated scanning alongside the go-licenses tool for local development. The combination of FOSSA (continuous monitoring) and go-licenses (attribution generation) provides comprehensive license compliance coverage.

Code Quality and Linting#

golangci-lint#

The project employs comprehensive Go linting with 70+ enabled linters configured in .golangci.yml. The linter runs on pre-commit hooks, CI builds, and PR checks with 8 parallel workers and a 30-minute timeout. Developers execute linting locally via just lint for immediate feedback.

Security-focused linters include gosec for vulnerability detection and errcheck with strict settings for unchecked error detection. Resource leak detection uses bodyclose, sqlclosecheck, and rowserrcheck to ensure proper cleanup. The noctx linter catches HTTP requests without context, preventing timeout and cancellation issues.

Code Quality Linters#

gocritic enables five check categories: diagnostic, experimental, opinionated, performance, and style. Other quality linters include staticcheck (advanced static analysis), revive (fast extensible linting), govet (official Go tool for suspicious constructs), and cyclop (cyclomatic complexity checking).

Auto-Formatters#

golines enforces 120-character line length, while gofumpt provides stricter formatting than standard gofmt. Import management and sorting use goimports and gci respectively, ensuring consistent import organization across the codebase.

CI/CD Security Controls#

GitHub Actions Security#

All GitHub Actions are pinned to SHA hashes rather than version tags, preventing supply chain attacks through action substitution. The repository contains six workflows:

  • ci.yml: lint, test, race detector, integration tests, coverage, build verification, SBOM generation
  • release.yml: GoReleaser execution, SLSA provenance, Cosign signing, attestation verification
  • security.yml: govulncheck, CodeQL, Trivy vulnerability scanning
  • scorecard.yml: OSSF Scorecard security metrics
  • sbom.yml: weekly scheduled SBOM generation
  • benchmarks.yml: performance benchmarking

CI Workflow#

The ci.yml workflow triggers on pushes to main and pull requests. It executes golangci-lint v2.9 for code quality, cross-platform testing (Ubuntu, macOS, Windows), integration tests with 5-minute timeout, and race detector for concurrent code safety (informational, continue-on-error).

Coverage reporting to Codecov now enforces strict failure on upload errors (fail_ci_if_error: true). Build verification ensures all platforms compile successfully, while SBOM generation produces both binary and module scans for every commit.

Local/CI Parity#

The local/CI parity principle requires all CI steps to be runnable locally via just commands. Verified commands include:

Pre-Release Validation#

Full test suite execution via just ci-full runs ci-check, security-all, release-check, and docs-test before releases. Developers can create test release builds using just release-snapshot, which executes goreleaser build --clean --snapshot without publishing artifacts.

Testing and Coverage#

Test Requirements#

The project mandates unit tests for all new functionality and integration tests for component interaction. A minimum 85% code coverage threshold is enforced via go test -coverprofile=coverage.out. Coverage reports upload to Codecov for historical tracking and PR comparisons.

All test commands include the -race flag for concurrent code safety, detecting data races that could cause unpredictable behavior in production. This catches synchronization issues during development rather than after deployment.

OSSF Best Practices#

OSSF Scorecard#

OSSF Scorecard provides weekly security health metrics assessment. The workflow triggers on multiple events: weekly cron (Saturday 8:32 AM UTC), push to main, branch protection changes, and manual dispatch. It uses OSSF Scorecard Action v2.4.3 to evaluate project security practices.

Results are published to GitHub Security tab via SARIF upload using the CodeQL action (v4.33.0) and to the OpenSSF public REST API for community visibility. Tracked metrics include branch protection, code review practices, CI/CD test coverage, dependency update practices, and vulnerability disclosure procedures.

Security Requirements and Threat Model#

Security Requirements#

The SECURITY.md file establishes explicit security requirements: the application must not crash or panic on any config.xml input, must not allow XXE or entity expansion attacks, must not allow path traversal via CLI or output paths, must not execute arbitrary code from config files, must not leak sensitive data in errors/logs, must not consume unbounded resources, and must handle sensitive data with appropriate visibility controls.

In-Scope Vulnerabilities#

Security scope includes vulnerabilities in opnDossier's XML parser (XXE, billion laughs attacks), path traversal in file input/output handling, command injection via CLI arguments, and information disclosure in generated reports. Out-of-scope issues include vulnerabilities in OPNsense itself, issues requiring physical access, and social engineering attacks.

Security Features#

Built-in security features include memory-safe implementation (pure Go with no unsafe package usage), XXE-safe parsing (Go's encoding/xml doesn't support external entities or DTD processing), offline-first design (no network access at runtime, built for airgapped environments), and typed data handling (all XML elements map to strictly typed Go structs with validation).

Supply chain transparency is achieved through CycloneDX SBOMs and Sigstore attestations for every release. Automated dependency updates via Dependabot keep dependencies current with security patches.

Safe Harbor Policy#

The safe harbor policy protects security researchers who make a good faith effort to avoid privacy violations, data destruction, and service disruption; only interact with accounts they own or have explicit permission to test; and report vulnerabilities through described channels. The project commits to no legal action against researchers following this policy.

Continuous Monitoring#

Scheduled Scans#

Scheduled security assessments include OSSF Scorecard weekly (Saturday 8:32 AM UTC), SBOM generation weekly (Sunday midnight UTC), security.yml vulnerability scanning weekly (Monday 06:00 UTC), and Dependabot updates weekly for all ecosystems. FOSSA license compliance operates continuously via GitHub App integration.

Real-time Monitoring#

Pull request gates execute all security and quality checks on every PR via ci.yml. This includes golangci-lint code quality checks, cross-platform testing (Ubuntu, macOS, Windows), and 85% code coverage threshold enforcement. The security.yml workflow runs govulncheck, CodeQL, and Trivy on every push and PR. FOSSA license policy enforcement operates via GitHub App, providing immediate feedback on dependency issues.

Usage Examples#

Local Development Workflow#

# Install development tools
just install-dev-tools
just install-security-tools

# Run all pre-commit checks
just check

# Run security scanning
just scan # gosec security scanner
just sbom # Generate SBOM
just notices # Generate THIRD_PARTY_NOTICES
just security-all # Run scan + sbom

# Full CI validation locally
just ci-full # Runs ci-check, security-all, release-check, docs-test

Release Workflow#

# Pre-release validation
just ci-full

# Test release build (snapshot, no publish)
just release-snapshot

# Create actual release (requires appropriate permissions)
# Tag and push to GitHub triggers automated release workflow
git tag v1.2.3
git push origin v1.2.3

Verifying Release Artifacts#

# Verify SLSA provenance with GitHub CLI
gh attestation verify opnDossier_1.2.3_linux_amd64.tar.gz \
  --owner EvilBit-Labs

# Verify Cosign signature
cosign verify-blob \
  --certificate-identity "https://github.com/EvilBit-Labs/opnDossier/.github/workflows/release.yml@refs/tags/v1.2.3" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  --bundle opnDossier_checksums.txt.sigstore.json \
  opnDossier_checksums.txt

SBOM Analysis#

# Generate SBOM locally
just sbom

# Examine binary dependencies
cat sbom-binary.cyclonedx.json | jq '.components[] | {name: .name, version: .version}'

# Examine module dependencies with licenses
cat sbom-modules.cyclonedx.json | jq '.components[] | {name: .name, version: .version, licenses: .licenses}'

# Download SBOM from GitHub Actions artifacts
# Available in CI workflow runs under "Artifacts" section

License Attribution#

# Generate THIRD_PARTY_NOTICES locally
just notices

# View generated attribution file
cat THIRD_PARTY_NOTICES

# Verify license compliance (manual review)
# Check for incompatible licenses or missing attributions

Relevant Code Files#

File PathPurposeDescription
.goreleaser.yamlBuild ConfigurationGoReleaser v2 config: multi-platform builds, Cosign signing, SBOM generation, Docker images, THIRD_PARTY_NOTICES inclusion
.golangci.ymlCode Qualitygolangci-lint config with 70+ linters including gosec for security
.github/dependabot.ymlDependency UpdatesWeekly updates for Go modules, GitHub Actions, Docker, Dev Containers
.github/workflows/ci.ymlCI PipelineLint, test, race detector, coverage, build verification, SBOM generation
.github/workflows/release.ymlRelease AutomationGoReleaser execution, SLSA provenance, Cosign signing, attestation verification
.github/workflows/security.ymlVulnerability Scanninggovulncheck, CodeQL, Trivy scanning on push/PR and weekly
.github/workflows/scorecard.ymlSecurity MetricsOSSF Scorecard weekly assessment with SARIF upload
.github/workflows/sbom.ymlSBOM GenerationWeekly scheduled CycloneDX SBOM generation
justfileTask AutomationLocal/CI parity commands: scan, sbom, notices, security-all, ci-full
mise.tomlTool ManagementMise configuration for development tools including go-licenses
packaging/notices.tplLicense TemplateTemplate for formatting THIRD_PARTY_NOTICES output
go.modDependenciesGo 1.26 with 19 direct dependencies, version locking
SECURITY.mdSecurity PolicyVulnerability disclosure process, security features, safe harbor policy
docs/development/releasing.mdRelease ProcessComplete release workflow documentation
docs/pipeline-v2-compliance.mdCompliancePipeline v2 specification compliance matrix
docs/security/compliance.mdSecurity ToolsOverview of security scanning tools and integrations
  • SLSA Framework: Supply chain Levels for Software Artifacts, providing a specification for build integrity
  • Sigstore: Keyless signing infrastructure using OIDC for artifact authentication
  • CycloneDX: SBOM standard for software component analysis and vulnerability management
  • OSSF Scorecard: Security health metrics for open source projects
  • GitHub Actions Security: Best practices for secure CI/CD pipeline implementation
  • Go Build Security: Compilation flags and settings for secure Go binaries
  • Dependency Management: Automated dependency updates and vulnerability tracking
  • Vulnerability Disclosure: Coordinated disclosure processes and safe harbor policies
Supply Chain Security | Dosu