DevOps

Compliance e Auditoria: LGPD, SOC2 e Evidências Automatizadas Já leu

19 min de leitura

Compliance e Auditoria: LGPD, SOC2 e Evidências Automatizadas
Existe uma diferença fundamental entre uma organização que é segura e uma organização que pode demonstrar que é segura. A primeira é uma propriedade técnica — medida por testes de penetração, scanning de vulnerabilidades

Existe uma diferença fundamental entre uma organização que é segura e uma organização que pode demonstrar que é segura. A primeira é uma propriedade técnica — medida por testes de penetração, scanning de vulnerabilidades e monitoramento de runtime. A segunda é uma propriedade regulatória e contratual — medida pela capacidade de produzir evidências documentadas de que controles específicos existem, funcionam e são auditados continuamente.

Frameworks como LGPD, SOC2 e ISO 27001 não exigem apenas que os controles existam — exigem que sua existência seja demonstrável. Para auditores, clientes corporativos e reguladores, a evidência de que um controle funcionou ontem é tão importante quanto o controle em si. Organizações que tratam compliance como uma atividade manual e episódica — coletando evidências às pressas antes de uma auditoria — pagam um preço alto em tempo de engenharia e risco de não conformidade.

A abordagem DevSecOps para compliance transforma esse processo: os mesmos pipelines que entregam software geram, armazenam e organizam evidências de conformidade continuamente. Quando uma auditoria chega, as evidências já existem — porque são um subproduto do trabalho de engenharia, não um esforço adicional.


Entendendo os Frameworks Relevantes

LGPD: Lei Geral de Proteção de Dados

A LGPD — Lei nº 13.709/2018 — é a lei brasileira de proteção de dados pessoais, inspirada no GDPR europeu. Seus impactos técnicos mais diretos sobre sistemas de software incluem:

Base legal para tratamento — toda operação sobre dados pessoais precisa de uma base legal documentada (consentimento, legítimo interesse, execução de contrato, etc.). Sistemas precisam registrar qual base legal justifica cada tipo de tratamento.

Direitos dos titulares — o sistema precisa implementar endpoints e processos que permitam ao titular acessar seus dados, corrigi-los, exportá-los em formato portável e solicitar sua exclusão. O prazo de atendimento é de 15 dias.

Notificação de incidentes — violações de dados que possam causar risco aos titulares devem ser notificadas à ANPD em até 72 horas. Isso exige sistemas de detecção rápida de vazamentos.

Data Protection by Design — a privacidade deve ser incorporada ao design dos sistemas, não adicionada depois. Minimização de dados, pseudonimização e criptografia são esperadas como padrão.

Registros de tratamento — o controlador deve manter um Registro das Atividades de Tratamento (ROPA — Records of Processing Activities) documentando quais dados são tratados, para qual finalidade, por quanto tempo e com quais medidas de segurança.

SOC2: Service Organization Control 2

O SOC2 é um framework de auditoria americano — mantido pelo AICPA — amplamente exigido por clientes corporativos B2B como evidência de que uma organização de software opera com controles adequados. É estruturado em torno de cinco Trust Service Criteria:

Security — proteção dos sistemas contra acesso não autorizado. É o único critério obrigatório em todos os relatórios SOC2.

Availability — os sistemas estão disponíveis conforme comprometido (SLAs). Requer monitoramento, gestão de incidentes e planos de recuperação.

Processing Integrity — o processamento de dados é completo, válido e autorizado. Relevante para sistemas de pagamento e processamento de dados críticos.

Confidentiality — dados designados como confidenciais são protegidos conforme acordado.

Privacy — dados pessoais são coletados, usados, retidos e descartados conforme a política de privacidade.

Um relatório SOC2 Type I avalia se os controles estão adequadamente desenhados em um ponto no tempo. Um SOC2 Type II — mais exigido por clientes enterprise — avalia se os controles funcionaram efetivamente durante um período (tipicamente 6 a 12 meses). É aqui que a geração contínua de evidências se torna essencial.

Mapeamento Técnico dos Controles SOC2

Os controles SOC2 do critério Security são organizados em categorias — CC1 a CC9. Os mais diretamente impactados por decisões técnicas de DevOps incluem:

CC6 — Logical and Physical Access Controls — controle de acesso baseado em princípio do menor privilégio, MFA para sistemas críticos, revisão periódica de acessos, offboarding imediato de usuários desligados.

