Ir para o conteúdo

Release attestations: Sigstore + GitHub Actions

Diátaxis: explanation. Para o como executar, veja scripts/release-attestation.sh e a seção "Verificar release" abaixo.

Este documento explica por que o Anotae usa Sigstore para attestations de release e como o modelo se encaixa em CLAUDE.md §1 — supply chain.


Problema

Distribuição binária open-source enfrenta dois ataques canônicos:

  1. Adulteração na entrega: alguém intercepta o ZIP/wheel entre o servidor e o usuário.
  2. Comprometimento da chave: a chave privada do mantenedor vaza, atacante assina binário malicioso com a chave legítima.

A defesa clássica é Authenticode (Microsoft) ou GPG-sign do mantenedor. Ambos sofrem do problema 2: a chave precisa estar em algum lugar (HSM, smart card, laptop) e é a superfície de ataque.

Por que Sigstore (PEP 740)

Sigstore introduz assinatura keyless baseada em OIDC + transparency log público:

  1. O processo que assina (CI, dev, etc.) prova sua identidade via OIDC (GitHub Actions, Google, Microsoft).
  2. Um certificado X.509 efêmero é emitido pelo Fulcio vinculando essa identidade à assinatura.
  3. A assinatura + cert efêmero são gravados em Rekor — um transparency log público append-only.
  4. Não existe chave privada longa duração. Ataque clássico fica sem alvo.

Para o Anotae:

  • Identidade do signer = workflow .github/workflows/build-windows.yml rodando na branch/tag específica do repositório carlosefdeavila/anotae.
  • Verificador consegue checar offline (com Rekor) que aquele exato workflow rodou e produziu aquele exato hash.

PEP 740 padroniza isso para distribuições Python (e ZIP genérico) via sigstore-python.

Modelo no Anotae

Em CI (release oficial)

.github/workflows/build-windows.yml:

  1. Builda Anotae-windows-x64.zip com PyInstaller.
  2. sigstore/gh-action-sigstore-python@v3 produz Anotae-windows-x64.zip.sigstore (bundle JSON).
  3. Ambos sobem para o GitHub Release como assets.

Permissões necessárias no workflow:

permissions:
  contents: write   # criar release + uploads
  id-token: write   # solicitar token OIDC ao GitHub

Localmente (dev / dry-run)

scripts/release-attestation.sh:

# assinar (abre browser para auth OIDC do GitHub/Google/MS)
scripts/release-attestation.sh sign dist/Anotae-windows-x64.zip

# verificar bundle adjacente
scripts/release-attestation.sh verify dist/Anotae-windows-x64.zip

O script é wrapper de sigstore sign|verify — toda lógica criptográfica fica no sigstore-python upstream.

Verificar release

Qualquer pessoa pode checar que um release veio do workflow oficial:

pip install sigstore

# baixe o ZIP e o .sigstore.json do GitHub Release; depois:
sigstore verify github \
  --repository carlosefdeavila/anotae \
  --bundle Anotae-windows-x64.zip.sigstore.json \
  Anotae-windows-x64.zip

verify github confirma:

  • Hash do ZIP bate com a assinatura registrada em Rekor.
  • A identidade do signer é um workflow do repositório oficial.
  • Cert efêmero está dentro da janela de validade Fulcio.

Se bater: o ZIP veio do CI oficial e não foi alterado desde.

Por que NÃO usar só Authenticode

CLAUDE.md §1 registra: "Code signing Authenticode tradicional: avaliar após 6 meses se SmartScreen friction se materializar".

Razões para preferir Sigstore como primeiro nível:

Critério Sigstore Authenticode
Custo $0 $200–$500/ano por cert
Chave longa não há precisa proteger HSM
Verificável por terceiros sem proprietário sim (Rekor público) signtool MS
Cobre Linux/macOS sim não
Reduz friction SmartScreen parcial melhor

A combinação ideal eventualmente: Sigstore para auditoria pública + Authenticode para reduzir friction Windows. Por ora, Sigstore sozinho resolve o problema de cadeia de confiança aberta. Vamos agregar Authenticode quando o feedback do beta indicar que SmartScreen está sendo barreira de adoção.

SLSA + SBOM

Sigstore attestation é o bloco de cadeia de confiança. Encaixa com:

  • SBOM CycloneDX (já em CI) — o que está dentro.
  • SLSA L1 (CLAUDE.md §1) — proveniência do build.
  • Reproducible build (SOURCE_DATE_EPOCH + diffoscope) — bate com binário publicado.

Cada um cobre uma pergunta diferente:

Pergunta Resposta
O artefato veio do código que diz vir? Sigstore
Quais dependências tem dentro? SBOM
O build é determinístico? SOURCE_DATE_EPOCH + diffoscope
Quem rodou o build? OIDC identity em Rekor

Quando reabrir esta decisão

  • Adoção lenta porque Windows SmartScreen friction se materializa → considerar Authenticode em paralelo.
  • Sigstore Foundation muda governança drasticamente → avaliar alternativa (e.g., Notary v2).
  • Necessidade de assinatura ICP-Brasil para conformidade regulatória (CFM, Anvisa) → adicionar terceiro nível, não substituir Sigstore.