[Conectores mock determinísticos, sem tráfego de saída live]

Ambiente sandbox

Testa integrações contra conectores mock determinísticos sem tráfego de saída para o parceiro em produção. Emite um token sandbox (`aud=sandbox`) em `auth.knogin.com`, chama a mesma superfície v2026.4 contra `https://sandbox-api.knogin.com` e recebe respostas idênticas byte a byte em cada replay do mesmo payload.

Ambiente sandbox

Começar

O acesso à sandbox é feito pelo fluxo padrão de admin de plataforma. Com o scope `argus:platform:admin` num bearer token, chama `POST /v1/platform/apps/{client_id}/sandbox-token` para emitir um JWT sandbox para a app que estás a integrar. A resposta inclui o host da sandbox (`https://sandbox-api.knogin.com`) e a lista de scenarios fixados ao token. Aponta o teu SDK parceiro existente para o host da sandbox, troca o token live pelo de sandbox e toda a superfície v2026.4 é encaminhada para mocks determinísticos de forma transparente.

Emissão de tokens

`POST /v1/platform/apps/{client_id}/sandbox-token` aceita um array `scenarios` opcional (fixa a sandbox em dados pré-definidos, p. ex. `["wallet.high-risk", "entity.sanctioned"]`) e um `ttl_seconds` opcional (limitado ao intervalo inclusivo [60, 86400]; valores fora do intervalo são normalizados antes da assinatura). A resposta inclui o token sandbox assinado, o seu `expires_at`, `audience: "sandbox"`, o conjunto de scopes embutido no token, o host da sandbox e os scenarios fixados. O token sandbox reutiliza o conjunto de chaves RS256 existente do auth_service; o cabeçalho `kid` aponta para o mesmo JWKS usado por `/oauth/token`, pelo que os SDKs parceiros já validam tokens sandbox sem alterações.

Catálogo de scenarios

Cinco scenarios são entregues no primeiro release. Fixa um ou mais no campo `scenarios` ao emitir o token para que a sandbox devolva os mesmos dados pré-definidos em cada replay; omite o campo para a rotação mista por defeito.

Dupla barreira

Argus impõe no-leak em ambas as direções. O host da sandbox (`sandbox-api.knogin.com`) recusa tokens live: o middleware de routing verifica a claim `aud` do JWT e rejeita com 403 quando `aud != "sandbox"`. Os conectores live recusam tokens sandbox: cada factory `<provider>_client.py` live verifica `request.state.sandbox` e lança 403 se o pedido estiver em scope sandbox. Os testes cobrem ambas as direções, pelo que um token live não pode ler dados mock por acidente e um token sandbox não pode atingir os sistemas live do parceiro.

Determinismo

As respostas da sandbox são determinísticas. O mesmo payload, disparado duas vezes com os mesmos scenarios fixados, devolve uma resposta idêntica byte a byte. Isto é intencional: os pipelines de CI parceiros podem fazer snapshot das respostas sandbox e asserir contra elas em cada build sem retry-flake. As respostas sandbox levam ainda `X-Argus-Sandbox: true` para que ferramentas de debug parceiras vejam de imediato que a resposta é sintética, mantendo o `X-Argus-Trace-ID` padrão de G2 para correlação ponta a ponta com os teus próprios logs.

Faturação e quota

As chamadas à sandbox não consomem a tua quota de conectores parceiros live e não são faturáveis. Nunca tocam em fornecedores OSINT ou financeiros reais, nunca atingem datasets sensíveis e nunca entram nos orçamentos de rate-limit que negociaste para produção. Os registos de auditoria de tráfego sandbox são marcados com `secrecy_level=sandbox` para que operadores possam filtrar tráfego sandbox dos relatórios de conformidade. Usa a sandbox livremente para testes de integração, ensaios de onboarding parceiro, gravações de demo e CI exploratória; os orçamentos de produção ficam intactos.

Migração para produção

