Marcio Cunha

Construção de Pipelines de Imagens OCI Seguras com Cosign e Kyverno

Aprenda a blindar a cadeia de suprimentos de software usando imagens OCI assinadas criptograficamente com Cosign e validadas em tempo de execução no Kubernetes pelo Kyverno.

Marcio Cunha•6 min
Também disponível em:EnglishEspañol
Resumo
  • A assinatura criptográfica de imagens garante a integridade e a origem confiável do software em ambientes distribuídos.
  • O uso do Cosign simplifica a geração e validação de chaves sem a complexidade de infraestruturas PKI tradicionais pesadas.
  • Políticas de admissão em tempo de execução bloqueiam imediatamente a execução de containers adulterados ou sem procedência.
  • A integração contínua automatizada reduz o erro humano ao incorporar a assinatura diretamente no pipeline de build.
  • A observabilidade de falhas de segurança no cluster evita incidentes em produção antes que o workload seja escalado.

O Desafio da Confiança em Imagens de Contêineres

No desenvolvimento moderno de software, containers padronizaram a forma como empacotamos aplicações e suas dependências. O formato OCI, que significa Open Container Initiative (uma especificação aberta que dita como imagens e tempos de execução de containers devem funcionar), tornou-se o padrão universal da indústria. No entanto, o fato de uma imagem rodar com sucesso não garante que ela seja confiável ou que não tenha sido modificada por um atacante no meio do caminho entre o registro privado e o cluster de produção. Na prática, isso significa que confiar cegamente em qualquer tag de imagem é o equivalente a receber um pacote lacrado pelos correios sem saber quem o despachou ou se o conteúdo foi violado.

Para resolver esse problema, a engenharia moderna recorre à assinatura criptográfica. Assim como assinamos um contrato físico com firma reconhecida ou usamos uma chave digital para validar uma transação bancária, a assinatura de containers usa matemática avançada para atestar duas propriedades vitais: quem construiu a imagem e se ela sofreu qualquer alteração após o build. Quando introduzimos ferramentas como o Cosign no fluxo de trabalho, transformamos o processo de implantação em uma operação matematicamente verificável, eliminando a dependência exclusiva de credenciais de acesso a repositórios.

Entendendo a Assinatura Criptográfica com Cosign

O Cosign é uma ferramenta desenvolvida pela comunidade nativa em nuvem que facilita a assinatura, verificação e armazenamento de artefatos OCI. Diferente de soluções legadas que exigem a gestão complexa de certificados X.509 e autoridades certificadoras tradicionais, o Cosign opera de forma simples através de pares de chaves assimétricas ou utilizando identidades baseadas em OIDC, o OpenID Connect (um protocolo de autenticação que permite verificar a identidade de um usuário por meio de um provedor confiável como o Google ou GitHub). Na prática, a chave privada fica restrita ao ambiente seguro de integração contínua, enquanto a chave pública é distribuída para os servidores que farão a verificação.

Quando um desenvolvedor dispara um build, o pipeline executa testes automatizados, gera a imagem e, logo em seguida, utiliza o Cosign para assinar a hash criptográfica da imagem armazenada no registro. Essa assinatura é enviada para o mesmo registro de containers como um artefato associado, criando um vínculo indissociável entre o binário e a prova de autenticidade. Se um invasor alterar um único byte na imagem dentro do repositório, a hash resultante mudará imediatamente, invalidando a assinatura e tornando a imagem rejeitada por qualquer sistema de verificação subsequente.

Garantindo a Segurança no Cluster com Kyverno

Assinar imagens é apenas a primeira etapa de uma estratégia robusta de segurança. A segunda etapa, igualmente crítica, acontece no momento em que o cluster tenta executar essa imagem. É aqui que entra o Kyverno, um mecanismo de políticas nativo do Kubernetes que funciona como um porteiro rigoroso para o seu ambiente. O Kubernetes é o orquestrador de containers que gerencia onde e como as aplicações rodam, e o Kyverno atua interceptando todas as solicitações de criação de pods para verificar se elas atendem aos critérios de conformidade da organização.

