Release attestations: Sigstore + GitHub Actions¶
Diátaxis: explanation. Para o como executar, veja
scripts/release-attestation.she 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:
- Adulteração na entrega: alguém intercepta o ZIP/wheel entre o servidor e o usuário.
- 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:
- O processo que assina (CI, dev, etc.) prova sua identidade via OIDC (GitHub Actions, Google, Microsoft).
- Um certificado X.509 efêmero é emitido pelo Fulcio vinculando essa identidade à assinatura.
- A assinatura + cert efêmero são gravados em Rekor — um transparency log público append-only.
- 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.ymlrodando na branch/tag específica do repositóriocarlosefdeavila/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:
- Builda
Anotae-windows-x64.zipcom PyInstaller. sigstore/gh-action-sigstore-python@v3produzAnotae-windows-x64.zip.sigstore(bundle JSON).- 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) | só 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.