MACGUARD · DOCUMENTATION
Español

Sigstore signatures

Keyless signing with the workflow identity, and what exactly is verified.

How signing works

There is no private key stored anywhere. During publish.yml, cosign sign-blob asks GitHub for an OIDC token naming the workflow, Fulcio issues a short-lived certificate bound to that identity, the signature is recorded in Rekor and everything is stored in a .sigstore.json bundle.

Diagram: Keyless signing and verification

Drawing the diagram…

Diagram description

Inside publish.yml, cosign asks GitHub for an OIDC token that names the workflow. Fulcio issues a short-lived certificate bound to that identity and an ephemeral key, cosign signs the blob, the signature is recorded in Rekor and everything is stored in a bundle. A client later verifies the bundle against the Sigstore trust root and checks the identity and the issuer.

Mermaid code
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

What is signed and with which identity

ArtifactBundle
manifest.jsonmanifest.sigstore.json
checkpoint.txtcheckpoint.sigstore.json

The package rules-release.tar.gz is not signed separately: it is covered because the signed manifest contains the SHA-256 of each file and rules_root, and the package is checked to contain exactly those files.

In MacGuard

The app ships a pinned cosign (v3.1.1, SHA-256 checked) and a pinned trusted_root.json trust root; it verifies offline with --trusted-root. There is no maintained Swift Sigstore library, which is why cosign is used (see DMGTrustAuditor/DMGTrustAuditor/docs/ADR-0001-sigstore-verification.md).

LIMIT There are no SLSA or in-toto attestations. Only two blobs are signed with Sigstore. That proves which workflow signed those bytes; by itself it does not prove the build process was the expected one beyond the workflow identity.
PROPOSED Adding provenance attestations (SLSA) would be a design change; it is not implemented or scheduled in this repository.