Integração com API do DUT — terceiro pilar da telemetria do TLSStress.Art¶
Leia no seu idioma: English · Português · Español
Status do escopo (pós-congelamento de escopo 2026-05-10) — Ver ARCHITECTURE.md para os 37 MÓDULOs canônicos + 7 Test Kinds + arquitetura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cobrem adições pós-Freeze. Este documento descreve como o TLSStress.Art conversa com as APIs REST dos elementos de rede do laboratório — Cisco FTD (NGFW), Cisco Nexus 9000 (switch), Palo Alto, Fortinet — para enriquecer o Dashboard, o Grafana e o Test Run Report com dados que somente a API consegue fornecer.
É o terceiro pilar de telemetria deste produto, juntando-se ao SNMP (métricas numéricas) e ao syslog (correlação de eventos):
| Fonte | Ponto forte | Limitação |
|---|---|---|
| SNMP | Contadores padronizados (bytes de interface, CPU, memória) | Genérico; objetos vendor-specific pouco modelados; sem config |
| Syslog | Eventos em tempo real com contexto completo | Apenas reativo; sem estado atual; sem inventário |
| API (este doc) | Config viva, versão, políticas aplicadas, status de deploy, LLDP/CDP, estado de HA | Vendor-specific; exige autenticação; precisa considerar rate-limit |
As três camadas combinadas produzem o nível de completude forense que o Test Run Report exige.
O que a integração de API destrava¶
| Capacidade | Sem API | Com API |
|---|---|---|
| Confirmar modelo + número de série do NGFW | SNMP entPhysicalSerialNum (genérico, às vezes errado em virtual appliances) |
Cisco FTD /operational/sysinfo retorna modelo preciso + revisão de hardware |
| Confirmar que a política de decrypt está habilitada e quais regras se aplicam | ❌ não visível externamente | ✅ Cisco FTD /policy/sslpolicies lista cada regra, ação, interfaces aplicadas |
| Confirmar status de deploy antes de iniciar uma execução | ❌ | ✅ Cisco FTD /operational/deploy — recusa iniciar se houver mudanças pendentes na fila |
| Confirmar que a config NTP do device bate com a expectativa do laboratório | ❌ | ✅ Cisco FTD /devicesettings/default/ntp + Cisco Nexus sys/time |
| Auto-descoberta de topologia do laboratório via LLDP/CDP | ❌ | ✅ Cisco Nexus DME sys/lldp/inst + sys/cdp/inst |
| Detectar standby de HA + pular escritas | ❌ | ✅ Cisco FTD HA endpoint + detecção de 405 |
| Capturar inventário de chassis + lista de módulos | parcial | ✅ Cisco Nexus sys/ch?rsp-subtree=full retorna fans, PSUs, line cards com S/Ns |
| Anexo com chain-of-custody criptográfica | ❌ | ✅ Cada resposta de API armazenada com SHA-256 em dut_api_snapshots |
Arquitetura¶
OOBI mgmt network
│
┌─────────────────┐ │
│ Cisco FTD │ ◄────HTTPS Bearer ┤
│ (FDM API v6) │ │
└─────────────────┘ │
│
┌─────────────────┐ │
│ Cisco Nexus 9k │ ◄────APIC-cookie ─┤
│ (NX-API DME) │ │
└─────────────────┘ │
│ Server-side fetch
┌─────────────────┐ │ inside Dashboard pod
│ Cisco UCS CIMC │ ◄────Basic Auth ──┤ (poll every N min OR
│ (Redfish) │ │ on-demand at run start)
└─────────────────┘ │
│
┌─────────────────┐ │
│ Fortinet │ ◄────Bearer ──────┤
│ (FortiOS REST) │ │
└─────────────────┘ ▼
┌──────────────────────┐
┌─────────────────┐ │ DUT API Collector │
│ Palo Alto │ ◄────XML ────▶│ (Next.js worker) │
│ (PAN-OS) v6.x │ │ │
└─────────────────┘ │ Adapter pattern: │
│ - cisco-ftd.ts │
│ - cisco-nexus.ts │
│ - cisco-ucs-cimc.ts │
│ - fortinet-fortigate.ts│
│ - (future) palo-alto │
└──────────┬───────────┘
│
┌─────────────────────▼────────────────────┐
│ Postgres │
│ dut_api_devices (creds AES-256-GCM) │
│ dut_api_snapshots (JSONB + SHA-256) │
└─────────────────────┬────────────────────┘
│
┌───────────────────────────────┼─────────────────────────┐
▼ ▼ ▼
┌──────────────────┐ ┌───────────────────────┐ ┌─────────────────┐
│ Grafana │ │ Test Run Report │ │ TLS Decrypt │
│ "DUT Live State" │ │ Phase 3 Annex B (Nexus)│ │ Probe (cross- │
│ dashboard │ │ Phase 3 Annex C (NGFW) │ │ verifies decryp │
│ │ │ + per-snapshot SHA-256│ │ policy) │
└──────────────────┘ └───────────────────────┘ └─────────────────┘
Resumo de referência por fabricante¶
Cisco FTD (gerenciado pelo FDM) — cisco-ftd¶
| Aspecto | Valor |
|---|---|
| Base URL | https://<ftd-mgmt>/api/fdm/v6/ |
| Auth | OAuth2 password grant → Bearer token |
| Token endpoint | POST /api/fdm/v6/fdm/token |
| TTL do token | tipicamente 30 min |
| Refresh em | resposta 401 |
| Detalhe de HA | Unidade standby retorna 405 em certas leituras |
| Método de update | Apenas PUT — objeto completo obrigatório (sem PATCH) |
| Habilitar no device | nada — a FDM API vem ligada por padrão |
Endpoints que consumimos (somente leitura):
- GET /operational/sysinfo → modelo, versão, hostname, uptime
- GET /devicesettings/default/ntp → servidores NTP configurados + estado
- GET /operational/interfaces → estado live de interfaces
- GET /policy/sslpolicies → regras da política de decrypt SSL/TLS
- GET /operational/deploy → pending/deploying/deployed
- GET /policy/intrusionpolicies → política IPS aplicada
- GET /devices/default/ha → estado do par HA
Referência: https://developer.cisco.com/docs/ftd-api-reference/latest/
Cisco Nexus 9000 (NX-API REST DME) — cisco-nexus¶
| Aspecto | Valor |
|---|---|
| Base URL | https://<nexus-mgmt>/api/ |
| Auth | POST /api/aaaLogin.json → Set-Cookie: APIC-cookie |
| TTL do cookie | ~10 min (re-login em 401/403) |
| Object Model | DME — Distinguished Names como sys, sys/ch, sys/intf, sys/lldp/inst |
| Formato da resposta | {"totalCount":"N","imdata":[{"className":{"attributes":{...}}}]} |
| Habilitar no device | feature nxapi + nxapi https port 443 |
| VRF binding | nxapi use-vrf management (recomendado) |
Endpoints que consumimos (somente leitura):
- GET /api/node/mo/sys/ch.json?rsp-subtree=full → chassis + módulos + S/Ns
- GET /api/node/mo/sys/time.json?rsp-subtree=full → config NTP + estado do clock
- GET /api/node/mo/sys/intf.json?rsp-subtree=full → config de interfaces
- GET /api/node/mo/sys/lldp/inst.json?query-target=subtree&target-subtree-class=lldpAdjEp → vizinhos LLDP
- GET /api/node/mo/sys/cdp/inst.json?query-target=subtree&target-subtree-class=cdpAdjEp → vizinhos CDP
- GET /api/node/mo/sys/vpc.json?rsp-subtree=full → estado do peer vPC (equivalente a HA)
Referência: https://developer.cisco.com/docs/nx-os-n3k-n9k-api-ref/
Cisco UCS C-Series CIMC (Redfish) — cisco-ucs-cimc¶
| Aspecto | Valor |
|---|---|
| Base URL | https://<cimc-mgmt>/redfish/v1/ |
| Auth | HTTP Basic (admin / password). Sem TTL de token — credenciais enviadas a cada requisição |
| Habilitar no device | Redfish está ativo por padrão no CIMC 4.0+; verifique em Admin → Communication Services |
| Caveat de HA | Nenhum (CIMC é single-controller) |
| Método de update | PATCH em /redfish/v1/Systems/{id} (não usamos; somos read-only) |
Endpoints que acessamos (read-only):
- GET /redfish/v1/Systems/<id> → modelo do servidor, versão BIOS, serial, asset tag
- GET /redfish/v1/Chassis/<id> → estado de power do chassis, indicadores, sku
- GET /redfish/v1/Chassis/<id>/Power → status de PSU, wattagem total, fontes
- GET /redfish/v1/Chassis/<id>/Thermal → fans, temperatura inlet/outlet, breaches de threshold
- GET /redfish/v1/Managers/<id> → versão de firmware do CIMC, saúde do serviço
- GET /redfish/v1/Systems/<id>/Memory → inventário de DIMMs + saúde (por slot)
- GET /redfish/v1/Systems/<id>/Processors → modelos de CPU + contagem de cores + saúde
Referência: https://www.dmtf.org/standards/redfish (padrão Redfish da DMTF, implementação Cisco CIMC).
Fortinet FortiGate (FortiOS REST v2) — fortinet-fortigate¶
| Aspecto | Valor |
|---|---|
| Base URL | https://<fgt-mgmt>/api/v2/ |
| Auth | Token de API (Bearer). Token gerado por admin em System → Administrators → REST API Admin. Sem TTL — token é long-lived |
| Rotação de token | Manual (operador regenera token na GUI; depois atualiza na nossa admin UI) |
| Caveat de HA | Unidade ativa serve a API; standby retorna redirect — adapter segue o redirect transparentemente |
| Método de update | PUT em /cmdb/<path>, mas somos read-only |
Endpoints que acessamos (read-only):
- GET /api/v2/monitor/system/status → hostname, versão, serial, uptime
- GET /api/v2/monitor/system/interface → estado e contadores de interfaces
- GET /api/v2/cmdb/system/ntp → servidores NTP configurados
- GET /api/v2/cmdb/firewall/ssl-ssh-profile → perfis de inspeção SSL
- GET /api/v2/cmdb/firewall/policy → tabela de policies de firewall (regras relevantes para decryption)
- GET /api/v2/monitor/system/ha-status → estado do cluster HA, primário/secundário
Referência: https://docs.fortinet.com/document/forticonverter/fortios/restapi/
Palo Alto (PAN-OS XML API) — planejado v6.x¶
Backlog. Sem scaffold de adapter ainda. Quando implementado, auth será geração de API key via /api/?type=keygen&user=...&password=.... Endpoints de leitura seguem o padrão ?type=op&cmd=<show...>.
Modelo de dados¶
dut_api_devices (uma linha por device registrado)¶
| Coluna | Propósito |
|---|---|
hostname |
Identificador único no laboratório |
vendor |
cisco-ftd / cisco-nexus / cisco-ucs-cimc / fortinet-fortigate / palo-alto-panos (planned) |
device_role |
ngfw / switch / futuro |
base_url |
https://10.0.0.1 |
username |
Conta de API |
password_enc |
Ciphertext AES-256-GCM (BYTEA) — veja Encryption |
tls_verify_mode |
strict (default) / self-signed (pin do primeiro cert) / insecure |
pinned_cert_sha256 |
Definido na primeira conexão quando tls_verify_mode=self-signed |
poll_interval_seconds |
Default 300 (5 min); mínimo 30 |
enabled |
Liga/desliga sem deletar a linha |
last_poll_at / last_poll_status / last_poll_error |
Status live exibido na UI admin |
notes |
Notas livres do operador |
dut_api_snapshots (histórico append-only)¶
Toda chamada de API bem-sucedida (ou até falhada) escreve uma linha. Cada linha é o payload JSON completo com SHA-256 da forma canônica para chain-of-custody forense.
| Coluna | Propósito |
|---|---|
device_id / device_hostname / vendor |
Desnormalizado para queries rápidas |
endpoint_path |
Path vendor-specific (ex.: /api/fdm/v6/operational/sysinfo) |
endpoint_label |
Label vendor-agnostic — system_info, ntp_config, lldp_neighbors, etc. |
http_status |
Status da resposta da API |
payload_json |
JSON completo do fabricante (coluna JSONB) |
payload_sha256 |
digest hex, citado nos anexos do Test Run Report |
collector_version |
Versão do TLSStress.Art que puxou o snapshot |
test_run_execution_id |
NULL para polls de background; preenchido quando o snapshot foi vinculado a uma execução específica |
Valores vendor-agnostic de endpoint_label:
system_info, ntp_config, interfaces, lldp_neighbors, cdp_neighbors, decrypt_policy, deploy_status, ips_policy, qos_state, mac_table, routing_table, ha_status, license_state, config_running.
Isso permite ao Dashboard escrever queries como "me dê a config NTP mais recente de qualquer NGFW registrado, independente do fabricante" sem branching por fabricante.
Criptografia de credenciais¶
Credenciais do DUT são armazenadas criptografadas em AES-256-GCM na coluna BYTEA do Postgres. A chave de criptografia é a env var DUT_CRED_ENC_KEY, provisionada via Secret padrão do K8s.
Requisitos da chave:
- 32 bytes
- Fornecida como 64 hex chars OU codificação base64
- Gerar uma vez com node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
- Armazenar em K8s Secret, montar como env var no pod do dashboard
Formato de criptografia: IV (12 bytes) || ciphertext || auth tag (16 bytes) concatenados como um único valor BYTEA. O helper decryptPassword() separa e verifica a tag GCM — corrupção ou chave errada lança erro.
Rotação de chave: re-criptografar cada linha sob a nova chave. Helper de migration para isso está planejado.
Fluxo do operador¶
Habilitar APIs nos devices¶
Cisco FTD — já vem ligada por padrão. Confirme com:
show api-server-info
Cisco Nexus 9000:
configure terminal
feature nxapi
nxapi https port 443
nxapi use-vrf management
end
write memory
show nxapi
Configurar a chave de criptografia (uma única vez)¶
# Generate
KEY=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")
# Provision via K8s Secret
kubectl create secret generic tlsstress-dut-cred \
--from-literal=DUT_CRED_ENC_KEY="$KEY" \
-n web-agents
# Reference in the dashboard Deployment env block:
# env:
# - name: DUT_CRED_ENC_KEY
# valueFrom:
# secretKeyRef:
# name: tlsstress-dut-cred
# key: DUT_CRED_ENC_KEY
Registrar um device¶
(O PR de follow-up entrega a UI admin. Por enquanto, devices são registrados via endpoint de API ou diretamente no banco.)
curl -X POST "https://dashboard/api/admin/dut/devices" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "content-type: application/json" \
-d '{
"hostname": "ftd-1.lab.example.com",
"vendor": "cisco-ftd",
"deviceRole": "ngfw",
"baseUrl": "https://10.10.10.1",
"username": "admin",
"password": "<plaintext — will be encrypted server-side>",
"tlsVerifyMode": "self-signed",
"pollIntervalSeconds": 300,
"notes": "Cisco FTD 7.4 on FPR1010 — primary in HA pair"
}'
Testar a conexão¶
curl -X POST "https://dashboard/api/admin/dut/devices/<id>/test" \
-H "Authorization: Bearer $ADMIN_TOKEN"
# expect: {"ok": true, "detail": "auth OK; CPU monitor reachable in 142ms", "latencyMs": 142}
Disparar um snapshot manualmente¶
curl -X POST "https://dashboard/api/admin/dut/devices/<id>/snapshot" \
-H "Authorization: Bearer $ADMIN_TOKEN"
# returns the IDs of the snapshot rows just written
Polling em background¶
Uma vez habilitado, o worker de polling do dashboard itera pelos devices registrados no poll_interval_seconds configurado, executa todos os métodos collect* suportados e grava snapshots. A implementação do polling worker entra no PR-B (follow-up).
Vinculando snapshots a uma execução¶
Quando uma execução de Test Plan inicia, a engine dispara um snapshot imediato de cada device registrado com test_run_execution_id preenchido. Esse snapshot vira o "estado do DUT no início" da execução. No fim da execução, outro snapshot estabelece o "estado do DUT no fim". Ambos são referenciados no Test Run Report.
Modelo de segurança¶
O que a integração FAZ¶
- Armazena credenciais do DUT criptografadas at rest (AES-256-GCM)
- Usa HTTPS para cada chamada ao device
- Suporta cert-pinning para devices self-signed
- Loga cada snapshot em tabela append-only com SHA-256
- Audit-log de cada registro de device / mudança de credencial
O que a integração NÃO faz¶
- NÃO escreve no device por padrão — apenas métodos de adapter read-only. Métodos de escrita futuros (ex. configurar servidor NTP via API) serão fluxos explícitos com confirmação do operador e auditoria separada
- NÃO faz cache de credenciais em texto plano além da duração de uma chamada de API
- NÃO suporta fluxo OAuth client_credentials no FTD (só password grant) — se sua política de segurança exige client_credentials, abra uma issue
Threat model¶
| Ameaça | Mitigação |
|---|---|
| Vazamento do banco expõe credenciais | AES-256-GCM com chave em K8s Secret — atacante precisa também obter DUT_CRED_ENC_KEY |
| MITM no caminho adapter↔device | Verificação TLS (strict default); modo insecure exige opt-in explícito do operador e fica registrado em tls_verify_mode |
| Pod do dashboard comprometido abusa do acesso à API | Adapter é read-only por padrão; métodos de escrita futuros exigirão re-auth admin nova |
| Replay de respostas antigas da API | payload_sha256 + timestamp collected_at; mismatch detectável por quem tiver tanto o snapshot quanto um fetch contemporâneo do device |
| Erro de digitação do operador registra device errado | Botão "Test connection" valida auth + reachability antes de salvar |
Considerações de performance + rate-limit¶
Intervalo de poll padrão é 5 minutos por device. Observação empírica:
- Cisco FTD: coletar todos os 7 endpoints de leitura leva ~3-8 segundos no total (token em cache, chamadas sequenciais)
- Cisco Nexus 9000: coletar todos os 6 endpoints leva ~2-5 segundos (cookie em cache)
- Nenhum dos fabricantes documenta números de rate-limit; ambos parecem aguentar 1 chamada/segundo confortavelmente em leituras
Se você estiver rodando múltiplos devices, o loop de poll do worker é sequencial por device (não paralelo) para ser educado. Tempo total de ciclo = soma das durações por device.
Trabalho futuro — operações de escrita¶
Uma vez estável a fundação de leitura, métodos de escrita se tornam possíveis:
- Configurar servidor NTP no Cisco FTD:
PUT /api/fdm/v6/devicesettings/default/ntp/{objId}(objeto completo) +POST /api/fdm/v6/operational/deploypara commit - Resetar contadores de interface no Cisco Nexus:
POSTMO com actionclear - Alternar estado da política de decrypt para testes A/B durante uma execução
- Aplicar política QoS específica do test-bed no Nexus pré-execução, reverter pós-execução
Cada escrita exigirá: 1. Re-auth admin no momento do request 2. Confirmação explícita do operador na UI ("prestes a mudar fonte NTP do NGFW — prosseguir?") 3. Entrada de audit log com snapshots before/after 4. Rollback automático se a leitura pós-escrita confirmar divergência da intenção
Fora do escopo deste PR; rastreado como PR-C no roadmap de integração de API.
What ships in this PR¶
Este PR é a fundação: - Tabelas do banco + schema Drizzle - Helpers de criptografia de credenciais AES-256-GCM - Interface de adapter + catálogo ENDPOINT_LABELS - Adapter Cisco FTD funcional com 7 endpoints de leitura - Adapter Cisco Nexus funcional com 6 endpoints de leitura (cobre descoberta LLDP/CDP) - Esta documentação
What ships in PR-B (follow-up):
- UI admin para registrar devices
- Polling worker (Kubernetes CronJob OU Next.js server interval)
- Endpoints de API /api/admin/dut/devices/* + /api/admin/dut/snapshots/*
- Dashboard Grafana "TLSStress.Art — DUT Live State"
- Integração na execução do Test Plan (snapshot no início + fim da execução)
What ships in PR-C (futuro): - Adapters Palo Alto + Fortinet - Test Run Report Phase 3 Annex B/C ligado a esses snapshots - Operações de escrita (set NTP, toggle decrypt-policy) com fluxo de confirmação do operador
Relacionados¶
SYSLOG_OPERATIONS.pt-BR.md— segundo pilar (eventos)MONITORING_TEST_VALIDITY.pt-BR.md— framework do primeiro pilar (métricas)TLS_DECRYPT_MODE_VERIFICATION.pt-BR.md— probe independente de decrypt-active; com a API o cross-check vira "probe diz decrypt active E/policy/sslpoliciesmostra regras habilitadas"TIME_SYNC.pt-BR.md— sem clocks precisos os timestamps dos snapshots ficam enganososUSAGE_POLICY.pt-BR.md— restrições de licença se aplicam aos dados de API coletados aqui
Referências¶
- Cisco FTD REST API reference — https://developer.cisco.com/docs/ftd-api-reference/latest/
- Cisco FTD API intro — https://www.cisco.com/c/en/us/td/docs/security/firepower/ftd-api/guide/ftd-rest-api/ftd-rest-api-intro.html
- Cisco Nexus 9000 NX-API SDK — https://developer.cisco.com/docs/nx-os-n3k-n9k-api-ref/
- Cisco Nexus 9000 Programmability Guide — https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus9000/sw/93x/progammability/guide/b-cisco-nexus-9000-series-nx-os-programmability-guide-93x/