PS Product SecurityKnowledge Base

✍️ Signing, Attestation, and Verification — Legacy vs Current

Intro: The underlying problem stayed the same: prove what artifact was built, by whom, from what source, and whether policy should allow it to run. The ecosystem changed a lot. This page translates older signing guidance into a 2026-friendly model.

The problem this page solves

A modern supply-chain control stack should answer five questions:

  1. What artifact is this?
  2. Which source and pipeline produced it?
  3. Was it signed by an expected identity?
  4. Do we have useful metadata, such as SBOM or provenance?
  5. Is the consumer actually verifying anything, or only storing metadata?

Legacy versus current reality

Topic Older model Practical current model
image signing Docker Content Trust / Notary v1 Cosign is the default open-source mental model for new builds; Notation is a valid OCI-oriented alternative
vulnerability evidence scanner output only signed SBOMs, attestations, and policy-aware verification
“trust” decision trust the registry or repo tag verify signature, identity, provenance, and policy at admission or deploy time
evidence handoff CI logs and screenshots machine-readable SBOM, attestations, and release evidence stored with the artifact

Minimal modern pattern

For most teams, the practical minimum is:

  • generate an SBOM;
  • sign the image or artifact;
  • optionally attest provenance or scan results;
  • verify signatures where the artifact is pulled, promoted, or admitted.

Practical snippet — legacy DCT example you may still encounter

export DOCKER_CONTENT_TRUST=1
docker trust sign registry.example.com/team/app:1.2.3
docker pull registry.example.com/team/app:1.2.3

Keep this in the KB because older runbooks and older training still refer to it. Do not choose it as the default for new platform design.

Practical snippet — current Syft + Cosign flow

syft registry.example.com/team/app:1.2.3 -o spdx-json=sbom.spdx.json
cosign sign --yes registry.example.com/team/app:1.2.3
cosign attest --yes --predicate sbom.spdx.json --type spdx registry.example.com/team/app:1.2.3

This is a good “small but real” pattern for teams that want evidence without building a large platform first.

Practical snippet — keyless sign and verify

cosign sign registry.example.com/team/app:1.2.3
cosign verify registry.example.com/team/app:1.2.3

Use workload identity or OIDC-backed CI where possible so signatures can be tied to the build identity rather than to a long-lived shared key.

Practical snippet — verify an attestation

cosign verify-attestation registry.example.com/team/app:1.2.3

Use this when your deploy or admission control wants more than “the image is signed.”

Practical snippet — SBOM generation and vulnerability scan

syft dir:. -o cyclonedx-json=sbom-source.cdx.json
trivy sbom sbom-source.cdx.json

Or with Grype:

grype sbom:sbom-source.cdx.json --fail-on high

Practical snippet — GitHub Actions example

name: build-sign-attest
on:
  push:
    branches: [ main ]

jobs:
  release:
    permissions:
      id-token: write
      contents: read
      packages: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build image
        run: docker build -t ghcr.io/org/app:${{ github.sha }} .
      - name: Push image
        run: docker push ghcr.io/org/app:${{ github.sha }}
      - name: Generate SBOM
        run: syft ghcr.io/org/app:${{ github.sha }} -o spdx-json=sbom.spdx.json
      - name: Sign image
        run: cosign sign --yes ghcr.io/org/app:${{ github.sha }}
      - name: Attach SBOM attestation
        run: cosign attest --yes --predicate sbom.spdx.json --type spdx ghcr.io/org/app:${{ github.sha }}

Practical snippet — admission-friendly verification gate

cosign verify \
  --certificate-identity "https://github.com/org/repo/.github/workflows/release.yml@refs/heads/main" \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  registry.example.com/team/app:1.2.3

This makes the policy more specific than “any valid signature”.

Practical snippet — Notation-style mental model

If your environment standardizes on OCI-native signature tooling through the Notary Project ecosystem, keep the model the same:

  • sign artifact;
  • push artifact and signature;
  • verify by policy before promotion or deployment.

Use Notation when your registry and platform standardize there. Use Cosign when you want the most common open-source path with broad examples and OIDC-first workflows.

Store or publish, per release:

  • artifact digest;
  • commit SHA;
  • pipeline run URL or immutable run identifier;
  • SBOM in SPDX or CycloneDX;
  • vulnerability summary or policy result;
  • signature verification result;
  • provenance or attestation where available.

Common mistakes

  • signing by tag instead of reasoning from immutable digests;
  • generating SBOMs but never tying them to a release artifact;
  • storing signatures but not verifying them in deployment paths;
  • using one shared signing key for too many repos or teams;
  • treating “artifact is signed” as equivalent to “artifact is safe”.

What to keep from older books

Older material is still valuable for:

  • explaining why provenance matters;
  • showing repository keys, offline roots, and freshness concepts;
  • teaching that artifact trust is different from transport security;
  • reminding teams that image sources must be curated.

What changed:

  • long-lived signing keys are less appealing than OIDC-backed identity flows;
  • SBOM and attestation workflows are much more common;
  • verification must happen in consumers, not only in producers.

---Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.