Cosign og Sigstore på Linux i 2026: Signering og verifikation af container-images

En praktisk guide til at signere og verificere container-images med Cosign v2.4 og Sigstore på Linux i 2026. Dæk keyless OIDC-signering i GitHub Actions, KMS-baseret signering i luftgab, håndhævelse med Kyverno og SLSA-attestationer.

Cosign v2.4 Guide: Container-Signering

Opdateret: 11. juli 2026

Cosign og Sigstore er open source-værktøjer, der signerer og verificerer container-images kryptografisk uden at gemme langtidsholdbare private nøgler: signaturen produceres med et kortvarigt OIDC-udstedt certifikat og publiceres i en offentlig transparenslog (Rekor). På Linux i 2026 er det den de facto standard for supply chain-sikkerhed i CI/CD-pipelines, og med cosign v2.4 kan du signere images, SBOM'er og in-toto-attestationer i samme workflow, hvorefter Kyverno eller Sigstore Policy Controller håndhæver dem ved deployment.

  • Sigstore består af tre komponenter (Fulcio som certifikatudsteder, Rekor som transparenslog og Cosign som klient) og fjerner behovet for et internt PKI til signering.
  • Keyless signering med OIDC (GitHub Actions, GitLab, Buildkite) fjerner den mest kompromitterbare del af signeringsflowet, altså den langtidsholdbare private nøgle.
  • Verifikation kræver, at forbrugeren tjekker både signaturen, certifikatets Subject Alternative Name (SAN) og at posten findes i Rekor. Ellers har du kun opnået security theater.
  • Kyverno 1.13+ og Sigstore Policy Controller 0.10+ kan blokere usignerede images i Kubernetes-admission, og bør konfigureres med fail-closed for produktionsklynger.
  • SLSA v1.0 build-provenance kan vedhæftes som en attestation via cosign attest: det er det, der lader forbrugere verificere hvem, hvor og hvordan et image blev bygget.
  • Rekor er ikke en single point of failure for verifikation. Rekor-kvitteringer kan cache-persisteres offline, og cosign v2 understøtter fuldt luftgab-verifikation.

Hvad er Sigstore, og hvorfor betyder det noget i 2026?

Sigstore er et OpenSSF-projekt, der samler kryptografisk signering, transparenslogning og kortlevende certifikater i én pipeline. Jeg begyndte at anbefale det som standard for alle nye image-registries omkring 2023, og i 2026 er der reelt ingen god teknisk grund til at bygge sin egen infrastruktur til container-signering længere. De sidste tre år har givet os Kubernetes-integration via Policy Controller, native support i Harbor og Artifact Registry, og (vigtigst) en offentlig transparenslog med milliarder af poster, som du kan verificere mod uden at drive noget selv.

Hvorfor det betyder noget: Supply chain-angreb bevæger sig fra teoretiske til reelle. Codecov, SolarWinds, XZ-bagdøren (marts 2024) og en række npm-hændelser gennem 2025 har lært os, at angriberen finder det svageste led. Og det svageste led er ofte "vi stoler på registret". Cosign flytter tilliden fra "hvem uploadede" til "hvem signerede, og kan vi bevise det?". For en arkitekt betyder det, at radius af et kompromitteret registry-token skrumper dramatisk: uden en gyldig signatur i Rekor kan angriberen ikke få sit image kørt.

Bemærk også, at flere compliance-frameworks (NIST SSDF, EU CRA, US EO 14028) nu eksplicit kræver verificerbar build-provenance. Cosign plus SLSA v1.0 er den nemmeste måde at levere den evidens på, uden at bygge et internt PKI, som ingen orker at rotere nøgler i.

Sigstore-arkitekturen: Fulcio, Rekor og cosign

