Secrets e variáveis no GitHub Actions

    Secrets no GitHub Actions são a forma segura de armazenar chaves SSH, tokens de API e senhas de banco que o CI/CD precisa — não ficam expostos nos logs e são criptografados em repouso. Entender a diferença entre secrets, variáveis e environments é essencial para uma pipeline segura e bem organizada.

    Tipos de secrets e variáveis

    GitHub Actions tem quatro escopos para secrets e variáveis:

    yaml
    # 1. Repository Secrets — disponíveis em todos os workflows do repositório
    # Settings → Secrets and variables → Actions → New repository secret
    # SSH_PRIVATE_KEY, DATABASE_URL, etc.
    
    # 2. Environment Secrets — disponíveis apenas em jobs de um ambiente específico
    # Settings → Environments → production → Add secret
    # Permite aprovação manual antes de usar (protection rules)
    
    # 3. Organization Secrets — compartilhados entre múltiplos repositórios
    # Organization Settings → Secrets → New secret
    # Útil para token de deploy compartilhado entre microserviços
    
    # 4. Variables (não secrets) — valores não sensíveis, visíveis nos logs
    # Settings → Secrets and variables → Variables
    # NODE_VERSION=22, APP_PORT=3000, etc.
    
    # Acessar no workflow:
    env:
      # Secret (mascarado nos logs)
      DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
      # Variável (visível nos logs)
      NODE_ENV: ${{ vars.NODE_ENV }}
      # Variável automática do GitHub (sempre disponível)
      BRANCH: ${{ github.ref_name }}
    Dica
    GitHub automaticamente mascara qualquer string que corresponda a um secret nos logs — aparece como ***. No entanto, se você passar um secret decodificado em base64 ou dividido em partes, pode não ser mascarado.

    Environments com aprovação manual

    Environments adicionam uma camada de controle — exigem aprovação antes de fazer deploy em produção:

    yaml
    # Settings → Environments → production → Protection rules:
    # ✓ Required reviewers: adicione pessoas que devem aprovar
    # ✓ Wait timer: aguardar N minutos antes de executar
    # ✓ Deployment branches: apenas main
    
    # No workflow — referenciar o environment:
    jobs:
      deploy-prod:
        runs-on: ubuntu-latest
        environment:
          name: production
          url: https://seudominio.com.br    # URL exibida no GitHub após deploy
    
        steps:
          # Aqui o job pausa e aguarda aprovação dos reviewers
          - name: Deploy para produção
            run: echo "Fazendo deploy..."
    
    # O job só executa após aprovação na interface do GitHub
    # Secrets do environment production ficam disponíveis apenas neste job

    OIDC: autenticação sem secrets de longa duração

    OpenID Connect elimina a necessidade de armazenar chaves de acesso como secrets — o GitHub gera tokens temporários:

    yaml
    # Para AWS (sem AWS_ACCESS_KEY_ID/SECRET armazenados):
    jobs:
      deploy:
        runs-on: ubuntu-latest
        permissions:
          id-token: write    # necessário para OIDC
          contents: read
    
        steps:
          - name: Configurar AWS credentials via OIDC
            uses: aws-actions/configure-aws-credentials@v4
            with:
              role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy
              aws-region: sa-east-1
    
          - name: Deploy no ECS/S3/EC2
            run: aws ecs update-service ...
    
    # O token AWS é temporário (1h) e gerado automaticamente
    # Sem credenciais de longa duração armazenadas no GitHub
    # Configuração requer criar IAM Role com trust policy para GitHub OIDC
    Dica
    OIDC é o padrão mais seguro para integração com cloud providers (AWS, GCP, Azure). Elimina o risco de credenciais de longa duração vazadas. Para VPS self-hosted: SSH com chave dedicada ainda é o método mais prático.

    Boas práticas para não vazar secrets

    Erros comuns que expõem secrets e como evitá-los:

    yaml
    # ❌ NUNCA faça:
    
    # 1. Imprimir secrets diretamente
    - run: echo "Minha senha: ${{ secrets.DB_PASSWORD }}"
    
    # 2. Passar secrets em args de linha de comando (visível em ps aux)
    - run: mysql -u root -p${{ secrets.DB_PASSWORD }} -e "SELECT 1"
    
    # 3. Commitar .env com secrets no repositório
    - run: git add .env && git commit
    
    # ✅ FAÇA:
    
    # 1. Usar variáveis de ambiente (mascaradas pelo runner)
    - name: Conectar ao banco
      env:
        DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
      run: mysql -u root -p"$DB_PASSWORD" -e "SELECT 1"
    
    # 2. Escrever em arquivo temporário
    - name: Criar .env
      run: |
        cat > .env << EOF
        DB_PASSWORD=${{ secrets.DB_PASSWORD }}
        EOF
      # O arquivo não é commitado — only em memória do runner
    
    # 3. Verificar que .env está no .gitignore
    - name: Verificar .gitignore
      run: grep -q "^.env" .gitignore || (echo ".env não está no .gitignore!" && exit 1)

    Gerenciar secrets via GitHub CLI

    Automatize a criação e atualização de secrets com gh CLI:

    bash
    # Instalar GitHub CLI (se não tiver)
    # https://cli.github.com
    
    # Login
    gh auth login
    
    # Criar ou atualizar secret
    gh secret set SSH_PRIVATE_KEY < ~/.ssh/id_ed25519_github_actions
    gh secret set DATABASE_URL --body "postgresql://user:pass@host:5432/db"
    
    # Criar secret de environment específico
    gh secret set DATABASE_URL --env production --body "postgresql://..."
    
    # Listar secrets (nomes apenas — valores nunca são exibidos)
    gh secret list
    gh secret list --env production
    
    # Deletar secret
    gh secret delete OLD_SECRET
    
    # Criar variável (não secret)
    gh variable set NODE_VERSION --body "22"
    gh variable list

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes