[Connecteurs mock déterministes, sans trafic sortant live]

Environnement sandbox

Testez les intégrations contre des connecteurs mock déterministes sans aucun trafic sortant vers le partenaire en production. Émettez un jeton sandbox (`aud=sandbox`) sur `auth.knogin.com`, appelez la même surface v2026.4 sur `https://sandbox-api.knogin.com` et recevez des réponses identiques au bit près à chaque rejeu du même payload.

Environnement sandbox

Démarrage

L’accès au sandbox passe par le flux admin de plateforme standard. Avec le scope `argus:platform:admin` sur un bearer token, appelez `POST /v1/platform/apps/{client_id}/sandbox-token` pour émettre un JWT sandbox pour l’app que vous câblez. La réponse contient le host sandbox (`https://sandbox-api.knogin.com`) et la liste des scenarios épinglés au jeton. Pointez votre SDK partenaire existant vers le host sandbox, remplacez le jeton live par le jeton sandbox et toute la surface v2026.4 est routée vers les mocks déterministes de manière transparente.

Émission de jetons

`POST /v1/platform/apps/{client_id}/sandbox-token` accepte un tableau `scenarios` optionnel (épingle le sandbox sur des données prédéfinies, p. ex. `["wallet.high-risk", "entity.sanctioned"]`) et un `ttl_seconds` optionnel (borné à l’intervalle inclusif [60, 86400]; les valeurs hors plage sont normalisées avant signature). La réponse inclut le jeton sandbox signé, son `expires_at`, `audience: "sandbox"`, l’ensemble des scopes embarqués dans le jeton, le host sandbox et les scenarios épinglés. Le jeton sandbox réutilise le jeu de clés RS256 existant d’auth_service; l’en-tête `kid` pointe vers le même JWKS que `/oauth/token`, donc les SDK partenaires valident déjà les jetons sandbox sans modification.

Catalogue de scenarios

Cinq scenarios sont livrés dans la première version. Épinglez-en un ou plusieurs dans le champ `scenarios` à l’émission du jeton pour que le sandbox renvoie les mêmes données prédéfinies à chaque rejeu; omettez le champ pour la rotation mixte par défaut.

Double barrière

Argus impose le no-leak dans les deux sens. Le host sandbox (`sandbox-api.knogin.com`) refuse les jetons live: le middleware de routage vérifie le claim `aud` du JWT et rejette en 403 lorsque `aud != "sandbox"`. Les connecteurs live refusent les jetons sandbox: chaque factory `<provider>_client.py` live vérifie `request.state.sandbox` et lève une 403 si la requête est en scope sandbox. Les tests couvrent les deux sens, de sorte qu’un jeton live ne peut pas lire de données mock par accident et qu’un jeton sandbox ne peut pas atteindre les systèmes live du partenaire.

Déterminisme

Les réponses du sandbox sont déterministes. Le même payload, tiré deux fois avec les mêmes scenarios épinglés, renvoie une réponse identique au bit près. C’est volontaire: les pipelines de CI partenaires peuvent faire un snapshot des réponses sandbox et asserter dessus à chaque build sans flake de retry. Les réponses sandbox portent en outre `X-Argus-Sandbox: true` pour que les outils de debug partenaires voient d’un coup d’œil que la réponse est synthétique, tout en conservant le `X-Argus-Trace-ID` standard de G2 pour la corrélation end-to-end avec vos propres journaux.

Facturation et quota

Les appels sandbox ne consomment pas votre quota live de connecteurs partenaires et ne sont pas facturés. Ils ne touchent jamais aux fournisseurs OSINT ou financiers réels, n’atteignent jamais de jeux de données sensibles et n’entrent jamais dans les budgets de rate-limit que vous avez négociés pour la production. Les entrées d’audit du trafic sandbox sont taggées `secrecy_level=sandbox` pour que les opérateurs puissent filtrer le trafic sandbox des rapports de conformité. Utilisez le sandbox largement pour les tests d’intégration, les répétitions d’onboarding partenaire, les enregistrements de démo et la CI exploratoire; les budgets de production restent intacts.

Migration vers la production

Quand votre intégration est prête, basculez la base URL de `https://sandbox-api.knogin.com` vers `https://api.knogin.com` et réémettez un jeton live via le flux standard `POST /v1/oauth/token` avec vos scopes de production. La forme wire, les en-têtes, les codes de statut et la propagation de trace sont identiques entre sandbox et live, donc un client validé en sandbox ne nécessite aucun changement comportemental. La seule différence à l’exécution est le claim `aud` du JWT et le host vers lequel vous pointez.

Catalogue de scenarios

ID de scenarioLibelléDescription
wallet.high-riskWallet à haut risqueRenvoie un enrichissement signalant des hits de sanctions, une interaction avec mixer et des transferts rapides à fort volume.
wallet.cleanWallet propreRenvoie un enrichissement indiquant une activité à faible risque et aucun hit de sanctions.
entity.sanctionedEntité sanctionnéeRenvoie un enrichissement OSINT avec des correspondances OFAC, UN et UE.
incident.escalatingIncident en escaladeRenvoie des signaux dispatch et ePCR cohérents avec une situation qui se dégrade.
device.offlineDispositif médical hors ligneRenvoie une télémétrie indiquant un last-seen il y a N heures avec un état de batterie obsolète.

Émettre un jeton 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"]
# }

Lister les 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

Appeler la surface 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"] } }'

Prêt à câbler votre intégration via le sandbox ?

Ouvrez la référence API pour le contrat public, ou contactez Knogin si vous avez besoin d’une fixture de scenario sur mesure pour votre flux partenaire.