Systemet består af tre distinkte tjenester, og det er afgørende at forstå tillidsgrænsen mellem dem, før du deployer det. Fulcio er en X.509-certifikatudsteder, der tager et OIDC-token (fra GitHub, Google, GitLab, Buildkite osv.) og udsteder et kortlivet signeringscertifikat på 10 minutter. Certifikatet har identiteten fra OIDC-tokenet i en SAN-extension, og det er den identitet, du senere verificerer mod.

Rekor er en append-only transparenslog baseret på Trillian (den samme kode, der driver Certificate Transparency). Hver signering skriver en post med signatur, certifikat og hash af artefakten, og posten inkluderes i et Merkle-tree, der publicerer sin rod jævnligt. Det gør uopdaget signatur-tilbagerulning kryptografisk umuligt.

Cosign er klienten. Den taler med Fulcio for at få et certifikat, laver signaturen over image-manifestet (specifikt: en registry-native OCI-artifact ved siden af image'et), uploader posten til Rekor, og returnerer et Rekor-log-index, der kan cache-persisteres. Ingen af de tre komponenter har adgang til den private nøgle. Den genereres in-memory i cosign og slettes efter brug.

Tillidsgrænser i praksis

Hvis Fulcio kompromitteres, kan angriberen udstede certifikater, men Rekor-poster er stadig offentligt reviderbare, og misbrug opdages. Hvis Rekor kompromitteres, mister du non-repudiation, men klienten kan konfigureres til at nægte poster uden gyldigt inklusion-proof. Klienten er dit sidste forsvarslag: den skal aldrig stole på et registry uden at gå hele vejen gennem certifikatverifikation og Rekor-tjek.

Installation og opsætning af cosign v2.4 på Linux

Cosign v2.4 er den aktuelle stabile linje i midten af 2026 og bringer forbedret luftgab-support samt bedre integration med KMS-udbydere. Installér binaren fra den officielle release på GitHub, og undgå distro-pakker, medmindre din distro backporter security-patches aggressivt (RHEL 9 og Ubuntu 24.04 er ok; alt andet kører du hellere fra upstream).

# Verificér officiel release med checksum
COSIGN_VERSION="v2.4.1"
curl -sSL -o cosign \
  "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64"
curl -sSL -o cosign.sig \
  "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64.sig"
curl -sSL -o cosign.pem \
  "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64.pem"

# Selv-verificér: den nye binary er signeret med den forrige
cosign verify-blob \
  --certificate cosign.pem \
  --signature cosign.sig \
  --certificate-identity-regexp "https://github.com/sigstore/cosign" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  cosign

install -m 0755 cosign /usr/local/bin/cosign
cosign version

Bemærk selv-verifikations-steppet. Cosign v2.4 er signeret af den forrige version af sig selv, hvilket etablerer en bootstrap-chain. Denne detalje er let at overse, men den er hele grunden til, at du kan stole på binaren, du lige har hentet. Uden det er det bare "endnu et download fra GitHub".

Keyless signering med OIDC i GitHub Actions

Keyless signering er cosigns skarpeste feature, og samtidig den sværeste at forklare første gang. Ideen: din CI-pipeline har allerede en identitet via OIDC (GitHub Actions har id-token: write-tilladelsen), så hvorfor generere og opbevare en langtidsholdbar signeringsnøgle? Cosign veksler OIDC-tokenet til et 10-minutters Fulcio-certifikat, signerer, publicerer til Rekor, og glemmer alt.

# .github/workflows/release.yml
name: Byg og signér image
on:
  push:
    tags: ["v*"]

permissions:
  id-token: write   # kritisk: OIDC-token til Fulcio
  contents: read
  packages: write

jobs:
  build-sign:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4

      - name: Login til GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Byg og push
        id: build
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}

      - name: Install cosign
        uses: sigstore/cosign-installer@v3
        with:
          cosign-release: "v2.4.1"

      - name: Signér image (keyless)
        env:
          IMAGE: ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
        run: |
          cosign sign --yes "$IMAGE"