CC7 — System Operations — monitoramento contínuo de sistemas, detecção e resposta a incidentes, gestão de vulnerabilidades, testes de controles.

CC8 — Change Management — processo documentado para todas as mudanças em produção, aprovações requeridas, testes antes do deploy, capacidade de rollback.

CC9 — Risk Mitigation — identificação e mitigação de riscos de fornecedores (supply chain), continuidade de negócios, planos de recuperação de desastres.


Implementando Logging de Auditoria Imutável

O log de auditoria é a espinha dorsal de qualquer programa de compliance — é a evidência de que ações específicas foram ou não realizadas. Para ser útil em auditorias, o log de auditoria precisa ter propriedades que o distinguem dos logs operacionais: imutabilidade, completude, integridade verificável e retenção de longo prazo.

Estrutura do Log de Auditoria

// src/audit/audit.service.js
const { EventBridge } = require('@aws-sdk/client-eventbridge');
const { CloudWatchLogs } = require('@aws-sdk/client-cloudwatch-logs');
const crypto = require('crypto');

class AuditService {
  constructor() {
    this.eventBridge = new EventBridge();
    this.logGroupName = `/auditoria/${process.env.SERVICE_NAME}`;
    this.previousHash = null;
  }

  // Gera um evento de auditoria com encadeamento de hash
  // para garantir imutabilidade e detectar adulteração
  async registrar(evento) {
    const timestamp = new Date().toISOString();

    const entradaAuditoria = {
      // Identificação do evento
      eventId: crypto.randomUUID(),
      timestamp,
      tipo: evento.tipo,          // ex: 'usuario.login', 'dado.exportado'
      resultado: evento.resultado, // 'sucesso' | 'falha' | 'negado'

      // Quem realizou a ação
      ator: {
        id: evento.ator?.id,
        email: evento.ator?.email,
        tipo: evento.ator?.tipo,   // 'usuario' | 'sistema' | 'api-key'
        ip: evento.ator?.ip,
        userAgent: evento.ator?.userAgent,
        sessionId: evento.ator?.sessionId,
      },

      // O que foi afetado
      recurso: {
        tipo: evento.recurso?.tipo,   // ex: 'usuario', 'pedido', 'relatorio'
        id: evento.recurso?.id,
        nome: evento.recurso?.nome,
      },

      // Detalhes adicionais da ação
      detalhes: evento.detalhes || {},

      // Contexto técnico
      servico: process.env.SERVICE_NAME,
      versao: process.env.APP_VERSION,
      ambiente: process.env.NODE_ENV,
      traceId: evento.traceId,

      // Hash encadeado — liga cada entrada à anterior
      // Permite detectar se entradas foram removidas ou alteradas
      hashAnterior: this.previousHash,
    };

    // Calcula o hash desta entrada para encadear à próxima
    const hashAtual = crypto
      .createHash('sha256')
      .update(JSON.stringify(entradaAuditoria))
      .digest('hex');

    entradaAuditoria.hash = hashAtual;
    this.previousHash = hashAtual;

    // Publica para EventBridge — roteado para múltiplos destinos
    await this.eventBridge.putEvents({
      Entries: [{
        Source: `${process.env.SERVICE_NAME}.auditoria`,
        DetailType: evento.tipo,
        Detail: JSON.stringify(entradaAuditoria),
        EventBusName: process.env.AUDIT_EVENT_BUS_NAME,
      }],
    });

    return entradaAuditoria;
  }

  // Registra acesso a dados pessoais — obrigatório para LGPD
  async registrarAcessoDadosPessoais(params) {
    return this.registrar({
      tipo: 'dados-pessoais.acesso',
      resultado: params.resultado || 'sucesso',
      ator: params.ator,
      recurso: {
        tipo: 'dados-pessoais',
        id: params.titularId,
        nome: params.categoria,  // 'financeiro', 'saude', 'identificacao'
      },
      detalhes: {
        finalidade: params.finalidade,
        baseLegal: params.baseLegal,
        camposAcessados: params.campos,
        quantidadeRegistros: params.quantidade,
      },
      traceId: params.traceId,
    });
  }