Quando a tua integração estiver pronta, troca a base URL de `https://sandbox-api.knogin.com` para `https://api.knogin.com` e volta a emitir um token live pelo fluxo padrão `POST /v1/oauth/token` com os teus scopes de produção. A forma na wire, os cabeçalhos, os status codes e a propagação de trace são idênticos entre sandbox e live, pelo que um cliente validado em sandbox não precisa de alterações de comportamento. A única diferença em runtime é a claim `aud` do JWT e o host para o qual apontas.

Catálogo de scenarios

ID de scenarioEtiquetaDescrição
wallet.high-riskWallet de alto riscoDevolve enriquecimento que indica hits de sanções, interação com mixer e transferências rápidas de elevado volume.
wallet.cleanWallet limpaDevolve enriquecimento que indica atividade de baixo risco e sem hits de sanções.
entity.sanctionedEntidade sancionadaDevolve enriquecimento OSINT com correspondências em listas OFAC, UN e UE.
incident.escalatingIncidente em escaladaDevolve sinais de dispatch e ePCR consistentes com uma situação que está a piorar.
device.offlineDispositivo médico offlineDevolve telemetria que indica last-seen há N horas com estado de bateria desatualizado.

Emitir um token sandbox

# Mint a sandbox token (requires argus:platform:admin)
curl -X POST https://auth.knogin.com/v1/platform/apps/app_123/sandbox-token \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scenarios": ["wallet.high-risk", "entity.sanctioned"],
    "ttl_seconds": 3600
  }'

# 200 OK
# {
#   "token": "<sandbox-jwt>",
#   "expires_at": "2026-05-08T13:00:00Z",
#   "audience": "sandbox",
#   "scopes": [
#     "argus:profiles:read",
#     "argus:profiles:write",
#     "argus:jobs:read",
#     "argus:jobs:write"
#   ],
#   "sandbox_host": "https://sandbox-api.knogin.com",
#   "scenarios": ["wallet.high-risk", "entity.sanctioned"]
# }

Listar scenarios sandbox

# Discover the scenario catalogue (sandbox host only)
curl https://sandbox-api.knogin.com/v1/sandbox/scenarios \
  -H "Authorization: Bearer $SANDBOX_TOKEN"

# 200 OK
# {
#   "scenarios": [
#     { "id": "wallet.high-risk", "label": "High-risk wallet", "description": "..." },
#     { "id": "wallet.clean", "label": "Clean wallet", "description": "..." },
#     { "id": "entity.sanctioned", "label": "Sanctioned entity", "description": "..." },
#     { "id": "incident.escalating", "label": "Escalating incident", "description": "..." },
#     { "id": "device.offline", "label": "Offline medical device", "description": "..." }
#   ]
# }

# A live token against the sandbox host fails closed:
# HTTP/1.1 403 Forbidden
# X-Argus-Sandbox-Reason: live-token-on-sandbox-host

Chamar a superfície sandbox

# Same v2026.4 surface, sandbox host, sandbox token.
# Two replays of the same payload return a byte-equal response.
curl -X POST https://sandbox-api.knogin.com/v1/jobs \
  -H "Authorization: Bearer $SANDBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "intelligence.enrich.bulk",
    "payload": { "profile_ids": ["p1", "p2"] }
  }'

# Response carries:
#   X-Argus-Sandbox: true
#   X-Argus-Trace-ID: <32-hex>   (G2 trace propagation, unchanged)

# When ready for production, swap the base URL and re-mint a live token:
curl -X POST https://auth.knogin.com/v1/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=app_123&client_secret=<secret>&scope=argus:jobs:write"

curl -X POST https://api.knogin.com/v1/jobs \
  -H "Authorization: Bearer $LIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "kind": "intelligence.enrich.bulk", "payload": { "profile_ids": ["p1"] } }'

Pronto para ligar a tua integração através da sandbox?

Abre a referência API para o contrato público ou contacta a Knogin se precisares de uma fixture de scenario à medida para o teu fluxo parceiro.