Conformidade e auditoria

Conformidade regulatória e auditoria em sistemas distribuídos: logs de auditoria, GDPR, criptografia de dados, retenção e rastreabilidade de ações.

Por que a conformidade importa na arquitetura

A conformidade regulatória não é apenas uma questão jurídica — ela tem implicações diretas em como um sistema é projetado e operado. Regulamentações como GDPR, PCI-DSS ou SOC 2 impõem requisitos técnicos concretos sobre como os dados são armazenados, processados e protegidos.

Ignorar a conformidade durante o design da arquitetura significa ter que fazer mudanças custosas depois ou, pior, enfrentar sanções legais e a perda de confiança dos usuários.

Logs de auditoria

Os logs de auditoria registram quem fez o quê, quando e sobre qual recurso. Eles são a base de qualquer estratégia de conformidade.

O que registrar

Nem tudo precisa de um log de auditoria. Concentre-se em:

  • Autenticação: login bem-sucedido, login falho, logout, troca de senha
  • Autorização: acesso negado, mudança de papéis ou permissões
  • Dados sensíveis: leitura, criação, modificação ou exclusão de dados pessoais
  • Configuração: mudanças na configuração do sistema, deploys
  • Operações críticas: transações financeiras, exclusão de contas, exportação de dados

Estrutura de um log de auditoria

{
  "timestamp": "2024-01-15T14:30:00.000Z",
  "eventType": "DATA_ACCESS",
  "action": "READ",
  "actor": {
    "userId": "user-456",
    "role": "admin",
    "ip": "192.168.1.100",
    "userAgent": "Mozilla/5.0..."
  },
  "resource": {
    "type": "user_profile",
    "id": "user-789",
    "fields": ["email", "phone", "address"]
  },
  "result": "SUCCESS",
  "metadata": {
    "service": "users-service",
    "requestId": "req-abc-123",
    "traceId": "trace-xyz-789"
  }
}

Propriedades de um bom log de auditoria

PropriedadeDescrição
ImutávelUma vez escrito, não pode ser modificado nem excluído
CompletoContém todas as informações necessárias para reconstruir o evento
RastreávelPode ser correlacionado com outros logs por meio de requestId ou traceId
SeguroProtegido contra acesso não autorizado e manipulação
RetidoArmazenado durante o período exigido pela regulamentação

Implementação prática

class AuditLogger {
  async log(event) {
    const auditEntry = {
      timestamp: new Date().toISOString(),
      eventType: event.type,
      action: event.action,
      actor: {
        userId: event.userId,
        role: event.userRole,
        ip: event.clientIp,
      },
      resource: {
        type: event.resourceType,
        id: event.resourceId,
      },
      result: event.result,
      metadata: {
        service: process.env.SERVICE_NAME,
        requestId: event.requestId,
        traceId: event.traceId,
      }
    };

    // Escrever em um armazenamento imutável
    await this.auditStore.append(auditEntry);
    
    // Nunca falhar silenciosamente na auditoria
    // Se não for possível registrar, a operação deve falhar
  }
}

Armazenamento de logs de auditoria

Os logs de auditoria exigem um armazenamento especial:

  • Append-only: só é possível adicionar registros, nunca modificar ou excluir
  • Separado: em um banco de dados ou serviço diferente do da aplicação
  • Criptografado: os logs podem conter dados sensíveis
  • Replicado: cópias em múltiplas localizações para prevenir perda

Opções comuns:

  • Amazon S3 com Object Lock (imutabilidade)
  • Elasticsearch com índices somente leitura
  • Banco de dados dedicado com permissões apenas de inserção
  • Serviços especializados como Splunk ou Datadog

GDPR e proteção de dados pessoais

O Regulamento Geral de Proteção de Dados (GDPR) da União Europeia estabelece requisitos rigorosos sobre como os dados pessoais são tratados. Embora seja uma regulamentação europeia, ela afeta qualquer sistema que processe dados de residentes da UE.