  // Registra mudanças em dados pessoais
  async registrarAlteracaoDadosPessoais(params) {
    return this.registrar({
      tipo: 'dados-pessoais.alteracao',
      resultado: params.resultado || 'sucesso',
      ator: params.ator,
      recurso: {
        tipo: 'dados-pessoais',
        id: params.titularId,
      },
      detalhes: {
        camposAlterados: params.campos,
        // Nunca loga os valores — apenas quais campos mudaram
        motivacao: params.motivacao,
        solicitacaoTitular: params.solicitacaoTitular || false,
      },
      traceId: params.traceId,
    });
  }
}

module.exports = new AuditService();

Infraestrutura de Auditoria na AWS

# auditoria.tf

# Event Bus dedicado para eventos de auditoria
resource "aws_cloudwatch_event_bus" "auditoria" {
  name = "${var.project_name}-${var.environment}-auditoria"
  tags = local.tags_comuns
}

# CloudWatch Log Group com retenção de 7 anos (LGPD + SOC2)
resource "aws_cloudwatch_log_group" "auditoria" {
  name              = "/auditoria/${var.project_name}/${var.environment}"
  retention_in_days = 2557  # 7 anos em dias
  kms_key_id        = aws_kms_key.auditoria.arn

  tags = local.tags_comuns
}

# Regra que roteia TODOS os eventos do bus de auditoria para o CloudWatch
resource "aws_cloudwatch_event_rule" "auditoria_para_cloudwatch" {
  name           = "auditoria-todos-eventos"
  event_bus_name = aws_cloudwatch_event_bus.auditoria.name
  event_pattern  = jsonencode({ source = [{ prefix = "" }] })

  tags = local.tags_comuns
}

resource "aws_cloudwatch_event_target" "auditoria_cloudwatch" {
  rule           = aws_cloudwatch_event_rule.auditoria_para_cloudwatch.name
  event_bus_name = aws_cloudwatch_event_bus.auditoria.name
  target_id      = "cloudwatch-logs"
  arn            = aws_cloudwatch_log_group.auditoria.arn
}

# Bucket S3 para arquivo de longo prazo com Object Lock
# Object Lock garante imutabilidade — nem administradores podem deletar
resource "aws_s3_bucket" "auditoria_arquivo" {
  bucket = "${var.project_name}-${var.environment}-auditoria-arquivo"

  # Object Lock deve ser habilitado na criação — não pode ser ativado depois
  object_lock_enabled = true

  tags = local.tags_comuns
}

resource "aws_s3_bucket_object_lock_configuration" "auditoria" {
  bucket = aws_s3_bucket.auditoria_arquivo.id

  rule {
    default_retention {
      mode  = "COMPLIANCE"  # COMPLIANCE = nem o root pode deletar
      years = 7
    }
  }
}

resource "aws_s3_bucket_versioning" "auditoria" {
  bucket = aws_s3_bucket.auditoria_arquivo.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "auditoria" {
  bucket = aws_s3_bucket.auditoria_arquivo.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.auditoria.arn
    }
    bucket_key_enabled = true
  }
}

