Sigstore a Cosign — Podpisovanie Container Images
Sigstore je open-source projekt pod Linux Foundation / OpenSSF, ktorý prináša jednoduché, bezplatné a automatizovateľné digitálne podpisovanie softvérových artefaktov — container images, binárok, git tagov, SBOM súborov — bez potreby manuálne spravovaných kľúčov.
Jeho hlavná myšlienka je radikálne zjednodušiť podpisovanie: namiesto dlhodobých GPG alebo PGP kľúčov používa krátke, jednorazové certifikáty viazané na OIDC identitu (GitHub, Google, GitLab, Microsoft, custom IdP). Výsledok: podpis môžete overiť späť na konkrétny GitHub Actions workflow alebo konkrétneho človeka bez toho, aby ste si spravovali súkromný kľúč.
Prečo supply-chain security je problém
Za posledných päť rokov sa útoky na softvérový supply-chain stali bežnou praxou:
- SolarWinds (2020) — útočník vsadil backdoor do build pipeline, ktorá sa rozšírila na 18 000 zákazníkov.
- Codecov (2021) — kompromitovaný bash uploader získal env premenné tisícov CI behov.
- ua-parser-js (2021) — npm package s 8M downloads týždenne bol injektovaný malware.
- xz-utils (2024) — backdoor v utility, ktorý bol takmer nasadený do ssh vo veľkých distribúciách.
Klasická odpoveď bola: "podpíšte svoj softvér GPG kľúčom". V praxi to nefunguje — developeri strácajú kľúče, CI runnery nemajú kam bezpečne uložiť privátny kľúč, rotácia je ťažká, verifikácia sa nerobí.
Sigstore nabúral tento model tým, že kľúče sú krátkodobé (platia 10 minút) a podpis je viazaný na identitu v čase podpisu (OIDC token), nie na dlhodobý kľúč.
Komponenty Sigstore
Sigstore stojí na troch hlavných komponentoch:
1. Fulcio — certifikačná autorita
Krátkodobá CA, ktorá vystaví X.509 certifikát platný 10 minút na základe overeného OIDC tokenu. Certifikát obsahuje identitu (napr. user@example.com alebo https://github.com/org/repo/.github/workflows/release.yml@refs/tags/v1.2.3).
2. Rekor — transparency log
Verejný, append-only log, do ktorého sa zapisujú všetky podpisy. Podobný Certificate Transparency logom pre TLS certifikáty. Ak niekto použije identitu na podpis, zanechá verejne dohľadateľnú stopu.
3. Cosign — CLI a knižnica
Klientský nástroj, ktorý orchestuje celé signing/verify kroky: získa OIDC token, požiada Fulcio o certifikát, podpíše artefakt, zapíše do Rekoru a nahrá podpis ako OCI artefakt vedľa imagu v registry.
Verejná inštancia Sigstore (Fulcio + Rekor) je prevádzkovaná OpenSSF zadarmo. Firmy môžu prevádzkovať vlastnú (napr. cez sigstore/scaffolding).
Keyless signing — ako to funguje
┌─────────┐ ┌─────────┐
│ Cosign │─── OIDC login ───►│ OIDC │
│ (local) │ │ Provider│
└────┬────┘ │ (GitHub)│
│ └────┬────┘
│ ◄──── token ─────────────┘
│
│ token + pubkey
▼
┌─────────┐
│ Fulcio │──► certifikát (10 min)
└────┬────┘
│
▼
┌─────────┐
│ Rekor │◄── zapis hash + podpis
└────┬────┘
│
▼
┌─────────┐
│ OCI │◄── signature artifact pripojeny k imagu
│ Registry│
└─────────┘
Z pohľadu developera je to jedna komanda:
cosign sign ghcr.io/myorg/myapp:v1.2.3
Cosign otvorí browser, prihlási sa cez GitHub, získa token, zavolá Fulcio, podpíše, zapíše do Rekoru. Hotovo.
Praktický príklad 1 — signing a verify lokálne
# Nainštaluj cosign
curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
chmod +x cosign-linux-amd64 && sudo mv cosign-linux-amd64 /usr/local/bin/cosign
# Podpíš image (interaktívne OIDC)
cosign sign ghcr.io/myorg/myapp:v1.2.3
# Overenie
cosign verify ghcr.io/myorg/myapp:v1.2.3 \
--certificate-identity=user@example.com \
--certificate-oidc-issuer=https://github.com/login/oauth
cosign verify skontroluje:
- Podpis matchuje digest imagu.
- Certifikát bol vystavený Fulciom a obsahuje očakávanú identitu.
- Záznam v Rekor logu existuje a tagovanie časom je konzistentné.
Ak overenie zlyhá, exit code != 0. Vhodné na CI gate alebo admission controller v Kubernetes.
Praktický príklad 2 — GitHub Actions
V GH Actions netreba žiadny interaktívny login — OIDC token sa generuje automaticky z workflow:
name: Build and Sign
on:
push:
tags: ["v*"]
permissions:
contents: read
id-token: write # povoli OIDC
packages: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- 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:
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}
- name: Install Cosign
uses: sigstore/cosign-installer@v3
- name: Sign image (keyless)
run: |
cosign sign --yes \
ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
Identita v certifikáte bude niečo ako:
https://github.com/myorg/myrepo/.github/workflows/release.yml@refs/tags/v1.2.3
Toto je cryptographically verifiable provenance — ktorá konkrétna verzia ktorého workflow v ktorom repe podpísala tento image. Pri verifikácii to viete presne skontrolovať.
Attestations — SBOM a SLSA provenance
Cosign dokáže pripojiť nielen podpis, ale aj attestácie — podpísané metadáta o tom, ako bol image vyrobený:
# SBOM attestation (CycloneDX)
cosign attest --yes \
--predicate sbom.cdx.json \
--type cyclonedx \
ghcr.io/myorg/myapp:v1.2.3
# SLSA provenance
cosign attest --yes \
--predicate provenance.json \
--type slsaprovenance \
ghcr.io/myorg/myapp:v1.2.3
Pri verifikácii:
cosign verify-attestation \
--type cyclonedx \
--certificate-identity-regexp='https://github.com/myorg/.*' \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
ghcr.io/myorg/myapp:v1.2.3
Dostanete späť podpísaný SBOM. Tým sa odomkýnajú policy otázky ako: "Nasadím iba image, ktorý má SBOM, kde žiadna komponenta nemá CVE nad severity 8.5". SBOM sa nedá ex-post podhodiť.
Detailnejší pohľad na supply chain security a SLSA nájdete v článku Supply Chain Security.
Policy enforcement — admission controllers
Samotný podpis je zbytočný, ak ho nikto pri deployi neoveruje. V Kubernetes sa na to používajú admission controllery:
1. Kyverno + Cosign
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: verify-signed-images
spec:
validationFailureAction: Enforce
rules:
- name: check-signature
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "ghcr.io/myorg/*"
attestors:
- entries:
- keyless:
subjectRegExp: "https://github.com/myorg/.*"
issuer: https://token.actions.githubusercontent.com
Každý Pod v klastri musí používať image, ktorý má valid Sigstore podpis s identitou z myorg GitHub Actions. Všetky ostatné images sú admission-rejected.
2. Sigstore Policy Controller
Natívny controller od Sigstore, jednoduchšia alternatíva:
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
name: myorg-keyless
spec:
images:
- glob: "ghcr.io/myorg/**"
authorities:
- keyless:
identities:
- issuer: https://token.actions.githubusercontent.com
subjectRegExp: "https://github.com/myorg/.*"
3. OPA / Gatekeeper
Rovnaký princíp, cez OPA rules. Viac konfigurácie, väčšia flexibilita.
Cosign vs klasické GPG signing
| Aspekt | GPG signing | Cosign keyless |
|---|---|---|
| Key management | Dlhodobé kľúče, treba rotovať | Žiadne — krátkodobé certs |
| CI integration | Treba injektovať privátny kľúč | Natívne cez OIDC |
| Identity | Kľúč = identita (slabé) | OIDC provider + Rekor log |
| Transparency | Žiadna | Verejný Rekor log |
| Revocation | Komplikované | Nepotrebné (krátke certs) |
| Verification | gpg --verify |
cosign verify + identity check |
Pre moderné CI/CD je Cosign dramaticky jednoduchší a bezpečnejší.
Produkčné tipy
- Nie každý image treba podpisovať — začnite s production imagmi a postupne pridávajte.
- Monitorujte Rekor log — nástroj
rekor-cli searchnájde všetky podpisy vytvorené vašou identitou. Užitočné na detekciu zneužitia. - Verify pri deploy, nie pri pull — registry vám tag prepíše, podpis to neochráni. Deploy gate je správne miesto.
- Identity pinning — neustále používajte
--certificate-identitya--certificate-oidc-issuer. Bez nich jecosign verifytakmer useless. - Self-hosted Sigstore — veľké firmy (Google, GitHub, Chainguard) si prevádzkujú vlastné inštancie Fulcio + Rekor pre compliance.
Zhrnutie
Sigstore a cosign posunuli signing z "something only paranoid infra teams do" do "default step v každom release workflow". Inštalácia trvá minúty, integrácia s GitHub Actions je triviálna, policy enforcement cez Kyverno alebo Sigstore Policy Controller uzatvára krúh medzi "podpis vznikol" a "podpis sa overí pred deployom".
Ak dnes staviate image pipeline a chcete vedieť odpovedať na otázku "kto a čím vyrobil tento konkrétny container image?", Sigstore je jediná rozumná odpoveď.