Sigstore Cosign 2.x v roce 2026: Kompletní průvodce podepisováním kontejnerů bez klíčů

Průvodce Sigstore Cosign 2.x v roce 2026: keyless podepisování container images přes OIDC, ověřování v Kubernetes Policy Controllerem, SLSA atestace a řešení nejčastějších chyb v produkčním nasazení.

Aktualizováno: 15. srpna 2026

Sigstore Cosign 2.x je open-source nástroj pro kryptografické podepisování container images a artefaktů, který v roce 2026 umožňuje takzvané „keyless" podpisy. Místo dlouhodobých soukromých klíčů využívá krátkodobé certifikáty vydané službou Fulcio na základě vaší OIDC identity (GitHub Actions, GitLab, Google, e-mail). Podpis je nesmazatelně zaznamenán do veřejného transparentního logu Rekor, takže kdokoli může nezávisle ověřit, že image opravdu pochází z konkrétní CI pipeline. Cosign je dnes de facto standard pro splnění SLSA Level 3 a je součástí praxe většiny bezpečnostně dospělých DevSecOps týmů.

  • Cosign 2.x zavádí keyless podepisování jako výchozí režim, takže soukromé klíče už nemusíte generovat ani rotovat.
  • Podpis se skládá ze tří artefaktů: samotného podpisu v OCI registru, krátkodobého certifikátu z Fulcio a záznamu v transparentním logu Rekor.
  • V GitHub Actions stačí přidat id-token: write a zavolat cosign sign. Žádné secrets, žádná správa klíčů, plná auditní stopa.
  • Pro produkční Kubernetes cluster se doporučuje Sigstore Policy Controller nebo Kyverno pro admission-time ověření podpisů a atestací.
  • Cosign umí vedle podpisů generovat i in-toto atestace (SBOM, provenance, výsledky skenování), které jsou stavebním kamenem SLSA Level 3.
  • Ověření podpisu bez správně omezené --certificate-identity a --certificate-oidc-issuer je bezpečnostně bezcenné. Vždy pinujte konkrétní workflow.

Co je Sigstore Cosign a proč podepisovat kontejnery v roce 2026

Sigstore je projekt OpenSSF (Open Source Security Foundation), který si dal za cíl zjednodušit podepisování softwarových artefaktů natolik, aby ho běžně používali i vývojáři, kteří dosud nikdy nepracovali s PKI. Cosign je jeho hlavní klientský nástroj. Zatímco Sigstore jako celek zahrnuje i certifikační autoritu Fulcio a transparentní log Rekor, Cosign je to, co spouštíte v CI a čím jako operátor ověřujete podpisy. Verze 2.x, která je v roce 2026 stabilní a produkčně nasazená u velkých hráčů jako Kubernetes, Istio, Helm nebo Distroless, přinesla dvě zásadní změny: keyless podepisování je výchozí režim a ephemeral klíče jsou automaticky zahazovány po podpisu.

Proč je to důležité právě teď? V posledních třech letech jsme viděli lavinu supply-chain útoků, od kompromitovaných npm balíčků přes injektované backdoory v XZ Utils až po škodlivé image v Docker Hubu. V mé praxi DevSecOps inženýra jsem viděl týmy, které měly perfektní skenování zranitelností kontejnerů pomocí Trivy, ale pak stahovaly „ověřený" base image z tagu latest, který v mezičase někdo přepsal. Popravdě, tenhle druh chyby je tichý a přijde na něj obvykle až incident response tým. Podpis image tento útok eliminuje: pokud policy v Kubernetes vyžaduje podpis od konkrétní GitHub workflow, žádný přepsaný tag ani typo-squattovaný image se do clusteru nedostane.

Podepisování kontejnerů také splňuje regulatorní požadavky. Executive Order 14028 v USA, evropský Cyber Resilience Act (CRA) a nová verze CIS Kubernetes Benchmarku všechny vyžadují nějakou formu ověřitelné provenience softwaru. Cosign je nejběžnější implementace, která splňuje SLSA Level 2 out-of-the-box a Level 3 při použití hermetických builderů.

