Dev (Back & Front)ARTIGO

Código, Fumaça e Assinaturas: Vault Transit na Linha de Fogo

Trago uma evolução desse mesmo princípio: assinatura de artefatos na linha de produção, com Zero Trust como base e o HashiCorp Vault … Vault Transit

Código, Fumaça e Assinaturas: Vault Transit na Linha de Fogo
Imagem: Rafael Lucas

Introdução: Selando confiança em tempos hostis

A cidade nunca dorme. Nem seus pipelines.

Em um mundo onde ataques de supply chainLeia tambémO impacto da inteligência artificial no crescimento do Supply ChainMarketing Tech · jun 2024 se tornam tão comuns quanto commits em um repositório monorepo, não basta mais verificar o conteúdo do código. É preciso comprovar a origem, assinar digitalmente a confiança e rastrear cada mudança até a última linha.

Já discutimos como acessos efêmeros com OTP via Vault revolucionam a segurança SSH. Agora, trago uma evolução desse mesmo princípio: assinatura de artefatos na linha de produção, com Zero TrustLeia tambémSegurança Efêmera e Zero Trust: A Nova Fronteira do SSH com OTP via VaultDevSecOps · ago 2025 como base e o HashiCorp Vault como caneta criptográfica.

O Problema da Proveniência

Assumir que todo artefato gerado no CI/CD é confiável é um erro clássico.

  • Quem garante que o build foi mesmo daquele commit?
  • Quem impede que alguém injete algo no runner entre etapas?
  • Como confiar no deploy se o artefato não prova quem o gerou?

É aqui que entra o conceito de validação de proveniência com assinatura digital.

Assinatura Digital com Vault Transit

O Vault Transit Engine permite assinar qualquer conteúdo sem expor a chave privada. Ele atua como um “cofre com caneta criptográfica”:

  • Você envia o hash do conteúdo.
  • O Vault assina usando a chave assimétrica protegida.
  • Você recebe uma assinatura verificável com validade garantida.

Essa abordagem encaixa perfeitamente em ambientes com pipelines GitLab CI/CDLeia tambémDevSecOps encontra DevSeQOps: a revolução quântica das assinaturas digitais com um Q a maisDevSecOps · dez 2025, onde o CI apenas invoca o Vault, sem nunca ter acesso direto à chave.

Arquitetura na prática

No exemplo real a seguir, usamos:

  • GitLab CI/CD
  • Chave ed25519 gerenciada no Vault
  • Assinatura do hash de todos os arquivos do diretório
  • Armazenamento da assinatura + metadados em um path do Vault (kv-v2)
Pipeline Real com GitLab

Etapa 1: Hash de todos os arquivos do projeto

package_artifact:
  stage: package
  image: alpine:latest
  before_script:
    - apk add --no-cache tar
  script:
    - mkdir -p artifact/
    - find $CODE_DIR -type f ! -name ".filehashes" -exec sha256sum {} \; > artifact/.filehashes
  artifacts:
    paths:
      - artifact/.filehashes

Gera o arquivo .filehashes com o hash de todos os arquivos presentes na pasta do código.

Etapa 2: Assinar o .filehashes via Vault

sign_artifact:
  stage: sign
  image: alpine:latest
  needs:
    - job: package_artifact
  before_script:
    - apk add --no-cache curl bash coreutils openssl jq xxd
  script: |
    ARTIFACT_PATH="artifact/.filehashes"
    HASH_HEX=$(sha256sum "$ARTIFACT_PATH" | awk '{print $1}')
    HASH_B64=$(echo -n "$HASH_HEX" | xxd -r -p | base64)
    SIGNATURE=$(curl -s --header "X-Vault-Token: $VAULT_SIGN_TOKEN" \
        --request POST \
        --data "{\"input\": \"$HASH_B64\"}" \
        "$VAULT_ADDR/v1/transit/sign/$VAULT_KEY" | jq -r .data.signature)
    echo "$SIGNATURE" > "$ARTIFACT_PATH.sig"
    echo "$HASH_HEX" > "$ARTIFACT_PATH.sha256"
    VAULT_PAYLOAD=$(jq -n \
      --arg sig "$(cat "$ARTIFACT_PATH.sig")" \
      --arg hash "$(cat "$ARTIFACT_PATH.sha256")" \
      --arg datetime "$(TZ='America/Sao_Paulo' date -d '-3 hours' '+%d/%m/%Y - %H:%M:%S')" \
      --arg size "$(stat -c%s "$ARTIFACT_PATH" | numfmt --to=iec)" \
      --arg executed_by "$(whoami)" \
      '{sign: $sig, hash_sha256: $hash, datetime: $datetime, artefact_size: $size, executed_by: $executed_by}')
 

  curl -s --header "X-Vault-Token: $VAULT_ARTEFATO_TOKEN" \
        --request POST \
        --data "$VAULT_PAYLOAD" \
        "$VAULT_ADDR/v1/artefatos/monitoramento_acesso"
  artifacts:
    paths:
      - artifact/.filehashes
      - artifact/.filehashes.sig
      - artifact/.filehashes.sha256

Verificação de assinatura (manual ou automática)

# Validar integridade
sha256sum artifact/.filehashes | grep $(cat artifact/.filehashes.sha256)

# Validar autenticidade com Vault
HASH_B64=$(cat artifact/.filehashes.sha256 | xxd -r -p | base64)

curl -s --header "X-Vault-Token: $VAULT_SIGN_TOKEN" \
    --request POST \
    --data "{\"input\": \"$HASH_B64\", \"signature\": \"$(cat artifact/.filehashes.sig)\"}" \
    "$VAULT_ADDR/v1/transit/verify/my-signing-key"

Se válido:

{"data":{"valid":true}}

Benefícios reais

Expansões possíveis
  • Uso com containers (cosign + Vault)
  • Integração com OIDC/JWT do GitLab (sem token fixo)
  • Auditoria automática com Lambda ou webhook
  • Verificação em runtime antes do deploy via webhook de validação
Conclusão

Se você já pensa em segurança como efemeridade, sua próxima etapa é a assinatura granular de tudo que o CI/CD gera. Vault deixa de ser só um cofre de senhas e vira o cartório digital do seu DevSecOps.

Em tempos de código, fumaça e ameaças, só sobrevive quem assina o que entrega.
A confiança agora tem um hash. E uma assinatura.

Profissional com mais de 15 anos de experiência em Tecnologia da Informação, Rafael Lucas é pós-graduado pela Royal Holloway, University of London em Cyber Security - Technology and Governance. Ao longo de sua carreira, tem se destacado na implementação de práticas DevSecOps, integrando segurança desde as fases iniciais do desenvolvimento de software. Atualmente, atua como membro de comitês públicos, contribuindo para a definição de políticas e estratégias na área de tecnologia, além de especialista na área de cybersec pela Facti.

Ver perfil