resource "aws_s3_bucket_public_access_block" "auditoria" {
  bucket                  = aws_s3_bucket.auditoria_arquivo.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# CloudTrail — registra todas as chamadas de API da AWS
resource "aws_cloudtrail" "principal" {
  name                          = "${var.project_name}-${var.environment}-trail"
  s3_bucket_name                = aws_s3_bucket.auditoria_arquivo.id
  s3_key_prefix                 = "cloudtrail"
  include_global_service_events = true
  is_multi_region_trail         = true
  enable_log_file_validation    = true  # Detecta adulteração nos logs
  kms_key_id                    = aws_kms_key.auditoria.arn
  cloud_watch_logs_group_arn    = "${aws_cloudwatch_log_group.cloudtrail.arn}:*"
  cloud_watch_logs_role_arn     = aws_iam_role.cloudtrail.arn

  event_selector {
    read_write_type           = "All"
    include_management_events = true

    data_resource {
      type   = "AWS::S3::Object"
      values = ["arn:aws:s3:::"]  # Todos os buckets S3
    }

    data_resource {
      type   = "AWS::Lambda::Function"
      values = ["arn:aws:lambda"]  # Todas as funções Lambda
    }
  }

  tags = local.tags_comuns
}

resource "aws_cloudwatch_log_group" "cloudtrail" {
  name              = "/cloudtrail/${var.project_name}/${var.environment}"
  retention_in_days = 2557
  kms_key_id        = aws_kms_key.auditoria.arn
  tags              = local.tags_comuns
}

Implementando os Direitos dos Titulares (LGPD)

// src/lgpd/titular.controller.js
const auditoria = require('../audit/audit.service');
const titularService = require('./titular.service');

class TitularController {
  // Art. 18, I — Direito de acesso
  async exportarMeusDados(req, res) {
    const { titularId } = req.params;

    // Verifica que o usuário autenticado é o próprio titular
    if (req.usuario.id !== titularId) {
      await auditoria.registrar({
        tipo: 'lgpd.acesso-dados.negado',
        resultado: 'negado',
        ator: { id: req.usuario.id, ip: req.ip },
        recurso: { tipo: 'dados-pessoais', id: titularId },
        detalhes: { motivo: 'titular-diferente-do-solicitante' },
        traceId: req.traceId,
      });
      return res.status(403).json({ erro: 'Acesso negado' });
    }

    const dados = await titularService.coletarTodosDados(titularId);

    await auditoria.registrarAcessoDadosPessoais({
      ator: { id: req.usuario.id, ip: req.ip },
      titularId,
      categoria: 'todos',
      finalidade: 'portabilidade-lgpd-art18',
      baseLegal: 'exercicio-de-direitos',
      campos: Object.keys(dados),
      quantidade: 1,
      traceId: req.traceId,
    });

    // Retorna em formato legível e portável (JSON)
    res.setHeader('Content-Disposition',
      `attachment; filename="meus-dados-${titularId}-${Date.now()}.json"`);
    res.json({
      exportadoEm: new Date().toISOString(),
      titular: titularId,
      dados,
      aviso: 'Exportação gerada em atendimento ao Art. 18, V da LGPD',
    });
  }

  // Art. 18, VI — Direito de exclusão
  async solicitarExclusao(req, res) {
    const { titularId } = req.params;
    const { motivo } = req.body;

    if (req.usuario.id !== titularId) {
      return res.status(403).json({ erro: 'Acesso negado' });
    }

    // Cria solicitação com prazo de 15 dias (Art. 19)
    const solicitacao = await titularService.criarSolicitacaoExclusao({
      titularId,
      motivo,
      prazoAtendimento: new Date(Date.now() + 15 * 24 * 60 * 60 * 1000),
      solicitadoPor: req.usuario.id,
    });

    await auditoria.registrar({
      tipo: 'lgpd.exclusao-dados.solicitada',
      resultado: 'sucesso',
      ator: { id: req.usuario.id, ip: req.ip },
      recurso: { tipo: 'dados-pessoais', id: titularId },
      detalhes: {
        solicitacaoId: solicitacao.id,
        motivo,
        prazoAtendimento: solicitacao.prazoAtendimento,
      },
      traceId: req.traceId,
    });

    res.json({
      solicitacaoId: solicitacao.id,
      prazoAtendimento: solicitacao.prazoAtendimento,
      mensagem: 'Solicitação recebida. Você será notificado por email quando concluída.',
    });
  }

  // Processo de anonimização para exclusão (Art. 18, VI)
  async processarExclusao(solicitacaoId) {
    const solicitacao = await titularService
      .buscarSolicitacao(solicitacaoId);

    // Anonimiza — não deleta, pois pode haver obrigação legal de retenção
    // Ex: dados fiscais devem ser mantidos por 5 anos
    await titularService.anonimizarDados(solicitacao.titularId, {
      manterParaObrigacaoLegal: ['dados-fiscais', 'logs-transacao'],
    });

    await auditoria.registrar({
      tipo: 'lgpd.exclusao-dados.concluida',
      resultado: 'sucesso',
      ator: { id: 'sistema', tipo: 'sistema' },
      recurso: { tipo: 'dados-pessoais', id: solicitacao.titularId },
      detalhes: {
        solicitacaoId,
        dadosAnonimizados: true,
        dadosRetidosPorObrigacaoLegal: ['dados-fiscais', 'logs-transacao'],
        baseRetencao: 'Lei 9.394/1996 art. 37 — obrigação contábil 5 anos',
      },
      traceId: crypto.randomUUID(),
    });
  }
}

Geração Automatizada de Evidências para SOC2

Para SOC2 Type II, a evidência precisa demonstrar que controles funcionaram ao longo do tempo — não apenas que existem. A coleta pode ser automatizada como parte do pipeline:

#!/bin/bash
# scripts/coletar-evidencias-soc2.sh
# Executa mensalmente via GitHub Actions para coletar evidências SOC2
# Resultados armazenados no S3 com Object Lock para imutabilidade

set -euo pipefail

PERIODO="${1:-$(date +%Y-%m)}"
BUCKET="${SOC2_EVIDENCIAS_BUCKET}"
PREFIXO="soc2/${PERIODO}"
REGIAO="us-east-1"

log() { echo "[$(date -u +%H:%M:%S)] $*"; }

# ── CC6: Controle de Acesso ───────────────────────

log "Coletando evidências CC6 — Controle de Acesso..."

# Lista usuários IAM com acesso à conta
aws iam get-credential-report --query 'Content' --output text \
  | base64 -d \
  > /tmp/iam-credential-report.csv

aws s3 cp /tmp/iam-credential-report.csv \
  "s3://${BUCKET}/${PREFIXO}/cc6/iam-credential-report.csv"

# Verifica políticas MFA
aws iam list-users --output json \
  | jq '.Users[] | {
      usuario: .UserName,
      criado: .CreateDate,
      ultimo_acesso: .PasswordLastUsed
    }' \
  > /tmp/usuarios-iam.json

