Cosign na prática exige decidir antes qual identidade você aceita e qual artefato quer verificar. Uma assinatura válida de qualquer pessoa não basta. Uma tag conhecida também não fixa, por si, os bytes da imagem. O teste útil combina digest, identidade esperada, emissor OIDC e recusa quando essa política não é atendida.
Em 22/10/2026, executamos uma verificação de leitura da imagem pública do próprio Cosign. A identidade oficial passou; uma identidade diferente e um emissor diferente foram recusados. Não assinamos, enviamos ou executamos a imagem, não acessamos registros privados e não alteramos um pipeline de produção.
Neste artigo
Três perguntas, três informações
Qual artefato? O digest identifica o conteúdo do manifesto ou índice consultado. Uma referência como repositorio@sha256:... evita depender de uma tag que pode ser movida. Em imagem multiplataforma, é importante distinguir o índice do manifesto específico de uma arquitetura.
Qual identidade assinou? Na verificação baseada em identidade, a assinatura é associada a um certificado. A política precisa dizer qual identidade é aceita, não simplesmente aceitar a primeira que aparecer no resultado.
Qual provedor OIDC atestou a identidade? O emissor OIDC também integra a política. Ele não é a autoridade certificadora: no fluxo keyless do Sigstore, o Fulcio emite o certificado de assinatura com base na identidade autenticada via OpenID Connect. O parâmetro --certificate-oidc-issuer confere o provedor OIDC registrado nesse certificado; não basta aceitar o mesmo identificador sob qualquer provedor.
O guia oficial de verificação do Cosign apresenta os parâmetros de identidade e emissor e verifica, por padrão, as declarações que ligam a assinatura ao artefato. Não desative essas checagens para transformar uma falha em resultado verde.
Política e artefato usados no ensaio
A documentação de instalação e verificação das releases do Sigstore informa a identidade e o emissor esperados para suas imagens. Usamos esses valores publicados pelo projeto, não uma identidade descoberta na assinatura e aceita depois do fato.
| Campo | Valor do ensaio |
|---|---|
| Ferramenta | Cosign v3.1.4, darwin/arm64 |
| Referência consultada inicialmente | ghcr.io/sigstore/cosign/cosign:v3.1.4 |
| Identidade esperada | [email protected] |
| Emissor OIDC esperado | https://accounts.google.com |
| Objeto verificado | Índice da imagem, fixado pelo digest abaixo |
O digest foi obtido do registro público e confrontado com o SHA-256 do conteúdo recebido. A partir daí, os comandos usaram a referência imutável, não voltaram à tag. Isso fixa o objeto do teste, mas não torna o registro uma fonte independente da identidade do publicador.
O executável veio da release v3.1.4, com hash comparado ao metadado da API do GitHub. Esse bootstrap depende de HTTPS e da origem GitHub; não executamos uma validação independente da raiz de confiança do binário. Para estabelecer a ferramenta em um ambiente de produção, siga também o procedimento de autenticidade da distribuição indicado pelo Sigstore. Não confunda o teste da imagem com uma auditoria completa de toda a cadeia usada para testá-la.
Comando positivo, com digest fixo
Com uma instalação confiável do Cosign, estes foram os valores passados ao comando:
IMAGE='ghcr.io/sigstore/cosign/cosign@sha256:0f06154836d2de34f887a5c273506d52ca43edaa1d9e53e6510fa78a48f69c2d'
IDENTITY='[email protected]'
ISSUER='https://accounts.google.com'
cosign verify "$IMAGE" \
--certificate-identity "$IDENTITY" \
--certificate-oidc-issuer "$ISSUER"
O comando terminou com código de saída 0. A saída continha docker-manifest-digest igual ao digest fixado e a versão v3.1.4 nas informações opcionais. O diagnóstico também informou verificação das declarações, do certificado e da evidência do log de transparência.
O termo “offline” no diagnóstico da prova do log não significa que o experimento inteiro dispensou rede: o comando consultou o registro e utilizou material de confiança do Sigstore. Também não se deve concluir que a imagem foi executada apenas porque sua assinatura foi verificada.
Controles negativos: precisa falhar pelo motivo certo
Repetimos a verificação do mesmo digest, mudando somente um elemento da política por vez:
cosign verify "$IMAGE" \
--certificate-identity '[email protected]' \
--certificate-oidc-issuer "$ISSUER"
cosign verify "$IMAGE" \
--certificate-identity "$IDENTITY" \
--certificate-oidc-issuer 'https://issuer.example.invalid'
| Verificação | Código observado | Evidência no erro |
|---|---|---|
| Identidade e emissor oficiais | 0 | Assinatura aceita para o digest consultado |
| Identidade deliberadamente incorreta | 1 | Identidade do certificado não corresponde ao valor esperado |
| Emissor OIDC deliberadamente incorreto | 1 | Emissor OIDC registrado no certificado não corresponde ao valor esperado |
Conferimos a causa nos erros. Um código diferente de zero por falta de internet não demonstraria que a política rejeitou uma identidade indevida. Também não alteramos o artefato remoto para simular adulteração; estes dois controles exercitam a política de identidade, não todas as formas possíveis de corrupção de manifesto.
O que fazer com uma recusa no pipeline
Trate falha como bloqueio da etapa que depende da verificação. Classifique se houve erro de transporte, artefato sem assinatura, identidade diferente, emissor diferente ou outro problema de confiança. Investigue a origem; não troque uma identidade exata por uma expressão que aceita qualquer valor apenas para continuar o deploy.
Depois de verificar por digest, a etapa seguinte precisa consumir aquele mesmo digest. Verificar a tag, deixá-la mudar e depois fazer deploy novamente pela tag quebra a correspondência entre o objeto aceito e o executado. Não instalamos essa política de execução neste laboratório; ela continua sendo responsabilidade do pipeline que consumir o resultado.
Uma assinatura aceita não prova ausência de vulnerabilidades, qualidade do código ou adequação da configuração. Um publicador legítimo pode assinar um artefato com problema. A verificação responde sobre integridade e identidade dentro da política escolhida, não substitui análise de vulnerabilidades, testes ou revisão da origem.
Para quem vem do Docker Content Trust e da migração de assinaturas, esse é o avanço importante: sair de “há uma assinatura” para “este artefato atende à identidade que eu decidi confiar”. E manter o teste negativo ao lado do positivo para que uma futura flexibilização não passe despercebida.