Læg mærke til @${{ steps.build.outputs.digest }}-syntaksen. Vi signerer digestet, ikke tagget. Tags er mutable; digests er ikke. En signatur bundet til et tag er værdiløs, fordi tagget kan pege på et andet image i morgen. Ærligt talt er det den anden fejl, jeg oftest ser i produktionsopsætninger.

Nøglebaseret signering med cloud-KMS til luftgab-miljøer

Ikke alle kan bruge keyless. Regulerede miljøer (banker, telco-core, defense) har ofte krav om, at signeringsnøglen skal ligge i en HSM, og at ingen ekstern tjeneste (Fulcio/Rekor) må konsulteres på tværs af et compliance-boundary. Cosign understøtter KMS-backends fra AWS, GCP, Azure, HashiCorp Vault og Kubernetes-native (via cosigned KeyRef).

# AWS KMS-eksempel
cosign sign \
  --key "awskms:///alias/prod-container-signing" \
  ghcr.io/example/api@sha256:abc123...

# Verifikation
cosign verify \
  --key "awskms:///alias/prod-container-signing" \
  ghcr.io/example/api@sha256:abc123...

# HashiCorp Vault (transit-engine)
export VAULT_ADDR="https://vault.internal:8200"
export VAULT_TOKEN="$(vault login -field=token -method=oidc)"
cosign sign \
  --key "hashivault://cosign-signer" \
  ghcr.io/example/api@sha256:abc123...

I luftgab-miljøer skal du også køre en intern Rekor-instans (deploy via helm chart rekor/rekor-server) eller acceptere at køre med --tlog-upload=false. Sidstnævnte er en betydelig sikkerhedsforringelse (du taber non-repudiation), men er nogle gange den eneste vej. Dokumentér valget i din trusselmodel.

Hvordan verificerer jeg en cosign-signatur i produktion?

Verifikation er det trin, hvor de fleste organisationer taber værdien af hele signeringsindsatsen. En cosign-verifikation skal tjekke fire ting: (1) at signaturen er kryptografisk gyldig, (2) at certifikatets identitet matcher en whitelistet identitet, (3) at OIDC-udstederen er den forventede, og (4) at posten er inkluderet i Rekor. Skipper du bare ét af de fire steps, har du ingen reel sikkerhed.

IMAGE="ghcr.io/example/api@sha256:abc123..."

cosign verify "$IMAGE" \
  --certificate-identity-regexp "^https://github.com/example/api/\.github/workflows/.+@refs/tags/v.+$" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  --certificate-github-workflow-repository "example/api" \
  --certificate-github-workflow-ref "refs/tags/v.*" \
  --output json | jq '.[0].optional'

Den regex, jeg bruger, tvinger tre ting: signeringen skete fra et workflow i det forventede repo (ikke en fork), på et tag (ikke en pull request), og fra en workflow-fil under .github/workflows/. Uden regex accepterer cosign enhver identitet, inklusive én angriberen har lavet i sit eget repo.

For runtime-verifikation i din klynge bør du læse vores gennemgang af runtime-beskyttelse af Linux-containere. Signaturverifikation er kun det første forsvarslag; når først containeren kører, er det syscall-filtrering og LSM-politikker, der begrænser blast radius, hvis noget alligevel sivede igennem.

Håndhævelse af signaturer i Kubernetes med Kyverno

Så her er sagen: det handler ikke om at verificere manuelt. Det handler om at gøre det umuligt at deploye et usigneret image. Kyverno 1.13 (juni 2026) har native Sigstore-integration og kan blokere admission af unsignede pods. Alternativet er Sigstore Policy Controller, som er lettere, men mindre fleksibel.

apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
  name: require-signed-images
