# P13 — Integrações externas e operação de confiança

| Campo | Valor |
|---|---|
| Programa | F7+ — operação, estrutura e conteúdo |
| Status | `adiado` (pós-P29; opcional, reavaliar após toda a implementação — D10) |
| Depende de | P3, P4, P9, P10 |
| Habilita | — (fim do programa) |
| Tamanho | **G** (4–6 sessões, parcialmente externo) |
| ADRs | ADR-002, ADR-019, ADR-020, ADR-021, ADR-027, ADR-037; ADR própria para SSO/ICP; `REVISAO` §7 Onda C |

## 1. Objetivo

Fechar o que depende de **terceiro, credencial ou ato oficial** — gov.br SSO, assinatura ICP-Brasil,
deliverability de e-mail e decisão de CDN — sem transformar dependência externa em bloqueio do
produto. **D10:** toda a trilha fica **adiada para o fim do backlog**, opcional, e será reavaliada
após **toda** a implementação; nenhum item externo bloqueia P0–P29. O login local continua sendo o
break-glass.

**Resultado observável:** um operador entra pelo gov.br e é vinculado a um `cms_user` existente; o
login local continua funcionando; um PDF de legislação é assinado/verificado com carimbo do tempo;
e-mails têm SPF/DKIM/DMARC verificados e supressão registrada; CDN tem decisão medida, não palpite.

## 2. Pré-condições externas (não são código)

| Item | Pré-condição | Se faltar |
|---|---|---|
| gov.br SSO | credenciamento do órgão, `client_id`/`client_secret`, redirect URI, escopos | fica `PODE`; login local opera |
| ICP-Brasil | certificado A1/A3, TSA/OCSP acessíveis, biblioteca permissiva compatível com PHP 8.4 | fica `PODE`; Legislação funciona sem assinatura |
| E-mail | domínio, DNS (SPF/DKIM/DMARC), provedor SMTP | dev usa Mailpit; produção depende do DNS |
| CDN | medição de origem e contrato comercial | não implementar (decisão registrada) |

## 3. Escopo fechado

### S1 — gov.br SSO (OIDC/OAuth2)

- Fluxo Authorization Code + PKCE, `state`/`nonce` de uso único, redirect URI allowlist, timeout,
  validação de `iss`/`aud`/`exp`/assinatura; nenhum token em URL/log.
- Vínculo **explícito**: o SSO autentica, mas só entra quem já tem `cms_user` ativo com o `sub`
  gov.br vinculado; auto-provisionamento **não** (deny-by-default, ADR-033/037). Tela de vínculo no
  perfil próprio (P2) exige sessão local.
- Se o `sub` não estiver vinculado: mensagem genérica + auditoria `core.sso_denied` (sem PII além do
  `sub` hasheado? guardar `sub` é necessário para o vínculo; nunca CPF).
- Break-glass: `POST /login` local continua; doc/runbook; teste de indisponibilidade do gov.br.
- Logout: sessão local encerrada; logout no provedor é opcional (documentar).
- Auditoria: `core.sso_login`, `core.sso_link`, `core.sso_denied`; sem token/credencial.
- Testes com provedor fake (HTTP fake, chaves de teste), state/nonce, conta inativa, sem vínculo.

### S2 — ICP-Brasil / assinatura digital

- **Spike primeiro** (timebox): bibliotecas PHP 8.4 com licença permissiva, PAdES, TSA e verificação;
  se nenhuma atender, registrar decisão e não implementar.
- Serviço `DigitalSignature` (ou módulo) com:
  - importação de certificado A1 (PFX) cifrada; chave privada nunca em claro, nunca em log;
  - assinatura PAdES de PDF (Legislação) com carimbo do tempo e cadeia;
  - endpoint de **verificação pública** (hash + assinatura + status TSA/OCSP), sem expor dados
    pessoais do signatário além do necessário;
  - armazenamento de chave com o mesmo rigor do segredo de aplicação (ADR-020), rotação e revogação.
- Sem TSA/OCSP não há “assinatura válida” — o produto deve dizer isso, não simular.
- Auditoria: `signature.created`, `signature.verified`, `signature.failed` (ids/hashes, sem chave).
- Testes: PDF assinado verificável; certificado expirado; TSA indisponível; chave não vaza.

### S3 — Deliverability de e-mail (operação + código mínimo)

- Código: tabela `mail_suppressions` (endereço hasheado? e-mail necessário para supressão; reter com
  base legal e retenção), status `bounce|complaint|unsubscribe`, origem, timestamps; `Notifier`
  consulta antes de enviar; bounce/complaint via webhook do provedor (se houver) ou import manual.
- Metadados de envio (P9) sem corpo; retenção; painel de suporte mostra falhas agregadas.
- Operação: runbook `wiki/runbooks/email.md` com SPF (`-all`), DKIM (selector/rotação), DMARC
  (`p=none` → `quarantine` → `reject` com relatórios), Mailpit em dev, teste de alinhamento.
- Nenhum envio em massa; newsletter fora de escopo.
- Testes: supressão bloqueia; complaint; retenção; sem PII em log.

### S4 — CDN/borda: decisão medida

- Não implementar Multi-CDN agora. Medir: TTFB/LCP de origem (RUM/P4), cache hit, largura de banda,
  latência por região; comparar com orçamento; só então decidir contrato/ADR.
- Registrar a decisão no `kd` e no backlog (não reabrir sem medição).
- Se a decisão for “sim”, o desenho é ADR própria (cache keys, `Vary`, purge, TLS, CSP, IP real via
  `TrustProxies`) — fora desta fase.

### S5 — Fechamento

- Runbooks: SSO, ICP, e-mail, CDN/medição; alertas e rollback.
- Testes de indisponibilidade/rollback; `make check` 2× + `E2E=1` para o que tocar UI.
- Atualizar `INVENTARIO.md` (itens externos) e o backlog.

## 4. Fora de escopo

- 2FA/MFA, “lembrar-me”, recuperação de senha por e-mail (ADR-037 backlog).
- gov.br como único login (nunca; break-glass).
- Assinatura em massa/ETL de PDFs do legado.
- Multi-CDN, WAF gerenciado, bot management (medir antes).
- Provedor de e-mail específico; o produto usa SMTP/API configurável.

## 5. Fatias de sessão

| Sessão | Entrega | Prova | Depende |
|---|---|---|---|
| **P13.S1** | spike + runbook + decisão SSO/ICP | decisão registrada; nenhuma dependência nova sem licença | P3/P10 |
| **P13.S2** | gov.br SSO + vínculo + break-glass | fake OIDC; state/nonce; sem vínculo nega; login local ok | S1 |
| **P13.S3** | assinatura/verificação (se aprovada) | PDF verificável; TSA off; chave não vaza | S1 |
| **P13.S4** | supressão + runbook de e-mail | supressão bloqueia; DMARC documentado; sem PII | P9 |
| **P13.S5** | medição de CDN + decisão | números de origem; decisão no `kd` | P4 |
| **P13.S6** | docs, runbooks, 2× check | evidência no `kd` | S2–S5 |

## 6. Contratos e dados

- **SSO:** `cms_users.sso_subject` (nullable, unique quando presente), `sso_provider`; rotas
  `sso.govbr.redirect`/`callback`; settings `sso.govbr.*` (client id/secret cifrado).
- **ICP:** tabela `signature_certificates`/`signature_logs` (metadados), chave cifrada; service ou
  módulo `Infraestrutura/Assinatura`.
- **E-mail:** `mail_suppressions`, metadados de envio; runbook.
- **Eventos:** `core.sso_login`, `core.sso_link`, `signature.created`, `mail.suppressed`.

## 7. DoD

- [ ] Nenhuma integração externa é obrigatória para operar; break-glass documentado e testado.
- [ ] SSO vincula conta existente, nega não vinculado, não auto-provisiona, não vaza token.
- [ ] ICP só é declarado “válido” com TSA/OCSP; chave nunca em claro; verificação pública.
- [ ] E-mail com SPF/DKIM/DMARC documentados, supressão efetiva e sem corpo em log.
- [ ] CDN decidido por medição, não por preferência; decisão registrada.
- [ ] `make check` 2×; cobertura ≥90%; PHPStan max 0.

## Fechamento — ficha de revisão

> **Obrigatório antes de fechar:** criar `_to_revision/P13-integracoes-externas.md` e seguir
> `_to_revision/README.md` + `_to_revision/PROTOCOLO.md` (v2.0). A ficha não é gate de build; é a
> entrada da fila de revisão profunda.

- Cabeçalho: fase, `kd` épico/tasks/slices, âncoras (este arquivo, ADRs e código) e status
  `⬜ pendente` → `🟡 em revisão` → `✅ revisado` / `🔧 com correções`.
- Conteúdo: o que foi implementado, arquivos/superfícies a revisar, checklist D1–D14 aplicável,
  riscos e observações.
- Fechamento: preencher “Notas da revisão” com data/revisor/resultado e achados (`kd write
  --anchor`), atualizar a fila em `_to_revision/README.md` e `_to_revision/_inventario.md`.
- Achado com correção exige teste vermelho→verde; a fase só é `closed` no `kd` com a ficha
  registrada.

## 8. Riscos

| Risco | Mitigação |
|---|---|
| SSO bloquear o painel | login local break-glass + runbook + teste de indisponibilidade |
| Auto-provisionamento indevido | vínculo explícito; deny-by-default; auditoria |
| Assinatura “falsa” sem TSA | exigir TSA/OCSP; dizer o que é válido; teste |
| Chave privada vazar | cifra + acesso mínimo + nunca log; rotação/revogação |
| E-mail em spam | DNS/runbook; supressão; medir bounce/complaint |
| CDN sem medição | decisão medida; sem contrato antecipado |

## 9. Retomada

```bash
kd prime
kd ask "gov.br SSO ICP-Brasil assinatura e-mail deliverability CDN"
kd task list --ready
```

Ler: `wiki/backlog/govbr-sso.md`, `assinatura-digital-icp-brasil.md`, `email-deliverability.md`,
`cdn-borda-multicdn.md` → `wiki/adr/ADR-027` §9 → `src/core/Area/Cms/**` → `services/Notifications`
(P9) → `wiki/runbooks/`.

Referências irmãs (UX/desenho, não código): `../lotep/V2/Modules/Infraestrutura/CertificadoDigital/**`
e `../sucesu-cms/V2/Services/DigitalSignature/**` (fluxo PFX → assinatura → verificação);
`../lotep/V2/Modules/Infraestrutura/MailAudit/**` (histórico de envio). Rejeitar “válido” sem
TSA/OCSP, chave derivada de `APP_KEY`+IV e corpo de e-mail em log.
