No mundo DevOps, a gestão de segredos — como senhas, chaves de API e tokens — é um dos pilares da segurança. Muitas vezes, por pressa ou falta de conhecimento, desenvolvedores acabam commitando esses dados em repositórios Git, criando vulnerabilidades graves. Nesta aula, vamos explorar por que isso é perigoso, como usar vaults, variáveis de ambiente e implementar rotação de segredos de forma eficaz.

Vamos mergulhar em conceitos e práticas que vão desde o básico até exemplos de implementação, sempre com foco em segurança e boas práticas. Ao final, você terá um entendimento sólido para proteger suas aplicações e pipelines.

Por que não versionar segredos

Versionar segredos em repositórios Git é um erro crítico que pode comprometer sistemas inteiros. Uma vez que um segredo é commitado, ele fica no histórico do Git, mesmo se for removido em um commit posterior. Isso significa que qualquer pessoa com acesso ao repositório — ou a um clone antigo — pode descobrir o segredo. Além disso, ferramentas de varredura automática, como GitHub Secret Scanning, podem expor esses dados para terceiros.

Os riscos incluem acesso não autorizado a serviços, vazamento de dados, prejuízos financeiros e danos à reputação da empresa. Muitas vezes, os segredos são usados em ambientes de produção, então o impacto pode ser imediato e devastador.

Exemplo de erro comum:

$ git add config.json
$ git commit -m "Adiciona configuração com senha"

Para evitar isso, é fundamental adotar políticas de segurança desde o início, como usar .gitignore para ignorar arquivos sensíveis e empregar ferramentas de detecção de segredos, como git-secrets ou trufflehog.

Boas práticas:

  • Nunca commitar arquivos de configuração com segredos.
  • Usar variáveis de ambiente ou vaults para armazenar segredos.
  • Configurar hooks de pré-commit para varrer segredos.
  • Rotacionar segredos imediatamente se algum vazamento for detectado.

Vaults (visão geral)

Vaults são ferramentas projetadas para armazenar, acessar e gerenciar segredos de forma segura. Eles oferecem criptografia, controle de acesso, auditoria e rotação automática. O exemplo mais popular é o HashiCorp Vault, mas existem outras opções como AWS Secrets Manager, Azure Key Vault e Google Cloud Secret Manager.

Um vault centraliza o armazenamento de segredos, eliminando a necessidade de espalhá-los em configurações de aplicações. Ele também permite que você conceda acesso temporário e revogue permissões facilmente, além de manter logs de quem acessou o quê.

Exemplo de uso do HashiCorp Vault via CLI:

# Iniciar o Vault em modo dev (não usar em produção)
$ vault server -dev

# Exportar o endereço e token
$ export VAULT_ADDR='http://127.0.0.1:8200'
$ export VAULT_TOKEN='root'

# Armazenar um segredo
$ vault kv put secret/myapp password='S3cr3t!'

# Ler o segredo
$ vault kv get secret/myapp

Em pipelines CI/CD, você pode integrar o Vault para injetar segredos nas builds sem expô-los em logs. Por exemplo, usando o vault kv get e exportando variáveis para o processo.

Os vaults são essenciais para ambientes escaláveis e seguros, pois permitem que as aplicações busquem segredos sob demanda, sem armazená-los localmente.

Variáveis de ambiente

Variáveis de ambiente são uma forma simples e eficaz de passar segredos para aplicações sem hardcodá-los no código. Elas são definidas fora do código, no ambiente de execução, e podem ser injetadas em containers, VMs ou processos.

No bash, você pode definir uma variável de ambiente e usá-la em seu script. Por exemplo:

$ export DB_PASSWORD='minhaSenhaForte'
$ echo $DB_PASSWORD

Em aplicações, você pode ler a variável com linguagens como Python (os.environ['DB_PASSWORD']), Node.js (process.env.DB_PASSWORD) ou Go (os.Getenv("DB_PASSWORD")).

No contexto de Docker, você pode passar variáveis de ambiente com a flag -e ou usando um arquivo .env (desde que não seja versionado). Veja um exemplo:

$ docker run -e DB_PASSWORD='S3cr3t!' -e DB_USER='admin' myapp

Em pipelines CI/CD, como GitHub Actions, você pode definir segredos nos settings do repositório e referenciá-los como variáveis de ambiente nos workflows. Isso mantém os segredos fora do código e dos logs.

