Skip to content

Signed Releases

Bindy releases are cryptographically signed using Cosign with keyless signing (Sigstore). This ensures:

  • Authenticity: Verify that releases come from the official Bindy GitHub repository
  • Integrity: Detect any tampering with release artifacts
  • Non-repudiation: Cryptographic proof that artifacts were built by official CI/CD
  • Transparency: All signatures are recorded in the Sigstore transparency log (Rekor)

What Is Signed

Every Bindy release includes signed artifacts:

  1. Container Images:
  2. ghcr.io/firestoned/bindy:* (Chainguard base - default)
  3. ghcr.io/firestoned/bindy:*-distroless (Google Distroless base - alternative)

  4. Binary Tarballs:

  5. bindy-linux-amd64.tar.gz
  6. bindy-linux-arm64.tar.gz

  7. Signature Artifacts (uploaded to releases):

  8. *.tar.gz.bundle - Cosign signature bundles for binaries
  9. Container signatures are stored in the OCI registry

Installing Cosign

To verify signatures, install Cosign:

# macOS
brew install cosign

# Linux (download binary)
LATEST_VERSION=$(curl -s https://api.github.com/repos/sigstore/cosign/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -Lo cosign https://github.com/sigstore/cosign/releases/download/${LATEST_VERSION}/cosign-linux-amd64
chmod +x cosign
sudo mv cosign /usr/local/bin/

# Verify installation
cosign version

Verifying Container Images

Cosign uses keyless signing with Sigstore, which means: - No private keys to manage or distribute - Signatures are verified against the GitHub Actions OIDC identity - All signatures are logged in the public Rekor transparency log

Quick Verification

# Verify the latest Chainguard image
cosign verify \
  --certificate-identity-regexp='https://github.com/firestoned/bindy' \
  --certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
  ghcr.io/firestoned/bindy:latest

# Verify a specific version
cosign verify \
  --certificate-identity-regexp='https://github.com/firestoned/bindy' \
  --certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
  ghcr.io/firestoned/bindy:v0.1.0

# Verify the Distroless variant
cosign verify \
  --certificate-identity-regexp='https://github.com/firestoned/bindy' \
  --certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
  ghcr.io/firestoned/bindy:latest-distroless

Understanding the Verification Output

When verification succeeds, Cosign returns JSON output with signature details:

[
  {
    "critical": {
      "identity": {
        "docker-reference": "ghcr.io/firestoned/bindy"
      },
      "image": {
        "docker-manifest-digest": "sha256:abcd1234..."
      },
      "type": "cosign container image signature"
    },
    "optional": {
      "Bundle": {
        "SignedEntryTimestamp": "...",
        "Payload": {
          "body": "...",
          "integratedTime": 1234567890,
          "logIndex": 12345678,
          "logID": "..."
        }
      },
      "Issuer": "https://token.actions.githubusercontent.com",
      "Subject": "https://github.com/firestoned/bindy/.github/workflows/build.yaml@refs/tags/v0.1.0"
    }
  }
]

Key fields to verify: - Subject: Shows the exact GitHub workflow that created the signature - Issuer: Confirms it came from GitHub Actions - integratedTime: Unix timestamp when signature was created - logIndex: Entry in the Rekor transparency log (publicly auditable)

Verification Failures

If verification fails, you'll see an error like:

Error: no matching signatures:

Do NOT use unverified images in production. This indicates: - The image was not signed by the official Bindy release workflow - The image may have been tampered with - The image may be a counterfeit

Verifying Binary Releases

Binary tarballs are signed with Cosign blob signing. Each release includes .bundle files containing the signature.

Download and Verify

# Download the binary tarball and signature bundle from GitHub Releases
VERSION="v0.1.0"
PLATFORM="linux-amd64"  # or linux-arm64

# Download tarball
curl -LO "https://github.com/firestoned/bindy/releases/download/${VERSION}/bindy-${PLATFORM}.tar.gz"

# Download signature bundle
curl -LO "https://github.com/firestoned/bindy/releases/download/${VERSION}/bindy-${PLATFORM}.tar.gz.bundle"

# Verify the signature
cosign verify-blob \
  --bundle "bindy-${PLATFORM}.tar.gz.bundle" \
  --certificate-identity-regexp='https://github.com/firestoned/bindy' \
  --certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
  "bindy-${PLATFORM}.tar.gz"

Verification Success

If successful, you'll see:

Verified OK

You can now safely extract and use the binary:

tar xzf bindy-${PLATFORM}.tar.gz
./bindy --version

Automated Verification Script

Create a script to download and verify releases automatically:

#!/bin/bash
set -euo pipefail

VERSION="${1:-latest}"
PLATFORM="${2:-linux-amd64}"

if [ "$VERSION" = "latest" ]; then
  VERSION=$(curl -s https://api.github.com/repos/firestoned/bindy/releases/latest | grep tag_name | cut -d '"' -f 4)
fi

echo "Downloading Bindy $VERSION for $PLATFORM..."

# Download artifacts
curl -LO "https://github.com/firestoned/bindy/releases/download/${VERSION}/bindy-${PLATFORM}.tar.gz"
curl -LO "https://github.com/firestoned/bindy/releases/download/${VERSION}/bindy-${PLATFORM}.tar.gz.bundle"

# Verify signature
echo "Verifying signature..."
cosign verify-blob \
  --bundle "bindy-${PLATFORM}.tar.gz.bundle" \
  --certificate-identity-regexp='https://github.com/firestoned/bindy' \
  --certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
  "bindy-${PLATFORM}.tar.gz"

# Extract
echo "Extracting..."
tar xzf "bindy-${PLATFORM}.tar.gz"

echo "✓ Bindy $VERSION successfully verified and installed"
./bindy --version

Additional Security Verification

Check SHA256 Checksums

Every release includes a checksums.sha256 file with SHA256 hashes of all artifacts:

# Download checksums
curl -LO "https://github.com/firestoned/bindy/releases/download/${VERSION}/checksums.sha256"

# Verify the tarball checksum
sha256sum -c checksums.sha256 --ignore-missing

Inspect Rekor Transparency Log

All signatures are recorded in the public Rekor transparency log:

# Search for Bindy signatures
rekor-cli search --email noreply@github.com --rekor_server https://rekor.sigstore.dev

# Or use the web interface:
# https://search.sigstore.dev/?email=noreply@github.com

Verify SLSA Provenance

Bindy releases also include SLSA provenance attestations:

# Verify SLSA provenance for the container image
cosign verify-attestation \
  --type slsaprovenance \
  --certificate-identity-regexp='https://github.com/firestoned/bindy' \
  --certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
  ghcr.io/firestoned/bindy:${VERSION}

Kubernetes Deployment Verification

Three complementary layers, in the order most deployments adopt them:

  1. FluxCD (GitOps) — verify the deployment source (signed OCI artifact) before anything is applied.
  2. ValidatingAdmissionPolicy — enforce image provenance (trusted registries, immutable references) with zero extra controllers. Ships with bindy.
  3. Kyverno / sigstore policy-controller — cryptographic signature verification at pod admission (CEL cannot verify signatures, so this layer needs a verifying controller).

FluxCD (GitOps) Verification

Flux verifies Cosign signatures on the OCI sources it pulls (OCIRepository / HelmChart) — tampered or unsigned artifacts are never applied. Note Flux does not verify container-image signatures at pod admission; combine it with the layers below.

Wrap bindy's released manifests in an OCI artifact you sign, and let Flux refuse anything unsigned:

# One-time (or per bindy upgrade): package + sign the manifests you deploy
VERSION=v0.6.0
curl -sSLO https://github.com/firestoned/bindy/releases/download/${VERSION}/install.yaml
flux push artifact oci://ghcr.io/<your-org>/bindy-manifests:${VERSION} \
  --path=. --source="github.com/firestoned/bindy" --revision="${VERSION}"
cosign sign ghcr.io/<your-org>/bindy-manifests:${VERSION}
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
  name: bindy-manifests
  namespace: flux-system
spec:
  interval: 10m
  url: oci://ghcr.io/<your-org>/bindy-manifests
  ref:
    tag: v0.6.0
  verify:
    provider: cosign
    # Keyless: pin the signing identity. For artifacts signed in YOUR CI,
    # match your workflow; for interactive `cosign sign`, match your OIDC
    # identity via a secretRef / matchOIDCIdentity as appropriate.
    matchOIDCIdentity:
      - issuer: "https://token.actions.githubusercontent.com"
        subject: "https://github.com/<your-org>/<your-repo>/.github/workflows/.*"
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: bindy
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: OCIRepository
    name: bindy-manifests
  path: ./
  prune: true

With spec.verify set, Flux marks the source SourceVerifiedFailed and refuses to reconcile if the signature is missing or does not match the pinned identity.

ValidatingAdmissionPolicy (no extra controller)

Bindy ships an image-provenance policy — deploy/admission-policies/15-bindy-image-provenance-policy.yaml — enforced by the API server itself (Kubernetes 1.30+, CEL; no webhook or controller to operate):

  • bindcar sidecar overrides must come from ghcr.io/firestoned/
  • BIND9 operand overrides must be internetsystemsconsortium/bind9 or a ghcr.io/firestoned/ mirror
  • every override must be immutable: digest-pinned (@sha256:) or a named non-:latest tag
kubectl apply -f deploy/admission-policies/
# or the combined release artifact:
kubectl apply -f https://github.com/firestoned/bindy/releases/latest/download/admission-policies.yaml

Scope: CEL cannot perform cryptographic verification — this policy pins where images come from and that references are immutable, not who signed them. For signature verification at admission, add Kyverno or the sigstore policy-controller below.

Kyverno Policy Example

When deploying to Kubernetes, use policy-controller or Kyverno to enforce signature verification:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-bindy-images
spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: verify-bindy-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "ghcr.io/firestoned/bindy*"
          attestors:
            - entries:
                - keyless:
                    # Releases are signed by the consolidated build.yaml
                    # workflow. Releases published before the consolidation
                    # were signed by the former release.yaml identity.
                    subject: "https://github.com/firestoned/bindy/.github/workflows/build.yaml@*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: https://rekor.sigstore.dev

This policy ensures: - Only signed Bindy images can run in the cluster - Signatures must come from the official release workflow - Signatures are verified against the Rekor transparency log

Troubleshooting

"Error: no matching signatures"

Cause: Image/artifact is not signed or signature doesn't match the identity.

Solution: - Verify you're using an official release from ghcr.io/firestoned/bindy* - Check the tag/version exists on the GitHub releases page - Ensure you're not using a locally-built image

"Error: unable to verify bundle"

Cause: Signature bundle is corrupted or doesn't match the artifact.

Solution: - Re-download the artifact and bundle - Verify the SHA256 checksum matches checksums.sha256 - Report the issue if checksums match but verification fails

"Error: fetching bundle: context deadline exceeded"

Cause: Network issue connecting to Sigstore services.

Solution: - Check your internet connection - Verify you can reach https://rekor.sigstore.dev and https://fulcio.sigstore.dev - Try again with increased timeout: COSIGN_TIMEOUT=60s cosign verify ...

Security Contact

If you discover a security issue with signed releases:

  • DO NOT open a public GitHub issue
  • Report to: security@firestoned.io
  • Include: artifact name, version, verification output, and steps to reproduce

See SECURITY.md for our security policy and vulnerability disclosure process.

SPDX License Headers

All Bindy source files include SPDX license identifiers for automated license compliance tracking.

What is SPDX?

SPDX (Software Package Data Exchange) is an ISO standard (ISO/IEC 5962:2021) for communicating software license information. SPDX identifiers enable:

  • Automated SBOM generation: Tools like cargo-cyclonedx detect licenses automatically
  • License compliance auditing: Verify no GPL contamination in MIT-licensed project
  • Supply chain transparency: Clear license identification at file granularity
  • Tooling integration: GitHub, Snyk, Trivy, and other tools recognize SPDX headers

Required Header Format

All source files MUST include SPDX headers in the first 10 lines:

Rust files (.rs):

// Copyright (c) 2025 Erick Bourgeois, firestoned
// SPDX-License-Identifier: MIT

Shell scripts (.sh, .bash):

#!/usr/bin/env bash
# Copyright (c) 2025 Erick Bourgeois, firestoned
# SPDX-License-Identifier: MIT

Makefiles (Makefile, *.mk):

# Copyright (c) 2025 Erick Bourgeois, firestoned
# SPDX-License-Identifier: MIT

GitHub Actions workflows (.yaml, .yml):

# Copyright (c) 2025 Erick Bourgeois, firestoned
# SPDX-License-Identifier: MIT
name: My Workflow

Automated Verification

Bindy enforces SPDX headers via CI/CD:

Workflow: .github/workflows/license-check.yaml

Checks: - All Rust files (.rs) - All Shell scripts (.sh, .bash) - All Makefiles (Makefile, *.mk) - All GitHub Actions workflows (.yaml, .yml)

Enforcement: - Runs on every pull request - Runs on every push to main - Pull requests fail if any source files lack SPDX headers - Provides clear error messages with examples for missing headers

Output Example:

✅ All 347 source files have SPDX license headers

File types checked:
  - Rust files (.rs)
  - Shell scripts (.sh, .bash)
  - Makefiles (Makefile, *.mk)
  - GitHub Actions workflows (.yaml, .yml)

License: MIT

Bindy is licensed under the MIT License, one of the most permissive open source licenses.

Permissions: - ✅ Commercial use - ✅ Modification - ✅ Distribution - ✅ Private use

Conditions: - 📋 Include copyright notice - 📋 Include license text

Limitations: - ❌ No liability - ❌ No warranty

Full license text: LICENSE

Compliance Evidence

SOX 404 (Sarbanes-Oxley): - Control: License compliance and intellectual property tracking - Evidence: All source files tagged with SPDX identifiers, automated verification - Audit Trail: Git history shows when SPDX headers were added

PCI-DSS 6.4.6 (Payment Card Industry): - Requirement: Code review and approval processes - Evidence: SPDX verification blocks unapproved code (missing headers) from merging - Automation: CI/CD enforces license compliance before code review

SLSA Level 3 (Supply Chain Security): - Requirement: Build environment provenance and dependencies - Evidence: SPDX headers enable automated SBOM generation with license info - Transparency: Every dependency's license is machine-readable


References