Princípios-chave do GDPR

  1. Minimização de dados: coletar apenas os dados estritamente necessários
  2. Limitação de finalidade: usar os dados somente para o fim declarado
  3. Limitação de armazenamento: não reter dados por mais tempo do que o necessário
  4. Integridade e confidencialidade: proteger os dados contra acesso não autorizado
  5. Responsabilização proativa: demonstrar conformidade, não apenas cumpri-la

Direitos do usuário que afetam a arquitetura

Direito de acesso (Art. 15)

O usuário pode solicitar todos os dados que o sistema possui sobre ele:

// O sistema deve ser capaz de reunir dados de TODOS os serviços
async function getUserData(userId) {
  const [profile, orders, payments, logs] = await Promise.all([
    usersService.getData(userId),
    ordersService.getData(userId),
    paymentsService.getData(userId),
    auditService.getData(userId),
  ]);
  
  return {
    personalData: profile,
    orderHistory: orders,
    paymentHistory: payments,
    activityLog: logs,
    exportedAt: new Date().toISOString()
  };
}

Isso implica que cada microsserviço deve ser capaz de exportar os dados de um usuário específico.

Direito ao esquecimento (Art. 17)

O usuário pode solicitar a exclusão de todos os seus dados:

async function deleteUserData(userId) {
  // Excluir de todos os serviços
  await usersService.deleteUser(userId);
  await ordersService.anonymizeOrders(userId);
  await paymentsService.anonymizePayments(userId);
  
  // Alguns dados não podem ser excluídos (obrigações legais)
  // mas podem ser anonimizados
  await auditService.anonymizeEntries(userId);
  
  // Registrar a exclusão (paradoxalmente, isto sim é retido)
  await auditLogger.log({
    type: 'DATA_DELETION',
    action: 'DELETE',
    userId: 'ANONYMIZED',
    resourceId: userId
  });
}

Direito à portabilidade (Art. 20)

O usuário pode solicitar seus dados em um formato legível por máquina:

{
  "format": "JSON",
  "exportDate": "2024-01-15",
  "userData": {
    "profile": { "name": "María García", "email": "maria@ejemplo.com" },
    "orders": [
      { "id": "ord-001", "date": "2024-01-10", "total": 150.00 }
    ]
  }
}

Implicações arquiteturais do GDPR

  • Cada serviço deve saber quais dados pessoais armazena
  • Deve existir um mecanismo centralizado para executar os direitos do usuário
  • Os dados devem poder ser anonimizados sem quebrar a integridade do sistema
  • Os logs de auditoria devem equilibrar a retenção com o direito ao esquecimento

Criptografia de dados

Criptografia em trânsito

Todo dado que trafega pela rede deve estar criptografado:

  • TLS 1.2+ para comunicação externa
  • mTLS para comunicação entre serviços
  • Criptografia de mensagens em filas e barramentos de eventos

Criptografia em repouso

Os dados armazenados devem estar criptografados:

Níveis de criptografia em repouso:

1. Criptografia de disco (transparente)
   - AWS EBS encryption, Azure Disk Encryption
   - Protege contra roubo físico do disco

2. Criptografia de banco de dados (TDE)
   - Transparent Data Encryption em PostgreSQL, MySQL
   - Protege contra acesso direto aos arquivos do BD

3. Criptografia em nível de campo (application-level)
   - Campos específicos criptografados pela aplicação
   - Protege mesmo que o BD seja comprometido

Criptografia em nível de campo

Para dados especialmente sensíveis, criptografe campos individuais:

const crypto = require('crypto');

class FieldEncryption {
  constructor(key) {
    this.key = Buffer.from(key, 'hex');
  }

