Como Garantir Proveniência Criptográfica de Contentores com Trivy, SBOM e Sigstore Cosign
Fazer deploy de contentores Docker em produção confiando apenas em etiquetas de texto mutáveis (:latest ou :production) é um risco operacional grave: se um atacante comprometer uma credencial do teu registo de contentores, pode substituir a imagem legítima por uma versão envenenada sem alterar o nome da tag. Sem verificação criptográfica, o teu servidor descarrega e executa o código malicioso de olhos fechados.
Em setores como Fintech Startups (Neobanks) e Arqueologia e Património, garantir a proveniência imutável de cada componente é um requisito técnico e de conformidade indispensável.
Na infraestrutura de CI/CD que operamos no Webxtek Studio, aplicamos uma validação tripla antes de qualquer imagem tocar num servidor Linux: inspeção de vulnerabilidades com Trivy, geração do inventário de componentes SBOM CycloneDX e assinatura imutável do digest SHA-256 via Sigstore Cosign com OIDC, sem recorrer a chaves estáticas no disco.
Esta segurança na cadeia de fornecimento alinha-se diretamente com o perímetro defensivo do nosso Alerta CISA, NSA e FBI: Blindagem PHP, Node e Portas Expostas.
Abaixo explico como integrar esta esteira de validação criptográfica no teu pipeline de CI/CD.
1. Do Rótulo Falsificado ao Digest Imutável: Trivy, SBOM CycloneDX e Sigstore Cosign
Para garantires a proveniência criptográfica dos teus contentores em produção, tens de substituir tags mutáveis por digests SHA-256 imutáveis, bloquear builds vulneráveis com o scanner Trivy, anexar um inventário SBOM CycloneDX e assinar a imagem via OIDC com o Sigstore Cosign antes de a validar no servidor de destino.
Para perceberes porque é que o comando docker pull minhaempresa/api:latest é uma roleta russa operacional, precisamos de olhar para a arquitetura dos registos de contentores compatíveis com a norma OCI (Open Container Initiative). Uma tag como :latest ou :v2.1.0 não é a imagem em si; é apenas um apontador mutável que hoje aponta para o resumo criptográfico sha256:4f8a... e amanhã pode ser reescrito por qualquer pessoa com acesso de escrita no registo para apontar para sha256:999b....
O perigo de confiar cegamente em dependências de terceiros sem um inventário auditado ficou dolorosamente demonstrado no Ataque Supply Chain ao LiteLLM: GhostAction e Fuga de Tokens, onde um pipeline de CI/CD foi sequestrado para roubar credenciais cloud através de dependências comprometidas.
Para transformar uma pipeline frágil numa cadeia de fornecimento inviolável, alinhada com a documentação oficial do Sigstore Cosign e com as especificações do scanner Aqua Security Trivy, ligamos três mecanismos determinísticos no pipeline de CI/CD:
Fluxo de Proveniencia Criptografica de Contentores (Padrao Webxtek Studio):
1. Compilacao Deterministica:
O Docker constroi a imagem multi-stage e exporta o Digest Imutavel (@sha256:4f8a...).
2. Portao de Seguranca (Trivy):
O Trivy analisa pacotes Debian/Alpine e lockfiles (npm/pip/composer).
- Se encontrar 1 CVE CRITICAL ou HIGH com correcao disponivel -> Quebra o pipeline na hora (Exit Code 1).
3. Inventario de Ingredientes (SBOM):
O Trivy gera o ficheiro sbom.cdx.json (norma CycloneDX).
4. Assinatura Keyless (Cosign + OIDC):
- O runner do GitHub Actions pede um token JWT OIDC.
- A CA Fulcio emite um certificado X.509 efemero (valido por 10 minutos) amarrado ao commit e workflow exatos.
- O Cosign assina a imagem e anexa o SBOM assinado no registo OCI, gravando a prova no livro-razao Rekor.
5. Alfandega no Servidor Linux:
Antes de correr 'docker compose up', o servidor executa 'cosign verify'.
- Se a assinatura nao pertencer ao nosso repositorio GitHub oficial -> Bloqueia o arranque e dispara alerta!
A Brilhante Engenharia do Keyless Signing (Assinatura Sem Chaves Estáticas)
No passado, quando tentavas implementar assinatura de imagens (como o antigo Docker Content Trust / Notary v1), tinhas um problema grave de gestão de segredos: precisavas de gerar uma chave privada criptográfica, guardá-la nos segredos do CI/CD e protegê-la durante anos. Se alguém roubasse essa chave privada dos segredos do GitHub, podia assinar malware em teu nome!
O Sigstore Cosign eliminou as chaves privadas permanentes através da criptografia efémera baseada em identidade OIDC:
- Quando o teu workflow corre no GitHub Actions (ou GitLab CI), o Cosign não usa nenhuma chave guardada no disco. Ele gera um par de chaves temporário exclusivamente na memória RAM daquele job.
- O Cosign apresenta o token OIDC do GitHub à autoridade de certificação gratuita Fulcio (gerida pela Linux Foundation).
- O Fulcio confirma matematicamente que aquele pedido veio mesmo do repositório
github.com/tua-empresa/tua-apina branchmain, e emite um certificado digital válido por apenas 10 minutos. - O Cosign assina o hash
@sha256:...da imagem, grava o carimbo de tempo no registo de transparência pública Rekor (funciona exatamente como o Certificate Transparency dos browsers) e apaga a chave privada da memória RAM. Passados 10 minutos, a chave já nem existe, mas qualquer servidor no mundo pode verificar através do registo Rekor que a assinatura era válida no momento exato em que o certificado estava ativo!
2. Pipeline Completo de Produção no GitHub Actions: Scan, SBOM e Assinatura OIDC
No meu dia a dia em produção, não confio em verificações manuais. Aqui tens o manifesto completo de GitHub Actions (.github/workflows/container-supply-chain.yml) que utilizamos para compilar, auditar com Trivy, gerar o SBOM CycloneDX e assinar quer a imagem quer o atestado SBOM sem uma única chave privada estática:
# ============================================================================
# .github/workflows/container-supply-chain.yml
# Pipeline Blindado: Build + Trivy Gate + SBOM CycloneDX + Sigstore Cosign OIDC
# ============================================================================
name: Build, SBOM e Assinatura Criptografica OCI
on:
push:
branches: [ main ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
# Permissoes estritas Zero-Trust (id-token: write e obrigatorio para o Sigstore Cosign OIDC)
permissions:
contents: read
packages: write
id-token: write
jobs:
build_scan_and_sign:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: 1. Checkout Imutavel do Codigo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: 2. Instalar Cosign (Sigstore)
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
- name: 3. Autenticar no GitHub Container Registry (GHCR)
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 4. Compilar e Publicar Imagem por Digest Imutavel
id: build_image
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
with:
context: .
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ github.sha }}
- name: 5. Portao de Seguranca Trivy (Bloquear CVEs CRITICAL e HIGH com Patch)
uses: aquasecurity/trivy-action@18f2510ee396bbf4004029bd2b394f2dd8c87dbb # 0.28.0
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build_image.outputs.digest }}
format: 'table'
exit-code: '1'
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH'
- name: 6. Gerar Inventario SBOM em Formato CycloneDX (JSON)
uses: aquasecurity/trivy-action@18f2510ee396bbf4004029bd2b394f2dd8c87dbb # 0.28.0
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build_image.outputs.digest }}
format: 'cyclonedx'
output: 'sbom.cdx.json'
- name: 7. Assinar Criptograficamente o Digest da Imagem com Cosign (Keyless OIDC)
run: |
cosign sign --yes \
"${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build_image.outputs.digest }}"
- name: 8. Anexar e Assinar o Atestado SBOM CycloneDX no Registo OCI
run: |
cosign attest --yes \
--predicate sbom.cdx.json \
--type cyclonedx \
"${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build_image.outputs.digest }}"
Analisa o que este pipeline garante matematicamente antes de qualquer deploy:
- No Passo 5, se uma biblioteca Python, Node.js, PHP ou um pacote base Debian tiver uma vulnerabilidade HIGH ou CRITICAL com correção disponível, o Trivy devolve
exit-code: 1, interrompe a execução imediatamente e a imagem nunca chega a ser assinada no Passo 7! - No Passo 7 e Passo 8, o Cosign nunca assina a tag mutável
:sha-...; assina exclusivamente o resumo criptográfico@sha256:...(steps.build_image.outputs.digest) e anexa o ficheirosbom.cdx.jsonassinado como uma camada de atestado OCI in-toto diretamente no registo.
3. O Portão de Admissão no Servidor de Produção Linux: Validar Antes de Executar
Assinar imagens no CI/CD só serve de alguma coisa se o teu servidor de produção se recusar terminantemente a arrancar imagens que não tenham uma assinatura válida.
Se operas clusters Kubernetes (EKS, GKE ou K3s), podes impor esta regra usando o admission controller Kyverno ou o Sigstore Policy Controller. Mas se operas servidores Linux dedicados ou VPS com Docker Compose (um cenário muito frequente em arquiteturas enxutas de alta velocidade), nunca deves correr docker compose up -d diretamente.
Cria este wrapper de verificação criptográfica (/usr/local/bin/webxtek-verified-deploy.sh) no teu servidor de produção Debian/Ubuntu:
#!/usr/bin/env bash
# ============================================================================
# /usr/local/bin/webxtek-verified-deploy.sh
# Alfandega Criptografica de Producao: Valida Assinatura Cosign e SBOM antes do Deploy
# ============================================================================
set -euo pipefail
# 1. Definir a imagem obrigatoriamente pelo seu Digest SHA-256 imutavel
IMAGE_DIGEST="${1:?Erro: Indica a imagem com @sha256:...}"
EXPECTED_REPO="https://github.com/tua-organizacao/teu-repositorio/.github/workflows/container-supply-chain.yml@refs/heads/main"
OIDC_ISSUER="https://token.actions.githubusercontent.com"
echo "[1/3] A verificar assinatura criptografica Keyless no registo Rekor..."
cosign verify \
--certificate-identity="$EXPECTED_REPO" \
--certificate-oidc-issuer="$OIDC_ISSUER" \
"$IMAGE_DIGEST" > /dev/null
echo "[OK] Assinatura de imagem confirmada matematicamente!"
echo "[2/3] A validar presenca e assinatura do atestado SBOM CycloneDX..."
cosign verify-attestation \
--type cyclonedx \
--certificate-identity="$EXPECTED_REPO" \
--certificate-oidc-issuer="$OIDC_ISSUER" \
"$IMAGE_DIGEST" | jq -r '.payload' | base64 -d | jq '.predicate.metadata.component.name'
echo "[OK] Inventario SBOM CycloneDX integro e verificado!"
echo "[3/3] A iniciar contentor blindado em producao..."
export VERIFIED_IMAGE="$IMAGE_DIGEST"
docker compose -f /opt/app/docker-compose.prod.yml up -d --pull always --no-build
Faz um teste prático: se um atacante conseguir invadir o teu registo de contentores, compilar uma imagem maliciosa no computador dele e empurrá-la para o teu repositório, quando o teu servidor correr /usr/local/bin/webxtek-verified-deploy.sh, o comando cosign verify falha no primeiro segundo com Error: no matching signatures found e o contentor adulterado nunca chega a ser iniciado!
4. Comparativo de Engenharia: Deploy Tradicional vs. Cadeia Blindada (Trivy + SBOM + Cosign)
Na tabela abaixo comparo o fluxo de deploy tradicional usado pela maioria das equipas com o pipeline de proveniência criptográfica que implementamos no Webxtek Studio:
| Dimensão Operacional / Segurança | Pipeline Docker Tradicional (docker pull :latest) | Padrão Blindado Webxtek (Trivy + SBOM + Cosign OIDC) | Impacto Real na Tua Operação |
|---|---|---|---|
| Referência da Imagem em Produção | Tag mutável (:latest, :prod, :v1.4) |
Digest criptográfico imutável (@sha256:4f8a...) |
Imunidade total contra ataques de substituição de tags (Tag Tampering) |
| Segredos de Assinatura no CI/CD | Inexistentes ou chaves privadas estáticas em risco de roubo | Zero chaves estáticas (Assinatura efémera via OIDC + Fulcio + Rekor) | Elimina o risco de roubo da chave privada de assinatura |
| Deteção de Pacotes Vulneráveis | Reativa (só descobres após um incidente ou pentest) | Preventiva no build (trivy --exit-code 1 bloqueia CVEs críticas) |
Código vulnerável é travado antes de chegar ao registo OCI |
| Resposta a Novos Zero-Days (SBOM) | Lenta (exige entrar por SSH em cada servidor para ver versões) | Instantânea (consulta ao atestado JSON CycloneDX assinado) | Auditoria de impacto em segundos em toda a frota |
| Conformidade Legal (CRA / DORA / NIS2) | Incumprimento por falta de inventário e proveniência | 100% Auditável com trilho criptográfico público no Rekor | Preparação nativa para o EU Cyber Resilience Act |
Quando lideras uma operação em Fintech Startups (Neobanks) ou geres plataformas digitais onde a integridade histórica e documental é sagrada, como em Arqueologia e Património, alinhar a tua infraestrutura através de Consultoria Técnica Antes de Construir protege o ativo mais valioso da tua empresa: a confiança. E quando essa solidez técnica é acompanhada por um posicionamento claro de mercado, apoiado em Rebranding e Evolução de Marca e numa estratégia consistente de Conteúdo SEO Mensal e Autoridade, transformas a tua maturidade de engenharia num argumento comercial decisivo perante clientes institucionais.
5. Checklist Prática de 5 Passos Para Produção
Segue estes cinco passos técnicos para implementares a assinatura e verificação de contentores na tua operação ainda esta semana:
- Migra para Imagens Base Minimalistas ou Distroless: Quanto mais pacotes desnecessários tiver a tua imagem Docker (como editores de texto, compiladores ou shells em imagens
ubuntu:latestcompletas), mais alertas o Trivy vai disparar. Usa builds multi-stage e imagens finais distroless ou alpine enxutas para reduzir a superfície de ataque em 80%. - Ativa o Bloqueio do Trivy com –ignore-unfixed: Configura o passo do Trivy no teu pipeline com
--exit-code 1 --severity CRITICAL,HIGH --ignore-unfixedsegundo a documentação de trivy.dev, garantindo que a equipa só é bloqueada quando já existe uma atualização de segurança oficial disponível para corrigir a falha. - Exige id-token: write e Assinatura Keyless: Implementa o
cosign signecosign attestnos teus workflows seguindo o guia oficial de docs.sigstore.dev, eliminando qualquer chave privada manual dos segredos do teu repositório. - Arquiva e Indexa os Ficheiros sbom.cdx.json: Além de anexares o SBOM à imagem no registo OCI, envia automaticamente o ficheiro CycloneDX gerado em cada release para uma plataforma de monitorização contínua (como o OWASP Dependency-Track) para receberes alertas imediatos se surgir um CVE novo num pacote antigo.
- Força a Verificação Antes do Arranque (cosign verify): Nunca deixes um nó de produção executar uma imagem sem validar primeiro os parâmetros
--certificate-identitye--certificate-oidc-issuer. Para além dos scanners de vulnerabilidades estáticas de pacotes, a auditoria semântica do próprio código aplicacional pode ser acelerada através da nossa arquitetura de agentes Caçador e Verificador com sandboxing.
Construir pipelines de software resilientes exige tratar cada artefacto compilado com o rigor de um contrato criptográfico assinado. No Webxtek Studio, desenhamos arquiteturas de entrega contínua e sistemas de produção preparados para as normas europeias mais exigentes. Através de Consultoria Técnica Antes de Construir, projetos estratégicos de Rebranding e Evolução de Marca e programas de Conteúdo SEO Mensal e Autoridade, ajudamos a tua empresa a consolidar uma infraestrutura inviolável e uma autoridade técnica inquestionável no teu mercado.
[+] [ INDEX_DIRECTORY ] 14 tópicos ▼
- 1. Do Rótulo Falsificado ao Digest Imutável: Trivy, SBOM CycloneDX e Sigstore Cosign
- A Brilhante Engenharia do Keyless Signing (Assinatura Sem Chaves Estáticas)
- 2. Pipeline Completo de Produção no GitHub Actions: Scan, SBOM e Assinatura OIDC
- 3. O Portão de Admissão no Servidor de Produção Linux: Validar Antes de Executar
- 4. Comparativo de Engenharia: Deploy Tradicional vs. Cadeia Blindada (Trivy + SBOM + Cosign)
- 5. Checklist Prática de 5 Passos Para Produção
- Autor
- Perguntas Frequentes
- Porque é que fazer deploy de imagens Docker por tags mutáveis (:latest ou :v1.2) sem verificar a assinatura criptográfica é um risco crítico?
- Como funciona a assinatura Keyless (sem chaves estáticas) do Sigstore Cosign com Fulcio e Rekor no GitHub Actions?
- Para que serve um atestado SBOM em formato CycloneDX anexado à imagem e como responde ao EU Cyber Resilience Act (CRA)?
- Como travas automaticamente no pipeline CI vulnerabilidades críticas sem bloquear a equipa por falhas sem correção disponível?
- Nós Relacionados
- Sequência do Caminho
Perguntas Frequentes
Porque é que fazer deploy de imagens Docker por tags mutáveis (:latest ou :v1.2) sem verificar a assinatura criptográfica é um risco crítico?
Porque uma tag num registo de contentores (Docker Hub, GHCR ou AWS ECR) é apenas um ponteiro de texto mutável. Se um atacante comprometer uma credencial do registo, pode substituir a imagem associada à tag :latest por uma versão contendo malware sem alterar o nome. Ao exigires o resumo criptográfico imutável (@sha256:...) assinado com Sigstore Cosign, o servidor recusa executar qualquer byte que não tenha sido gerado pela tua pipeline oficial.
Como funciona a assinatura Keyless (sem chaves estáticas) do Sigstore Cosign com Fulcio e Rekor no GitHub Actions?
Em vez de guardares uma chave privada estática nos segredos do CI (que poderia ser roubada), o Cosign solicita um token de identidade OpenID Connect (OIDC) de curta duração ao runner do GitHub Actions. A autoridade de certificação Fulcio valida esse token e emite um certificado X.509 efémero válido apenas por 10 minutos para assinar o digest da imagem, gravando a prova criptográfica no livro-razão público e imutável Rekor antes de destruir a chave da memória.
Para que serve um atestado SBOM em formato CycloneDX anexado à imagem e como responde ao EU Cyber Resilience Act (CRA)?
O Software Bill of Materials (SBOM) em formato CycloneDX é a lista exata de todos os pacotes de sistema operativo (Debian/Alpine) e bibliotecas de linguagem (npm, pip, composer, cargo) compilados dentro da imagem. Ao anexares o SBOM como um atestado assinado (cosign attest), consegues identificar em segundos se uma nova vulnerabilidade zero-day afeta os teus contentores em produção e cumpres os requisitos legais de rastreabilidade do Cyber Resilience Act europeu.
Como travas automaticamente no pipeline CI vulnerabilidades críticas sem bloquear a equipa por falhas sem correção disponível?
Ao executares o scanner Trivy com as flags --exit-code 1 --severity CRITICAL,HIGH --ignore-unfixed --vuln-type os,library, o pipeline quebra imediatamente o build se existir uma vulnerabilidade grave que já tenha patch oficial lançado pelos mantenedores, forçando a atualização do pacote antes da imagem ser assinada.
[ RELATED_NODES ]
> INICIAR_PROJETO
Precisa de um website que transmita confiança, apareça na pesquisa e dê mais força à sua presença digital? Comece a conversa aqui.