Audit log: rastreando ações em repositórios corporativos

1. Fundamentos do Audit Log em Ambientes Git Corporativos

Em ambientes corporativos, o Git vai além do controle de versão: ele se torna um ativo crítico que exige rastreabilidade completa. O audit log (log de auditoria) é o registro cronológico e imutável de todas as ações realizadas em um repositório, essencial para conformidade com normas como LGPD, SOX e PCI-DSS.

Diferentemente dos logs nativos do Git — como git log (histórico de commits) e git reflog (operações locais) —, os audit logs gerenciados por plataformas como GitHub, GitLab e Bitbucket capturam ações administrativas e de colaboração que o Git puro não registra. Enquanto git reflog mostra apenas operações locais no seu clone, o audit log corporativo documenta quem fez um force push, quem alterou permissões de branch ou quem aprovou um merge.

O escopo típico de ações auditáveis inclui:
- Operações em repositórios: push, force push, criação e deleção de branches e tags
- Colaboração: aprovações de pull requests, comentários em code review, merges
- Administração: alterações de permissões de usuários, proteção de branches, configuração de webhooks

2. Configuração de Audit Log em Plataformas Corporativas

GitHub Enterprise e GitHub.com

No GitHub Enterprise Server, acesse Settings > Audit log no painel de administração. Para GitHub.com (planos Enterprise), vá em Organization Settings > Audit log. A ativação é automática para organizações empresariais, mas é necessário garantir que o log esteja exportando para armazenamento externo.

# Exemplo de configuração via API REST do GitHub para listar eventos de auditoria
curl -H "Authorization: Bearer GITHUB_TOKEN" \
  "https://api.github.com/orgs/minha-empresa/audit-log?per_page=100"

GitLab Self-Managed e GitLab.com

No GitLab, o audit log é ativado em Admin Area > Monitoring > Audit Events. Para GitLab.com, está disponível em Group > Settings > Audit Events. É possível configurar streaming de logs para sistemas externos.

# Consultando eventos de auditoria no GitLab via API
curl --header "PRIVATE-TOKEN: GITLAB_TOKEN" \
  "https://gitlab.com/api/v4/audit_events?created_after=2024-01-01"

Bitbucket Data Center e Cloud

No Bitbucket Data Center, o audit log está em Administration > Audit Log. No Bitbucket Cloud, acesse Workspace Settings > Audit log. Ambos suportam filtros por usuário, ação e período.

3. Eventos e Ações Rastreáveis no Audit Log

Eventos de Repositório

# Exemplos de eventos registrados:
- repository.push: usuário fez push para branch main
- repository.force_push: força de push detectada em branch protegida
- repository.branch.create: branch feature-x criada
- repository.tag.delete: tag v1.0 removida

Eventos de Colaboração

# Eventos comuns de pull request:
- pull_request.approve: PR #42 aprovado por maria.silva
- pull_request.merge: PR #42 merged por joao.souza
- pull_request.comment: comentário adicionado por ana.oliveira

Eventos Administrativos

# Eventos de alteração de configuração:
- branch_protection.update: regras de proteção alteradas na branch main
- team.add_member: usuário pedro.alves adicionado ao time devs
- webhook.create: webhook configurado para URL https://hooks.slack.com/...

4. Ferramentas de Consulta e Filtragem de Audit Logs

APIs REST e GraphQL

A extração programática é essencial para automação. Exemplo com GitHub CLI (gh):

# Usando gh para buscar eventos de auditoria
gh api /orgs/minha-empresa/audit-log \
  --method GET \
  --field include=all \
  --field per_page=100 > audit_log.json

Filtragem por Data, Usuário e Ação

# Exemplo de filtro via API REST do GitHub
curl -H "Authorization: Bearer GITHUB_TOKEN" \
  "https://api.github.com/orgs/minha-empresa/audit-log?\
  created=2024-01-01..2024-01-31&\
  actor=joao.souza&\
  action=repository.force_push"

Exportação e Integração com SIEM

# Exportando logs em CSV via interface web
# Navegue até Settings > Audit log > Export > CSV

# Exemplo de script para enviar logs ao Splunk via HEC
curl -k -X POST "https://splunk.local:8088/services/collector" \
  -H "Authorization: Splunk HEC_TOKEN" \
  -d '{"event": {"audit_log": "conteudo_do_evento"}}'

5. Boas Práticas para Retenção e Armazenamento de Logs

