Secrets no GitHub Actions

1. Introdução aos Secrets no GitHub Actions

Secrets no GitHub Actions são variáveis criptografadas que armazenam informações sensíveis como tokens de autenticação, chaves SSH, senhas de banco de dados ou credenciais de cloud providers. Em pipelines DevOps que envolvem Docker e Kubernetes, os Secrets são indispensáveis para autenticar em registros de container, configurar acesso a clusters Kubernetes e proteger dados críticos durante o ciclo de CI/CD.

É crucial entender a diferença entre Secrets, Variables e Environment Files:
- Secrets: criptografados, nunca aparecem em logs ou outputs. Usados para dados sensíveis.
- Variables: variáveis de ambiente comuns, visíveis em logs. Adequadas para valores não sensíveis (ex: versão de build).
- Environment Files: arquivos .env que podem conter Secrets, mas exigem cuidado redobrado para não vazar.

Casos de uso típicos incluem tokens de registro Docker (Docker Hub, Amazon ECR, Google GCR), arquivos kubeconfig para clusters Kubernetes, chaves SSH para acesso a servidores e credenciais de serviços cloud.

2. Criando e Gerenciando Secrets no GitHub

Para adicionar Secrets no GitHub, navegue até Settings > Secrets and variables > Actions no repositório, organização ou ambiente.

Níveis de Secrets:
- Repositório: visível em todos os workflows do repositório.
- Organização: disponível para múltiplos repositórios, com controle de acesso via políticas.
- Ambiente: vinculado a ambientes específicos (dev, staging, production), com regras de proteção.

Práticas de nomenclatura:
Use nomes descritivos em maiúsculas com underscores:

DOCKER_REGISTRY_TOKEN
KUBE_CONFIG_DATA
AWS_ACCESS_KEY_ID

Limitações e rotação:
- Tamanho máximo: 48 KB por Secret (para valores maiores, use criptografia externa ou armazenamento em blob).
- Rotação: alterne Secrets periodicamente (a cada 90 dias é uma boa prática) e atualize os workflows imediatamente.
- Versionamento: nunca versionar Secrets no repositório. Use variáveis de ambiente do GitHub Actions.

3. Utilizando Secrets em Workflows do GitHub Actions

A sintaxe para acessar Secrets é ${{ secrets.NOME_DO_SECRET }}. Eles só podem ser usados em etapas que explicitamente os referenciam.

Exemplo 1: Autenticação em registro Docker privado (Docker Hub)

name: Build and Push Docker Image

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: myuser/myapp:latest

Exemplo 2: Configuração de kubeconfig para deploy no Kubernetes

name: Deploy to Kubernetes

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up kubeconfig
        run: |
          mkdir -p $HOME/.kube
          echo "${{ secrets.KUBE_CONFIG }}" > $HOME/.kube/config
          chmod 600 $HOME/.kube/config

      - name: Deploy to Kubernetes
        run: |
          kubectl apply -f k8s/deployment.yaml
          kubectl rollout status deployment/myapp

4. Secrets e Ambientes (Environments) no GitHub Actions

Ambientes no GitHub Actions permitem vincular Secrets a contextos específicos como dev, staging ou production.

Configuração de ambiente:
1. Vá em Settings > Environments e crie ambientes (ex: production).
2. Adicione Secrets específicos para cada ambiente.
3. No workflow, referencie o ambiente:

name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - name: Deploy with Helm
        run: |
          helm upgrade --install myapp ./helm \
            --set image.tag=${{ github.sha }} \
            --set docker.password=${{ secrets.DOCKER_PASSWORD }}

Regras de proteção:
- Aprovação manual: exija revisão antes de executar jobs em ambientes críticos.
- Gatilhos restritos: limite branches que podem fazer deploy em produção.
- Isolamento: Secrets de production não vazam para workflows que não especificam esse ambiente.

5. Segurança Avançada: Prevenção de Vazamento de Secrets

O GitHub Actions automaticamente mascara Secrets em logs, substituindo seus valores por ***. No entanto, existem armadilhas:

Uso de env versus secrets:
- Prefira env para valores não sensíveis. Secrets devem ser passados diretamente em ações ou comandos, nunca expostos como variáveis de ambiente no workflow inteiro.
- Evite:

env:
  MY_SECRET: ${{ secrets.MY_SECRET }}  # Perigoso: pode vazar em logs de subprocessos

Ferramentas de detecção:
- GitHub Secret Scanning: monitora repositórios automaticamente para credenciais vazadas.
- truffleHog: scanner local que detecta Secrets em commits históricos.
- git-secrets: previne commits com padrões de credenciais.

Boas práticas:
- Nunca imprima Secrets com echo ou print.
- Use run: | com cuidado: comandos multi-linha podem expor Secrets se não forem mascarados.
- Revise logs periodicamente para detectar vazamentos acidentais.

6. Integração com Docker e Kubernetes: Exemplos Práticos

Workflow completo: build, push e deploy

name: CI/CD Pipeline

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    environment: production

    steps:
      - uses: actions/checkout@v4

      - name: Log in to Amazon ECR
        uses: aws-actions/amazon-ecr-login@v2
        with:
          registry: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com

      - name: Build, tag, and push image
        env:
          ECR_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com
          ECR_REPOSITORY: myapp
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

      - name: Set up kubectl
        uses: azure/setup-kubectl@v3

      - name: Configure kubeconfig
        run: |
          echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config

      - name: Deploy to Kubernetes
        run: |
          kubectl set image deployment/myapp myapp=$ECR_REGISTRY/$ECR_REPOSITORY:${{ github.sha }}
          kubectl rollout status deployment/myapp

Injetando Secrets em pods Kubernetes:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: myapp
        image: myregistry/myapp:latest
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: password

No workflow, crie o Secret no cluster antes do deploy:

- name: Create Kubernetes Secret
  run: |
    kubectl create secret generic db-credentials \
      --from-literal=password=${{ secrets.DB_PASSWORD }} \
      --dry-run=client -o yaml | kubectl apply -f -

7. Alternativas e Melhores Práticas para Ambientes Corporativos

Gerenciamento centralizado:
- HashiCorp Vault: integre com GitHub Actions via hashicorp/vault-action para injetar Secrets dinâmicos.
- AWS Secrets Manager: use aws-actions/secrets-manager para recuperar Secrets sob demanda.
- Azure Key Vault: similar para ambientes Azure.

OpenID Connect (OIDC):
Em vez de Secrets estáticos, configure OIDC entre GitHub Actions e seu cloud provider (AWS, Azure, GCP). Isso elimina a necessidade de armazenar credenciais de longa duração:

- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789012:role/github-actions-role
    aws-region: us-east-1

Checklist de segurança:
- [ ] Rotacione Secrets a cada 90 dias.
- [ ] Use ambientes com aprovação manual para produção.
- [ ] Ative GitHub Secret Scanning no repositório.
- [ ] Audite logs de acesso a Secrets regularmente.
- [ ] Prefira OIDC sempre que possível.
- [ ] Nunca armazene Secrets em código-fonte ou arquivos de configuração.

Referências