spec:
  validationFailureAction: Enforce  # fail-closed
  webhookTimeoutSeconds: 30
  rules:
    - name: verify-signature
      match:
        any:
          - resources:
              kinds: [Pod]
              namespaces: ["prod-*"]
      verifyImages:
        - imageReferences:
            - "ghcr.io/example/*"
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/example/*/.github/workflows/*@refs/tags/v*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: "https://rekor.sigstore.dev"
          mutateDigest: true   # opløser tag -> digest før verifikation
          verifyDigest: true
          required: true

Tre detaljer, der bider dig, hvis du ikke sætter dem: validationFailureAction: Enforce (uden det, logger politikken bare), mutateDigest: true (så tags låses til digests ved admission), og required: true på attestor (ellers accepterer Kyverno et image, som du aldrig har lavet en attestor for). Test altid med kyverno-cli lokalt før rollout. En fejlkonfigureret Enforce-policy kan låse hele klyngen ude, og det er ikke sjovt en fredag eftermiddag.

SBOM- og SLSA-attestationer

En signatur siger, at nogen har verificeret et digest. En attestation siger noget om, hvordan det digest kom til verden: hvilke afhængigheder, hvilken commit, hvilken build-runner. SLSA v1.0 build-provenance er den mest udbredte attestation-type i 2026, og cosign gør det billigt at vedhæfte.

# Generér SBOM med syft
syft ghcr.io/example/api@sha256:abc123... -o spdx-json > sbom.spdx.json

# Vedhæft SBOM som attestation
cosign attest --yes \
  --predicate sbom.spdx.json \
  --type spdxjson \
  ghcr.io/example/api@sha256:abc123...

# GitHub Actions genererer SLSA v1.0-provenance automatisk
# med slsa-framework/[email protected]

# Verificér SLSA-provenance
cosign verify-attestation \
  --type slsaprovenance1 \
  --certificate-identity-regexp ".*slsa-github-generator.*" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  ghcr.io/example/api@sha256:abc123... | jq '.payload | @base64d | fromjson'

SBOM'en er ikke bare compliance-teater. Den kan queries af værktøjer som Trivy eller Grype for at få øjeblikkelig CVE-status, uden at rescanne image'et. Kombineret med den type automatiseret compliance-auditering vi bruger med OpenSCAP, får du en verificerbar audit-trail fra source til produktion.

Trusselmodel: Hvad bryder først?

Jeg spørger altid: "hvad bryder først, hvis vi rammes af hver enkelt komponent i denne kæde?" Det er den øvelse, der adskiller en fungerende opsætning fra en, der ser fin ud på en arkitekturtegning. Jeg ramte præcis dette scenarie i et audit sidste år, hvor kunden troede de var dækket ind, indtil vi kørte tabellen igennem sammen.

  • Kompromitteret CI-runner: angriberen kan signere et ondsindet image med gyldig identitet. Mitigation: pin runner-image via digest, brug ephemeral runners, log alle Rekor-poster til en SIEM (se vores Wazuh-guide til indtrængningsdetektion for indtag-pipelinen).
  • Kompromitteret Fulcio: teoretisk. Angriberen udsteder falske certifikater. Mitigation: Rekor gør misbrug offentligt reviderbart; tredjeparts-monitorer alarmerer.
  • Kompromitteret Rekor: angriberen kan skjule poster. Mitigation: klient tjekker inklusion-proof mod uafhængige witness-noder (Sigstore Trust Root, opdateret via TUF).
  • Kompromitteret Kyverno: admission-webhook går ned, klyngen fejler open. Mitigation: kør Kyverno HA (3+ replicas), sæt failurePolicy: Fail, monitorér webhook-latency.
  • Kompromitteret OIDC-udsteder: GitHub-tokens kan misbruges. Mitigation: stram certificate-identity-regexp, alarmer på signaturer fra uventede branches/tags.

Blast radius af det almindeligste scenario, altså en stjålet GitHub PAT, reduceres fra "kan push og deploye alt" til "kan push, men uden en gyldig OIDC-flow-signatur bliver det aldrig deployet". Det er den type reduktion, jeg forsvarer overfor mit CISO-board.

Sammenligning: Cosign vs Notation vs GPG

EgenskabCosign (Sigstore)Notation (Notary v2)GPG
Keyless signeringJa, via OIDCNejNej
TransparenslogRekor (default)Nej (planlagt)Nej
OCI-native artefakterJaJaNej (out-of-band)
KMS-supportAWS, GCP, Azure, VaultAWS, AzureKun via YubiKey/HSM
Kubernetes-håndhævelseKyverno, Policy ControllerRatifyCustom
SBOM/SLSA-attestationJa (native)Ja (v1.1+)Nej
Adoption 2026Meget højVoksendeLegacy
Registry-supportAlle OCIAlle OCISideløbende storage

Min anbefaling for 2026: Cosign er default. Notation er relevant, hvis din CNCF-værktøjskæde allerede er investeret i Notary v2 (typisk Azure-brugere), og GPG bør fases ud af alle nye pipelines. Det har ingen transparenslog, klodset nøglehåndtering og elendig integration med moderne CI. Se også den officielle cosign-oversigt for detaljerede forskelle.

Produktionsoprydning og observabilitet

To ting, der ofte glemmes. Rekor-poster vokser uendeligt (det er en append-only log), og det er ikke dit problem, medmindre du kører intern Rekor. I så fald: planlæg storage-vækst på ~500 MB per million poster. Og monitorér cosign-verifikationsfejl separat fra andre webhook-fejl i Kyverno. Den type fejl er ofte det tidligste tegn på et supply chain-angreb. Jeg ramte selv præcis det mønster i en kundes klynge i foråret, hvor et enkelt uventet verifikationsfejl viste sig at være en tester, der havde forsøgt at pushe et lokalt image forbi vores policy.

Ofte stillede spørgsmål

Hvad er forskellen mellem keyless og nøglebaseret signering?

Keyless bruger et 10-minutters certifikat udstedt af Fulcio baseret på et OIDC-token, så der er ingen langtidsholdbar privatnøgle. Nøglebaseret bruger en klassisk asymmetrisk nøgle, typisk gemt i en HSM eller KMS. Keyless er sikrere i CI-flows; nøglebaseret er nødvendig i luftgab- eller compliance-tunge miljøer.

Er Sigstore produktionsklar i 2026?

Ja. Fulcio, Rekor og cosign er alle GA og har været det siden 2022-2023. Fortune 500-virksomheder bruger den offentlige Sigstore-infrastruktur i produktion, og OpenSSF driver høje SLO'er. Til compliance-tunge workloads kan du desuden selv-hoste med helm charts fra sigstore/helm-charts.

Kan cosign signere andet end container-images?

Ja. Cosign kan signere vilkårlige filer og blobs med cosign sign-blob, samt Helm charts, Tekton bundles, WebAssembly-moduler og enhver OCI-artefakt. Signaturer og attestationer lagres som separate OCI-artefakter ved siden af det oprindelige artefakt.

Hvad sker der, hvis Rekor er nede?

Ved signering fejler cosign, medmindre du kører med --tlog-upload=false. Ved verifikation kan cosign v2 bruge en cached Rekor-kvittering (--rekor-offline-modus), hvilket er den anbefalede måde til luftgab-verifikation. Sigstore-tjenesten selv har 99.9% SLO.

Hvordan roterer jeg en KMS-baseret cosign-signeringsnøgle?

Signér de eksisterende images med den nye nøgle (cosign v2 understøtter flere signaturer per image), roll den nye nøgle ud i din Kyverno-policy som en accepteret attestor sideløbende med den gamle, verificér verifikationssucces i staging, fjern så den gamle. Rotation bør ske mindst kvartalsvist eller efter enhver mistænkt eksponering.

Aisha Okonkwo
Om Forfatteren Aisha Okonkwo

Infrastructure security architect at a hyperscaler. Spends her days on Zero Trust, secrets management, and yelling at unencrypted backups.