Pular para o conteúdo principal

ADR 0003 — Autenticação dupla: API Key + JWT

Introdução ao documento

Este ADR registra a decisão de implementar autenticação dupla (API Key para acesso geral + JWT para operações sensíveis) na API.

Versionamento

  • Versão do documento: 1.0.0
  • Última atualização: 2026-03-04
  • Responsável: Time Dhedalos

Referencial teórico

Contexto

  • A API é consumida por um app mobile que precisa de autenticação segura mas sem fluxo de login tradicional (OAuth/session).
  • Diferentes endpoints possuem diferentes níveis de sensibilidade: leitura de submissões vs. criação de submissões.
  • Evidência: app/Http/Middleware/ApiKeyMiddleware.php, app/Http/Middleware/JwtAuthenticate.php, routes/api.php

Decisão

  1. Implementar middleware api.key para endpoints de leitura e operações gerais — valida uma chave estática armazenada na tabela api_keys.
  2. Implementar middleware jwt.auth para operações sensíveis (criação de submissão) — valida JWT Bearer token (HS256, 1h de expiração).
  3. O JWT é gerado pelo próprio serviço via GET /api/submissions/token (protegido por API Key).
  4. Utilizar firebase/php-jwt para encoding/decoding de JWT.

Consequências

Positivas

  • Separação de preocupações: API Key para autenticação de serviço, JWT para autenticação de operação.
  • JWT com expiração curta (1h) limita janela de abuso em caso de vazamento.
  • API Key permite revogar acesso facilmente sem afetar tokens em trânsito.
  • Implementação simples e auditável via middleware.

Negativas

  • JWT gerado internamente sem refresh token — client precisa obter novo token a cada hora.
  • API Key transmitida em texto no header (necessário HTTPS em produção).
  • Sem rate limiting granular por API Key individual (apenas rate limiter global do Fortify para login).

Alternativas consideradas

  • Laravel Sanctum — tokens de API com scopes. Configurado no projeto mas usado apenas para GET /api/user (default). Não adotado para endpoints principais.
  • OAuth 2.0 — mais robusto mas excessivo para o caso de uso mobile simples.
  • Apenas JWT — sem API Key; perderia a capacidade de revogar acesso ao serviço de forma independente.

Pendências

  • ⚠️ PENDÊNCIA: Avaliar adição de rate limiting por API Key individual.
  • ⚠️ PENDÊNCIA: JWT_SECRET não consta no .env.example — deve ser adicionada.