# Verifica quais usuários têm MFA habilitado
while IFS= read -r usuario; do
  MFA=$(aws iam list-mfa-devices \
    --user-name "$usuario" \
    --query 'MFADevices | length(@)')
  echo "{\"usuario\": \"$usuario\", \"mfa_habilitado\": $([ "$MFA" -gt 0 ] && echo true || echo false)}"
done < <(aws iam list-users --query 'Users[].UserName' --output text | tr '\t' '\n') \
  > /tmp/mfa-status.json

aws s3 cp /tmp/mfa-status.json \
  "s3://${BUCKET}/${PREFIXO}/cc6/mfa-status.json"

# ── CC7: Operações do Sistema ─────────────────────

log "Coletando evidências CC7 — Operações do Sistema..."

# Métricas de disponibilidade do mês
aws cloudwatch get-metric-statistics \
  --namespace AWS/ApplicationELB \
  --metric-name HTTPCode_ELB_5XX_Count \
  --dimensions Name=LoadBalancer,Value="${ALB_NAME}" \
  --start-time "${PERIODO}-01T00:00:00Z" \
  --end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --period 86400 \
  --statistics Sum \
  --output json \
  > /tmp/erros-alb.json

aws s3 cp /tmp/erros-alb.json \
  "s3://${BUCKET}/${PREFIXO}/cc7/metricas-disponibilidade.json"