Na prática, configuramos o Kyverno para exigir que qualquer imagem que tente subir no cluster possua uma assinatura válida emitida pela chave confiável da empresa. Se um desenvolvedor tentar implantar uma imagem sem assinatura ou com uma assinatura gerada por uma chave desconhecida, o Kyverno rejeita a requisição no mesmo instante, impedindo que o código não auditado toque nos nós de computação. Esse mecanismo opera de forma transparente e declarativa, permitindo que equipes de segurança definam regras complexas usando YAML simples, sem a necessidade de escrever scripts em linguagens obscuras.

Implementando o Fluxo Automatizado no Pipeline

Para colocar essa arquitetura para funcionar na prática, precisamos integrar a geração e a assinatura de imagens diretamente no nosso pipeline de integração contínua, como o GitHub Actions ou GitLab CI. O procedimento envolve compilar o código, enviar a imagem para o OCI registry e imediatamente assinar o artefato resultante antes que o pipeline seja concluído. A seguir, visualizamos os passos fundamentais executados pelo sistema de automação para garantir que nenhuma imagem suba sem validação prévia:

  1. O código é testado e compilado em um ambiente isolado de build.
  2. A imagem resultante é enviada para o registro privado OCI utilizando credenciais temporárias.
  3. O Cosign é acionado utilizando a chave privada armazenada de forma segura nos segredos do repositório.
  4. A assinatura criptográfica é gerada e enviada para o mesmo registro de imagens.
  5. O manifesto do Kubernetes é atualizado para referenciar a imagem e sua respectiva tag imutável.

O uso de tags imutáveis, como a hash SHA-256 da imagem em vez de tags mutáveis como 'latest', é um requisito fundamental para evitar ataques de substituição de tag. Quando apontamos para uma hash específica, temos a garantia absoluta de que o código executado em produção é exatamente o mesmo que passou pelos testes de segurança e recebeu a assinatura criptográfica.

Validando Imagens em Tempo de Execução com Políticas Declarativas

Com as imagens devidamente assinadas no registro, o próximo passo é configurar o Kyverno no cluster Kubernetes para impor essa validação. Criamos uma política de admissão, conhecida no vocabulário do Kyverno como um ClusterPolicy, que intercepta qualquer tentativa de criação de recursos do tipo Pod. O arquivo de configuração instrui o Kyverno a consultar o Cosign internamente para verificar se a imagem possui uma assinatura válida vinculada à nossa chave pública oficial. Abaixo, examinamos a estrutura conceitual dessa regra de validação aplicada diretamente pelo motor de políticas:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signatures
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-cosign-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "registry.empresa.com/*"
          attestors:
            - count: 1
              entries:
                - keys:
                    publicKeys: "-----BEGIN PUBLIC KEY-----\n...-----\n-----\n"

Esse bloco de configuração garante que o modo de imposição esteja ativo, bloqueando ativamente qualquer tentativa de execução de código não assinado. Caso ocorra uma tentativa de violação, o operador do cluster recebe um erro descritivo detalhando que a assinatura da imagem falhou na checagem criptográfica, mantendo a superfície de ataque rigorosamente controlada.

Considerações Finais e Próximos Passos

A construção de pipelines de imagens OCI seguras utilizando a assinatura do Cosign e a verificação em tempo de execução com o Kyverno representa um salto expressivo na maturidade de segurança de qualquer infraestrutura moderna baseada em Kubernetes. Ao substituir a confiança cega em repositórios por garantias matemáticas e políticas automatizadas, as organizações protegem seus sistemas contra invasões sofisticadas de cadeia de suprimentos. Embora exija um esforço inicial de configuração e mudança de cultura nos processos de build, o retorno sobre o investimento se traduz em resiliência operacional, conformidade regulatória e a tranquilidade de saber que apenas códigos autenticados e auditados habitam o ambiente produtivo.