Jak funguje keyless podepisování krok za krokem

Termín „keyless" je trochu zavádějící, protože klíč skutečně existuje, jen žije jen pár sekund. Celý proces vypadá takto: Cosign v okamžiku volání cosign sign vygeneruje ephemeral ECDSA klíčový pár přímo v paměti. Poté kontaktuje váš OIDC provider (GitHub Actions, GitLab, Google, Microsoft nebo interní Dex/Keycloak) a získá ID token, který dokazuje vaši identitu. Tento token pošle certifikační autoritě Fulcio, která vydá krátkodobý X.509 certifikát platný typicky 10 minut, s vaší identitou zapsanou do rozšíření Subject Alternative Name.

Cosign tímto certifikátem podepíše digest container image, uloží podpis do OCI registru vedle původního image (typicky jako sha256-XXX.sig tag) a nakonec záznam odešle do transparentního logu Rekor. Rekor je append-only Merkle-tree log s podpisy inklúze, takže žádný záznam už nikdy nelze skrytě odstranit ani přepsat. Soukromý klíč je pak zahozen a nikdy neopustí paměť procesu.

Ověření probíhá opačně. Verifier stáhne podpis a certifikát z registru, ověří certifikátový řetězec proti kořenovému certifikátu Sigstore, zkontroluje, že identita v SAN odpovídá očekávané workflow (např. https://github.com/mojefirma/repo/.github/workflows/release.yml@refs/tags/v1.2.3), a nakonec ověří inclusion proof v Rekoru s časovou známkou. Pokud kterýkoli krok selže, image je odmítnut.

Instalace Cosign 2.x na Linuxu a ověření integrity

Cosign distribuuje projekt jako statický Go binární soubor. Nikdy neinstalujte Cosign přes curl | bash. Je to sice ironické, ale i nástroj pro ověřování podpisů je třeba nejdřív bezpečně nainstalovat. Doporučuji vždy stáhnout binárku z GitHub Releases a ověřit její vlastní podpis (Cosign totiž podepisuje sám sebe).

# Zjistíme aktuální verzi z GitHub API
COSIGN_VERSION=$(curl -s https://api.github.com/repos/sigstore/cosign/releases/latest | jq -r .tag_name)
echo "Instalujeme Cosign ${COSIGN_VERSION}"

# Stáhneme binárku pro Linux amd64
curl -sSL -o cosign "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64"

# Stáhneme certifikát a podpis samotné binárky
curl -sSL -o cosign.pem "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64-keyless.pem"
curl -sSL -o cosign.sig "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64-keyless.sig"

# Ověříme SHA-256 checksum proti oficiálním hodnotám
curl -sSL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign_checksums.txt" | \
  grep cosign-linux-amd64$ | sha256sum -c -

# Umístíme binárku do PATH s bezpečnými právy
sudo install -m 0755 cosign /usr/local/bin/cosign
cosign version

Pro produkční servery preferuji instalaci přes distribuční balíček. Fedora 40+ a RHEL 9 mají Cosign v EPEL, Ubuntu 24.04 v universe. Pokud spravujete flotilu strojů s Ansible, ideální je vlastní repository se signed .deb nebo .rpm balíčky. Nikdy neinstalujte Cosign z náhodných třetích repositorů, protože kompromitace instalačního nástroje pro ověřování podpisů by byla noční můra.

Po instalaci vytvořte pracovní prostředí. Cosign 2.x nemá žádný konfigurační soubor, veškeré chování se řídí flagy a proměnnými prostředí. Užitečné je nastavit COSIGN_EXPERIMENTAL=0. V Cosign 2.x už to není potřeba, ale explicitní deklarace pomáhá udržet skripty portovatelné mezi verzemi.

Podepisování container image v GitHub Actions pipeline

Toto je scénář, který nasazuji nejčastěji. Cíl: pokaždé, když se merguje do main, sestavit image, pushnout do GHCR a podepsat ho pomocí GitHub OIDC tokenu, bez jediného secretu v repozitáři. Kompletní workflow vypadá takto.

name: build-and-sign
on:
  push:
    branches: [main]
    tags: ['v*']

permissions:
  contents: read
  packages: write       # push do GHCR
  id-token: write       # keyless podpis přes OIDC

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

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@v3

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

      - name: Build and push
        id: build
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
          # Digest je stabilnější než tag, používáme ho pro podpis
          outputs: type=image,name=ghcr.io/${{ github.repository }},push-by-digest=true,name-canonical=true

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

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

      - name: Attach SBOM as attestation
        env:
          DIGEST: ${{ steps.build.outputs.digest }}
        run: |
          syft "ghcr.io/${{ github.repository }}@${DIGEST}" -o spdx-json > sbom.spdx.json
          cosign attest --yes \
            --predicate sbom.spdx.json \
            --type spdxjson \
            "ghcr.io/${{ github.repository }}@${DIGEST}"

Klíčové řádky jsou id-token: write a push-by-digest=true. První dává jobu právo vyžádat OIDC token od GitHub, druhý zajišťuje, že podepisujeme přímo digest, ne tag (tag lze přepsat, digest ne). Také si všimněte absence jakéhokoli COSIGN_KEY secretu, protože celá autentizace probíhá přes ephemeral OIDC token, který GitHub vloží do prostředí. Pro hlubší kontext nad zabezpečením celé pipeline doporučuji můj starší text o zabezpečení GitHub Actions a ochraně dodavatelského řetězce.

Ověřování podpisů v Kubernetes s Policy Controllerem

Podpis, který nikdo neověřuje, je bezcenný. Poctivě řečeno, tenhle problém jsem viděl u dvou třetin týmů, kterým jsem pomáhal Cosign zavést. V Kubernetes máte dvě mainstreamové možnosti: Sigstore Policy Controller (dříve cosigned), který je maintainovaný přímo Sigstore týmem, a Kyverno, obecnější policy engine s nativní podporou Sigstore verifikace. V mé praxi doporučuji Policy Controller pro projekty, kde jde primárně o podpisy, a Kyverno tam, kde už Kyverno běží pro jiné policies (network policies, resource limits, atd.).

Instalace Policy Controlleru přes Helm:

helm repo add sigstore https://sigstore.github.io/helm-charts
helm repo update
helm install policy-controller sigstore/policy-controller \
  --namespace cosign-system --create-namespace \
  --version 0.10.0

Poté označíme namespace, kde má admission controller vynucovat podpisy, a definujeme ClusterImagePolicy:

kubectl label namespace production policy.sigstore.dev/include=true

cat <<'EOF' | kubectl apply -f -
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
  name: require-signed-from-our-org
spec:
  images:
    - glob: "ghcr.io/mojefirma/**"
  authorities:
    - name: keyless-github
      keyless:
        url: https://fulcio.sigstore.dev
        identities:
          - issuer: https://token.actions.githubusercontent.com
            subjectRegExp: "^https://github\\.com/mojefirma/.*/\\.github/workflows/release\\.yml@refs/tags/v.*$"
      ctlog:
        url: https://rekor.sigstore.dev
EOF

Tato policy říká: každý image z ghcr.io/mojefirma/*, který se pokusí naběhnout v označeném namespace, musí mít keyless podpis od Fulcio, vydaný pro GitHub Actions workflow release.yml na tagu v* v naší organizaci. Ostatní podepsané image (třeba z fork PR) budou odmítnuty. Regulární výraz subjectRegExp je nejdůležitější řádek celé konfigurace, protože bez něj by policy přijala jakýkoli podpis od kohokoliv, kdo má GitHub účet.

Pro lokální ověření na CLI slouží cosign verify:

cosign verify \
  --certificate-identity-regexp "^https://github\.com/mojefirma/.*" \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/mojefirma/api:v1.2.3

Cosign vs Notation vs Docker Content Trust: které řešení zvolit

V ekosystému existují tři hlavní konkurenční přístupy k podepisování OCI artefaktů. Vybrat mezi nimi není triviální; každý řeší trochu jiný problém.

VlastnostCosign 2.xNotation 1.xDocker Content Trust (DCT)
GovernanceOpenSSF / SigstoreCNCF (Notary Project)Docker Inc. (deprecated)
Keyless režimAno (OIDC + Fulcio)Ne (jen X.509 s vlastní PKI)Ne (offline TUF klíče)
Transparentní logAno (Rekor)Volitelné (blob storage)Ne
Atestace (SBOM, provenance)Ano (in-toto)Ano (v1.1+)Ne
Podpora v KubernetesPolicy Controller, Kyverno, OPA GatekeeperRatify, KyvernoŽádná admission integrace
Adopce (2026)Vysoká (Kubernetes, Istio, Helm, Distroless)Střední (Azure ACR, AWS ECR)Nízká, projekt EOL
Křivka učeníNízkáStřední (nutná PKI)Vysoká

Doporučení: pro většinu týmů volte Cosign. Notation dává smysl v prostředí, kde už máte HSM-based PKI a compliance vyžaduje offline root of trust (typicky finance, obrana). Docker Content Trust byste v roce 2026 už neměli nasazovat, protože projekt neprošel modernizací a Docker sám doporučuje migraci na Cosign nebo Notation.

SBOM a in-toto atestace pro SLSA Level 3

Podpis dokazuje „tento image sestavil někdo s touto identitou". SLSA Level 3 vyžaduje víc. Musíte doložit „jaké přesně komponenty jsou uvnitř" (SBOM), „z jakého zdrojového kódu byly sestaveny" (provenance) a „v jakém prostředí" (hermetic builder). Cosign k tomu používá formát in-toto atestací.

Kompletní workflow s Trivy skenováním a Syft SBOM:

# 1. Vygenerujeme SBOM
syft ghcr.io/mojefirma/api@sha256:abc... -o cyclonedx-json > sbom.cdx.json
cosign attest --yes \
  --predicate sbom.cdx.json \
  --type cyclonedx \
  ghcr.io/mojefirma/api@sha256:abc...

# 2. Přidáme výsledky Trivy skenování jako atestaci
trivy image --format cosign-vuln \
  --output vuln.json \
  ghcr.io/mojefirma/api@sha256:abc...
cosign attest --yes \
  --predicate vuln.json \
  --type vuln \
  ghcr.io/mojefirma/api@sha256:abc...

# 3. Attest provenance (SLSA v1.0)
cosign attest --yes \
  --predicate provenance.json \
  --type slsaprovenance1 \
  ghcr.io/mojefirma/api@sha256:abc...

Každá atestace je uložena jako samostatný OCI artefakt vedle image a je sama o sobě podepsána stejným keyless mechanismem. V ověřovacím kroku můžete použít cosign verify-attestation --type cyclonedx a v Kyverno/Policy Controlleru vyžadovat, aby SBOM neobsahoval balíčky s CVE severity ≥ HIGH. To je moment, kdy podpis přestává být formalitou a stává se skutečnou obranou proti supply-chain útokům.

Pro správu artefaktů a rotaci klíčů v případě, že přece jen musíte použít key-based režim (například pro root of trust pro interní Fulcio), se vyplatí propojit Cosign s trezorem, jako je HashiCorp Vault nebo OpenBao. Podrobněji jsem tento vzor rozebíral v článku o OpenBao a správě secrets na Linuxu.

Časté chyby při nasazení Cosign a jak se jim vyhnout

Během dvou let, kdy pomáhám týmům zavádět Cosign, se pořád opakují stejné chyby. Popravdě, právě tenhle konkrétní scénář jsem řešil naposledy u finančního klienta loni na podzim. Pojďme si je projít.

1. Verifikace bez omezení identity

Nejčastější chyba je zavolat cosign verify bez flagů --certificate-identity a --certificate-oidc-issuer. Taková verifikace pouze potvrdí, že podpis existuje a je platný, ale nekontroluje, kdo ho udělal. Útočník s libovolným GitHub účtem si může podepsat vlastní malicious image a projde. Vždy pinujte konkrétní workflow a issuer.

2. Podepisování tagu místo digestu

Tag latest nebo v1.2.3 lze přepsat. Pokud podpis váže na tag, útočník s právem push může tag přepsat a podpis zůstane platný pro původní digest, ale při docker pull stáhnete jiný obsah. Vždy podepisujte image@sha256:... digest.

3. Ignorování Rekor timestamp

Certifikát z Fulcio platí jen 10 minut. Když ho ověřujete o měsíce později, potřebujete důkaz, že podpis vznikl v době platnosti certifikátu. To zajišťuje inclusion proof v Rekoru s časovou známkou. Cosign to dělá automaticky, ale při offline verifikaci (například v air-gapped clusteru) musíte explicitně dodat --rekor-url nebo bundle s offline verifikací.

4. Nesledování rate limitů Sigstore public infrastruktury

Veřejná Sigstore infrastruktura je zdarma, ale má rate limity. V CI, která podepisuje stovky image za hodinu, se občas setkáte s HTTP 429. Řešení: nasadit lokální mirror Fulcio a Rekor, nebo použít komerční Sigstore-as-a-service (Chainguard, GitLab Sigstore proxy).

5. Zapomenutá id-token: write permission

GitHub Actions ve výchozím stavu OIDC token neexponuje. Bez explicitního permissions: id-token: write v jobu Cosign spadne s chybou „no OIDC token available". Doporučuji tuto permission dávat jen do jobů, které opravdu podepisují, ne globálně na workflow úroveň.

Často kladené otázky

Je Sigstore Cosign zdarma?

Ano, Cosign je open-source pod licencí Apache 2.0 a veřejná Sigstore infrastruktura (Fulcio + Rekor) je poskytována zdarma pro OSS i komerční projekty. Pokud potřebujete SLA nebo dedikovanou instanci, existují komerční nabídky od Chainguard, GitLab a dalších.

Jak ověřím podepsaný container image bez klíče?

Použijte cosign verify --certificate-identity-regexp "..." --certificate-oidc-issuer "..." image:tag. Cosign stáhne podpis a certifikát z registru, ověří řetězec proti Sigstore root a zkontroluje shodu identity v SAN s vaším regexem. Bez těchto flagů verifikace neposkytuje žádnou reálnou bezpečnost.

Jaký je rozdíl mezi podpisem a atestací v Cosign?

Podpis (cosign sign) dokazuje pouze integritu a autorství image. Atestace (cosign attest) je podepsaný dokument v in-toto formátu, který k image přidává strukturovaná metadata: SBOM, výsledky skenování zranitelností, provenance z builderu. Oba mechanismy sdílejí stejný keyless workflow, ale slouží k odlišným cílům.

Funguje Cosign i mimo Kubernetes, například v čistém Dockeru?

Ano. Cosign pracuje přímo s OCI registrem, takže funguje s Docker Enginem, Podmanem, containerd i jakýmkoli jiným runtime. Pro vynucení verifikace při docker pull mimo Kubernetes existují nástroje jako Docker Scout, notation-plugin-cosign nebo podman s containers-policy.json.

Musím kvůli Cosign migrovat pryč z Docker Hubu?

Ne. Cosign podpis ukládá jako běžný OCI artefakt s příponou .sig ve stejném registru jako image. Docker Hub, GHCR, Quay, ECR, ACR, GCR i Harbor toto všechno bez problému podporují. Pouze registry starší než OCI 1.0 (velmi vzácné dnes) by nemusely fungovat.

Co se stane, když je Sigstore veřejná infrastruktura offline?

Pokud je Fulcio nedostupný, nové podpisy nejdou vytvořit, ale ověření existujících podpisů funguje dál díky offline bundle s inclusion proofem z Rekoru. Pro produkční prostředí, které nesmí spadnout se Sigstore, se doporučuje self-hosted Fulcio + Rekor nebo použití komerční redundantní infrastruktury s SLA.

Raj Patel
O Autorovi Raj Patel

DevSecOps engineer who's gradually turning every CI pipeline he sees into a security-checking machine.