Políticas de Retenção

  • LGPD/ GDPR: mínimo de 6 meses, recomendado 2 anos
  • SOX (Sarbanes-Oxley): 7 anos para empresas de capital aberto
  • PCI-DSS: 1 ano, com possibilidade de retenção estendida para investigações

Armazenamento Externo

# Configuração de streaming para AWS S3 no GitHub Enterprise
# Em Settings > Audit log > Streaming, adicione bucket S3:
arn:aws:s3:::meu-bucket-audit-logs

# Exemplo de script para backup automático via AWS CLI
aws s3 cp audit_log_$(date +%Y-%m-%d).json s3://meu-bucket-audit-logs/

Estratégias de Backup e Rotação

Implemente rotação baseada em tamanho ou tempo. Exemplo com logrotate:

# /etc/logrotate.d/git-audit-logs
/var/log/git-audit/*.log {
    daily
    rotate 365
    compress
    missingok
    notifempty
}

6. Monitoramento e Alertas Baseados em Audit Logs

Alertas para Ações Suspeitas

# Script Python para detectar force push em branches protegidos
import requests

token = "GITHUB_TOKEN"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(
    "https://api.github.com/orgs/minha-empresa/audit-log",
    headers=headers,
    params={"action": "repository.force_push"}
)

for event in response.json():
    if "main" in event.get("branch", ""):
        send_alert_slack(f"Force push detectado em main por {event['actor']}")

Webhooks para Notificações em Tempo Real

# Configuração de webhook no GitLab para alertas
# Settings > Webhooks > Adicionar URL do Slack
URL: https://hooks.slack.com/services/TXXXX/BXXXX/XXXXX
Eventos: Audit Events

Análise Automatizada de Padrões Anômalos

# Script bash para detectar múltiplos force pushes em 1 hora
#!/bin/bash
COUNT=$(curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.github.com/orgs/minha-empresa/audit-log?\
  action=repository.force_push&\
  created_after=$(date -d '1 hour ago' -Iseconds)" | jq length)

if [ "$COUNT" -gt 5 ]; then
  echo "ALERTA: $COUNT force pushes na última hora"
fi

7. Integração com Ferramentas de Compliance e Governança

Conexão com Sistemas GRC

# Exemplo de integração com ServiceNow via API REST
curl -X POST "https://instance.service-now.com/api/now/table/audit_log" \
  -H "Authorization: Bearer SN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "repository.force_push",
    "user": "joao.souza",
    "repository": "projeto-x",
    "timestamp": "2024-01-15T10:30:00Z"
  }'

Geração de Relatórios Periódicos

# Script para relatório mensal de auditoria
#!/bin/bash
MONTH=$(date -d "last month" +%Y-%m)
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.github.com/orgs/minha-empresa/audit-log?\
  created_after=${MONTH}-01&\
  created_before=$(date +%Y-%m-01)" | \
  jq 'group_by(.action) | map({action: .[0].action, count: length})' \
  > relatorio_${MONTH}.json

Investigação Forense

Para investigar incidentes, cruze audit logs com logs de sistema e commits:

# Rastreando quem fez push de um commit específico
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.github.com/repos/minha-empresa/projeto-x/commits/abc123"

8. Limitações e Considerações de Segurança no Audit Log

Lacunas Conhecidas

  • Comandos Git locais (git commit --amend, git reset --hard) não são auditados
  • Hooks locais (pre-commit, pre-push) não geram eventos no audit log central
  • Ações em forks pessoais podem não ser registradas

Proteção Contra Adulteração

# Implementação de assinatura digital para logs
openssl dgst -sha256 -sign private_key.pem -out log.sig audit_log.json
openssl dgst -sha256 -verify public_key.pem -signature log.sig audit_log.json

Gerenciamento de Acesso aos Logs

Apenas administradores devem ter acesso aos audit logs. Implemente:
- RBAC (Role-Based Access Control) para visualização
- Logs de auditoria sobre quem acessou os audit logs (meta-auditoria)
- Armazenamento imutável (WORM - Write Once Read Many) em S3 ou Azure Blob

# Configuração de bucket S3 com política WORM
aws s3api put-object-lock-configuration \
  --bucket meu-bucket-audit-logs \
  --object-lock-configuration '{
    "ObjectLockEnabled": "Enabled",
    "Rule": {
      "DefaultRetention": {
        "Mode": "COMPLIANCE",
        "Days": 3650
      }
    }
  }'

Referências