  encrypt(plaintext) {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv('aes-256-gcm', this.key, iv);
    let encrypted = cipher.update(plaintext, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    const tag = cipher.getAuthTag().toString('hex');
    return `${iv.toString('hex')}:${tag}:${encrypted}`;
  }

  decrypt(ciphertext) {
    const [ivHex, tagHex, encrypted] = ciphertext.split(':');
    const iv = Buffer.from(ivHex, 'hex');
    const tag = Buffer.from(tagHex, 'hex');
    const decipher = crypto.createDecipheriv('aes-256-gcm', this.key, iv);
    decipher.setAuthTag(tag);
    let decrypted = decipher.update(encrypted, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
  }
}

// Uso
const encryption = new FieldEncryption(process.env.ENCRYPTION_KEY);
const encryptedSSN = encryption.encrypt('123-45-6789');

Gestão de chaves

As chaves de criptografia são tão sensíveis quanto os dados que protegem:

  • Nunca armazenar chaves no código-fonte
  • Usar um serviço de gestão de chaves (KMS): AWS KMS, Azure Key Vault, HashiCorp Vault
  • Rotacionar chaves periodicamente
  • Manter chaves separadas por ambiente (desenvolvimento, staging, produção)
  • Implementar envelope encryption para dados em grande escala

Retenção de dados

Cada tipo de dado tem um período de retenção diferente conforme a regulamentação e a finalidade:

Tipo de dadoRetenção típicaMotivo
Logs de auditoria1–7 anosConformidade regulatória
Dados de transações5–10 anosObrigações fiscais
Dados pessoaisEnquanto forem necessáriosGDPR: minimização
Logs de aplicação30–90 diasDebugging e operações
Backups30–365 diasRecuperação de desastres

Implementação de políticas de retenção

# Política de retenção por tipo de dado
retention_policies:
  audit_logs:
    retention_days: 2555  # 7 anos
    storage: s3-archive
    encryption: aes-256
    immutable: true
    
  application_logs:
    retention_days: 90
    storage: elasticsearch
    auto_delete: true
    
  user_data:
    retention: until_deletion_request
    anonymization: on_request
    backup_retention_days: 30
    
  transaction_data:
    retention_days: 3650  # 10 anos
    storage: database
    anonymization: after_retention

Rastreabilidade de ações

Em um sistema distribuído, uma ação do usuário pode envolver múltiplos serviços. A rastreabilidade permite reconstruir o caminho completo:

Usuário solicita excluir sua conta
  → API Gateway (request recebido)
    → BFF (orquestra a exclusão)
      → Users Service (exclui o perfil)
      → Orders Service (anonimiza os pedidos)
      → Payments Service (anonimiza os pagamentos)
      → Notifications Service (envia confirmação)
    → Audit Service (registra a operação completa)

Correlation ID

Cada request gera um ID único que se propaga por todos os serviços:

// Middleware que gera ou propaga o correlation ID
function correlationMiddleware(req, res, next) {
  const correlationId = req.headers['x-correlation-id'] || uuid();
  req.correlationId = correlationId;
  res.setHeader('x-correlation-id', correlationId);
  
  // Incluir em todos os logs
  req.logger = logger.child({ correlationId });
  
  next();
}

Com o correlation ID, você pode pesquisar nos logs de todos os serviços e reconstruir exatamente o que aconteceu em cada etapa.

Checklist de conformidade

Para verificar se sua arquitetura atende aos requisitos básicos:

  • Os logs de auditoria são imutáveis e estão criptografados
  • Cada serviço pode exportar os dados de um usuário específico
  • Existe um mecanismo para excluir ou anonimizar os dados de um usuário
  • Os dados em trânsito estão criptografados (TLS/mTLS)
  • Os dados em repouso estão criptografados
  • As chaves de criptografia são gerenciadas em um KMS, não no código
  • Existem políticas de retenção definidas por tipo de dado
  • Cada request tem um correlation ID para rastreabilidade
  • Os acessos a dados sensíveis são registrados no log de auditoria
  • Os dados pessoais são coletados com consentimento explícito

Resumo

A conformidade regulatória e a auditoria são responsabilidades arquiteturais, não apenas jurídicas. Os logs de auditoria imutáveis fornecem a base para demonstrar conformidade. O GDPR impõe requisitos concretos sobre como os dados pessoais são armazenados, exportados e excluídos — e esses requisitos afetam diretamente o design de cada microsserviço. A criptografia protege os dados em trânsito e em repouso, e a gestão de chaves é tão crítica quanto a própria criptografia. A rastreabilidade por meio de correlation IDs permite reconstruir qualquer ação através de múltiplos serviços. Projetar para conformidade desde o início é muito mais econômico do que se adaptar depois.