# Relatório de vulnerabilidades identificadas e remediadas
aws securityhub get-findings \
  --filters '{
    "CreatedAt": [{"Start": "'"${PERIODO}"'-01T00:00:00Z",
                   "End": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"}],
    "RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}]
  }' \
  --query 'Findings[*].{
    Titulo: Title,
    Severidade: Severity.Label,
    Status: Workflow.Status,
    Criado: CreatedAt
  }' \
  --output json \
  > /tmp/findings-seguranca.json

aws s3 cp /tmp/findings-seguranca.json \
  "s3://${BUCKET}/${PREFIXO}/cc7/vulnerabilidades-identificadas.json"

# ── CC8: Gestão de Mudanças ───────────────────────

log "Coletando evidências CC8 — Gestão de Mudanças..."

# Histórico de deploys do mês via GitHub API
curl -s \
  -H "Authorization: Bearer ${GITHUB_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/${GITHUB_ORG}/${GITHUB_REPO}/deployments?per_page=100" \
  | jq "[.[] | select(.created_at | startswith(\"${PERIODO}\"))]" \
  > /tmp/deployments-mes.json

aws s3 cp /tmp/deployments-mes.json \
  "s3://${BUCKET}/${PREFIXO}/cc8/deployments.json"

# PRs mergeados no período — evidência de revisão de código
curl -s \
  -H "Authorization: Bearer ${GITHUB_TOKEN}" \
  "https://api.github.com/repos/${GITHUB_ORG}/${GITHUB_REPO}/pulls?state=closed&per_page=100" \
  | jq "[.[] | select(.merged_at != null and (.merged_at | startswith(\"${PERIODO}\")))]
        | map({
            numero: .number,
            titulo: .title,
            autor: .user.login,
            revisores: [.requested_reviewers[].login],
            mergeado_por: .merged_by.login,
            mergeado_em: .merged_at
          })" \
  > /tmp/prs-mergeados.json

aws s3 cp /tmp/prs-mergeados.json \
  "s3://${BUCKET}/${PREFIXO}/cc8/pull-requests-revisados.json"

# ── Gera índice consolidado ───────────────────────

log "Gerando índice de evidências..."

cat > /tmp/indice.json << EOF
{
  "periodo": "${PERIODO}",
  "gerado_em": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "gerado_por": "pipeline-automatizado",
  "evidencias": {
    "CC6": {
      "descricao": "Controle de acesso e gestão de identidades",
      "arquivos": [
        "${PREFIXO}/cc6/iam-credential-report.csv",
        "${PREFIXO}/cc6/mfa-status.json"
      ]
    },
    "CC7": {
      "descricao": "Operações do sistema e gestão de vulnerabilidades",
      "arquivos": [
        "${PREFIXO}/cc7/metricas-disponibilidade.json",
        "${PREFIXO}/cc7/vulnerabilidades-identificadas.json"
      ]
    },
    "CC8": {
      "descricao": "Gestão de mudanças e revisão de código",
      "arquivos": [
        "${PREFIXO}/cc8/deployments.json",
        "${PREFIXO}/cc8/pull-requests-revisados.json"
      ]
    }
  }
}
EOF

aws s3 cp /tmp/indice.json \
  "s3://${BUCKET}/${PREFIXO}/indice.json"

log "Coleta de evidências concluída para o período ${PERIODO}"

Automatizando a coleta mensalmente:

# .github/workflows/coletar-evidencias-soc2.yml
name: Coleta Mensal de Evidências SOC2

on:
  schedule:
    - cron: '0 6 1 * *'  # Primeiro dia de cada mês às 6h UTC
  workflow_dispatch:
    inputs:
      periodo:
        description: 'Período no formato YYYY-MM'
        required: false

jobs:
  coletar:
    runs-on: ubuntu-latest
    environment: production

    permissions:
      contents: read
      id-token: write

    steps:
      - uses: actions/checkout@v4

      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_COMPLIANCE_ROLE_ARN }}
          aws-region: us-east-1

      - name: Coleta evidências SOC2
        run: |
          PERIODO="${{ inputs.periodo || '' }}"
          if [ -z "$PERIODO" ]; then
            PERIODO=$(date -d "last month" +%Y-%m 2>/dev/null || \
                      date -v-1m +%Y-%m)
          fi
          bash scripts/coletar-evidencias-soc2.sh "$PERIODO"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITHUB_ORG: ${{ github.repository_owner }}
          GITHUB_REPO: ${{ github.event.repository.name }}
          ALB_NAME: ${{ vars.ALB_NAME }}
          SOC2_EVIDENCIAS_BUCKET: ${{ vars.SOC2_EVIDENCIAS_BUCKET }}

      - name: Notifica time de compliance
        if: success()
        uses: slackapi/slack-github-action@v1.26.0
        with:
          channel-id: ${{ vars.SLACK_COMPLIANCE_CHANNEL }}
          slack-message: |
            ✅ *Evidências SOC2 coletadas automaticamente*
            Período: ${{ inputs.periodo || 'mês anterior' }}
            Bucket: ${{ vars.SOC2_EVIDENCIAS_BUCKET }}
            Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
        env:
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

Registro de Atividades de Tratamento (ROPA)

O ROPA é obrigação direta da LGPD para o controlador. Na prática, é um documento vivo que descreve cada operação de tratamento de dados pessoais. A infraestrutura pode automatizar a geração de parte desse documento:

// src/lgpd/ropa.js
// Registro das Atividades de Tratamento — Art. 37 LGPD

