Firmas con Sigstore
Firma sin clave con la identidad del workflow, y qué se verifica exactamente.
Cómo se firma
No hay clave privada guardada en ningún sitio. Durante publish.yml, cosign sign-blob pide a GitHub un token OIDC que nombra el workflow, Fulcio emite un certificado de corta duración ligado a esa identidad, la firma se registra en Rekor y todo se guarda en un bundle .sigstore.json.
Dibujando el diagrama…
sequenceDiagram autonumber participant GA as GitHub Actions publish.yml participant OI as GitHub OIDC participant CO as cosign participant FU as Fulcio participant RE as Rekor participant GR as GitHub Releases participant CL as Client GA->>OI: request ID token (id-token write) OI-->>GA: JWT naming workflow, repository and ref GA->>CO: sign-blob manifest.json CO->>CO: ephemeral key pair CO->>FU: JWT and public key FU-->>CO: short lived certificate CO->>RE: signature and certificate RE-->>CO: signed entry timestamp CO-->>GA: manifest.sigstore.json bundle GA->>GR: attach manifest.json and the bundle CL->>GR: download both CL->>CL: verify chain to the trust root, signature, Rekor evidence, identity, issuer
Descripción del diagrama
Dentro de publish.yml, cosign pide a GitHub un token OIDC que nombra al workflow. Fulcio emite un certificado de corta duración ligado a esa identidad y a una clave efímera, cosign firma el blob, la firma se registra en Rekor y todo se guarda en un bundle. Más tarde un cliente verifica el bundle con la raíz de confianza de Sigstore y comprueba la identidad y el emisor.
Código Mermaid
sequenceDiagram
autonumber
participant GA as GitHub Actions publish.yml
participant OI as GitHub OIDC
participant CO as cosign
participant FU as Fulcio
participant RE as Rekor
participant GR as GitHub Releases
participant CL as Client
GA->>OI: request ID token (id-token write)
OI-->>GA: JWT naming workflow, repository and ref
GA->>CO: sign-blob manifest.json
CO->>CO: ephemeral key pair
CO->>FU: JWT and public key
FU-->>CO: short lived certificate
CO->>RE: signature and certificate
RE-->>CO: signed entry timestamp
CO-->>GA: manifest.sigstore.json bundle
GA->>GR: attach manifest.json and the bundle
CL->>GR: download both
CL->>CL: verify chain to the trust root, signature, Rekor evidence, identity, issuerQué se firma y con qué identidad
| Artefacto | Bundle |
|---|---|
manifest.json | manifest.sigstore.json |
checkpoint.txt | checkpoint.sigstore.json |
- Identidad del certificado:
https://github.com/MacGuard/macguard-yara-channel/.github/workflows/publish.yml@refs/heads/main. - Emisor OIDC:
https://token.actions.githubusercontent.com. - Repositorio del workflow:
MacGuard/macguard-yara-channel(--certificate-github-workflow-repository).
El paquete rules-release.tar.gz no se firma por separado: está cubierto porque el manifiesto firmado contiene el SHA-256 de cada fichero y rules_root, y se comprueba que el paquete contiene exactamente esos ficheros.
En MacGuard
La app incluye un cosign fijado (v3.1.1, con su SHA-256 comprobado) y una raíz de confianza trusted_root.json fijada; verifica sin red con --trusted-root. No existe una biblioteca Swift de Sigstore mantenida, por eso se usa cosign (ver DMGTrustAuditor/DMGTrustAuditor/docs/ADR-0001-sigstore-verification.md).
LÍMITE No hay atestaciones SLSA ni in-toto. Solo se firman dos blobs con Sigstore. Eso prueba qué workflow firmó esos bytes; no prueba por sí solo que el proceso de construcción fuera el esperado más allá de la identidad del workflow.
PROPUESTA Añadir atestaciones de procedencia (SLSA) sería un cambio de diseño; no está implementado ni planificado en este repositorio.