Boas práticas:

  • Nunca definir segredos em variáveis de ambiente de forma explícita em scripts versionados.
  • Usar arquivos .env que são ignorados pelo Git (adicionar ao .gitignore).
  • Limpar variáveis de ambiente após o uso em scripts sensíveis.
  • Preferir vaults para cenários complexos, onde a rotação é necessária.

Rotação

Rotação de segredos é o processo de substituir segredos antigos por novos, periodicamente ou quando há suspeita de comprometimento. Isso reduz a janela de exposição e limita o impacto de um vazamento. A rotação pode ser manual ou automática, dependendo da ferramenta.

Muitos vaults oferecem rotação automática integrada. Por exemplo, o HashiCorp Vault pode gerar credenciais dinâmicas para bancos de dados, que expiram após um período. Já serviços como AWS Secrets Manager permitem agendar rotação automática para credenciais do RDS.

Exemplo de rotação manual com Vault:

# Gerar novo segredo
$ vault kv put secret/myapp password='NovoValor!'

# Atualizar a aplicação para usar o novo valor (via variável de ambiente ou acesso ao vault)

Em pipelines, você pode automatizar a rotação com scripts que chamam APIs dos provedores. Por exemplo, no AWS CLI, você pode rotacionar uma chave de acesso:

$ aws iam create-access-key --user-name meu-usuario

Depois, atualize a chave antiga e desative-a. É crucial acompanhar a rotação com monitoramento e alertas para garantir que tudo funcione sem interrupções.

Boas práticas:

  • Defina uma política de rotação (por exemplo, a cada 90 dias).
  • Teste a rotação em um ambiente de staging antes de produção.
  • Automatize a rotação sempre que possível, usando scripts ou serviços gerenciados.
  • Mantenha um inventário de segredos e suas datas de expiração.

Boas práticas e observações finais

Além dos subtópicos, é essencial adotar uma cultura de segurança no time. Isso inclui treinar desenvolvedores sobre os riscos, usar ferramentas de varredura de segredos em repositórios e revisar periodicamente os acessos aos segredos.

Considere usar um gerenciador de segredos desde o início do projeto, mesmo em fases iniciais. Isso evita a migração dolorosa de segredos já expostos. Também é importante lembrar que nenhuma solução é perfeita: combine vaults com boas práticas de variáveis de ambiente e rotação para uma defesa em profundidade.

Referências

Exercícios

  1. Crie um script em bash que verifique se um arquivo contém padrões de segredos (como senhas ou chaves) e falhe se encontrar. Use grep ou awk.

    ✓ Resposta:
    #!/bin/bash
    # Verifica se o arquivo contém segredos
    file="$1"
    if grep -E -i "(password|senha|api[_-]?key|secret)" "$file" > /dev/null; then
        echo "Arquivo contém possíveis segredos!"
        exit 1
    else
        echo "Nenhum segredo encontrado."
        exit 0
    fi
    
  2. Configure o HashiCorp Vault no modo dev e armazene um segredo. Em seguida, leia-o via CLI.

    ✓ Resposta:
    # Iniciar servidor dev
    vault server -dev &
    # Exportar variáveis
    sleep 2
    export VAULT_ADDR='http://127.0.0.1:8200'
    export VAULT_TOKEN='root'
    # Armazenar e ler segredo
    vault kv put secret/myapp password='S3cr3t!'
    vault kv get secret/myapp
    
  3. Escreva um trecho de código em Python que leia uma variável de ambiente chamada DB_PASSWORD e a imprima (em um ambiente seguro).

    ✓ Resposta:
    import os
    password = os.environ.get('DB_PASSWORD')
    if password:
        print("Senha encontrada")
    else:
        print("Variável não definida")
    
  4. Explique como você rotacionaria uma chave de acesso da AWS usando o CLI, listando os comandos principais.

    ✓ Resposta:
    # Criar nova chave
    aws iam create-access-key --user-name meu-usuario
    # Atualizar a aplicação com a nova chave
    # Desativar a chave antiga
    aws iam update-access-key --access-key-id ANTIGA --status Inactive --user-name meu-usuario
    # (Opcional) Deletar a chave antiga
    aws iam delete-access-key --access-key-id ANTIGA --user-name meu-usuario
    
  5. Crie um script bash que use o Vault para obter um segredo e exportá-lo como variável de ambiente para um processo filho.

    ✓ Resposta:
    #!/bin/bash
    export VAULT_ADDR='http://127.0.0.1:8200'
    export VAULT_TOKEN='root'
    # Obter o segredo
    secret=$(vault kv get -field=password secret/myapp)
    # Exportar e executar comando
    export DB_PASSWORD="$secret"
    ./meu_processo