const ROPA = [
  {
    id: 'cadastro-usuarios',
    nome: 'Cadastro e autenticação de usuários',
    controlador: 'Empresa S.A. — CNPJ XX.XXX.XXX/0001-XX',
    encarregado: 'dpo@empresa.com',

    finalidade: 'Criação e gestão de contas de usuário para acesso à plataforma',
    baseLegal: 'Execução de contrato — Art. 7º, V, LGPD',

    categoriaTitulares: 'Clientes e usuários cadastrados',
    categoriasDados: [
      { dado: 'Nome completo', sensivel: false },
      { dado: 'E-mail', sensivel: false },
      { dado: 'CPF', sensivel: false },
      { dado: 'Senha (hash bcrypt)', sensivel: false },
      { dado: 'Data de nascimento', sensivel: false },
      { dado: 'IP de acesso', sensivel: false },
    ],

    prazoRetencao: '5 anos após encerramento da conta (obrigação legal fiscal)',
    criterioRetencao: 'Decreto 9.580/2018 — obrigação contábil',

    compartilhamento: [
      {
        receptor: 'AWS (processador)',
        pais: 'Brasil (us-east-1 com mecanismos adequados)',
        finalidade: 'Hospedagem e processamento de dados',
        garantia: 'DPA com AWS — cláusulas contratuais padrão',
      },
    ],

    medidasSeguranca: [
      'Criptografia em trânsito (TLS 1.2+)',
      'Criptografia em repouso (AES-256 via AWS KMS)',
      'Controle de acesso baseado em papéis (RBAC)',
      'Autenticação multifator para administradores',
      'Logs de auditoria de todos os acessos',
    ],

    avaliacaoRisco: 'Baixo — dados não sensíveis, processamento comum',
    dataUltimaRevisao: '2025-01-15',
    proximaRevisao: '2026-01-15',
  },

  {
    id: 'processamento-pagamentos',
    nome: 'Processamento de pagamentos',
    baseLegal: 'Execução de contrato — Art. 7º, V, LGPD',

    categoriasDados: [
      { dado: 'Dados do cartão (tokenizados — não armazenados)', sensivel: false },
      { dado: 'Valor da transação', sensivel: false },
      { dado: 'Histórico de compras', sensivel: false },
    ],

    compartilhamento: [
      {
        receptor: 'Gateway de Pagamento XYZ',
        pais: 'Brasil',
        finalidade: 'Processamento de transações financeiras',
        garantia: 'Contrato com cláusulas de proteção de dados',
      },
    ],

    prazoRetencao: '10 anos (obrigação legal — Banco Central do Brasil)',
    avaliacaoRisco: 'Médio — dados financeiros, processador regulado pelo BACEN',
    dataUltimaRevisao: '2025-01-15',
  },
];

module.exports = { ROPA };

O Que Vem a Seguir

O próximo artigo cobre o tema de Performance e Otimização de Custos em Cloud — como identificar gargalos de performance em produção, como aplicar práticas de FinOps para controlar e otimizar os custos AWS, e como construir dashboards de custo que conectam gastos de infraestrutura ao valor entregue.


Referências para Aprofundamento

LGPD e regulação brasileira - Lei Geral de Proteção de Dados — planalto.gov.br — Texto integral da LGPD com todas as alterações, incluindo direitos dos titulares, bases legais e obrigações do controlador. - ANPD — Guias e Orientações — gov.br — Guias oficiais da Autoridade Nacional de Proteção de Dados sobre implementação da LGPD, incluindo orientações sobre ROPA e notificação de incidentes.

SOC2 e frameworks internacionais - AICPA SOC2 Overview — aicpa-cima.org — Visão geral oficial do SOC2 pelo AICPA, incluindo os Trust Service Criteria e diferença entre Type I e Type II. - AWS Compliance Center — aws.amazon.com — Centro de compliance da AWS com relatórios SOC2, ISO 27001, PCI-DSS e outros frameworks, incluindo o AWS Shared Responsibility Model.

Ferramentas - AWS CloudTrail Documentation — docs.aws.amazon.com — Documentação completa do CloudTrail com guia de configuração de trilhas multi-região, validação de integridade de logs e integração com CloudWatch. - AWS Security Hub — docs.aws.amazon.com — Documentação do Security Hub, incluindo os padrões de segurança disponíveis (AWS Foundational Security Best Practices, CIS, PCI-DSS) e integração com GuardDuty e Inspector.

Comentários

Mais em DevOps

Gerando e Revisando Pipelines com IA
Gerando e Revisando Pipelines com IA

O GitHub Copilot foi lançado em 2021. O ChatGPT em novembro de 2022. O Cursor...

Projeto Capstone: Arquitetura do Sistema Completo
Projeto Capstone: Arquitetura do Sistema Completo

Os quarenta e sete artigos anteriores cobriram, em progressão cuidadosa, cada...

Trabalhando em Equipe com Git Flow
Trabalhando em Equipe com Git Flow

O Git oferece branches, mas n&atilde;o diz como us&aacute;-las. Em uma equipe...