nAIxus Docs
Comprendre

Architecture et sécurité du canal API

Explication - comment le canal API fonctionne, comment l'authentification et la signature fonctionnent, ce qu'elles protègent, et les limitations actuelles.

Cette page explique les décisions de conception du canal API de nAIxus - ce qu'il est, pourquoi il fonctionne ainsi, et quels sont ses compromis de sécurité actuels.


Déclencheur API entrant vs livraison webhook sortante

Ce canal est entrant uniquement. Votre système appelle nAIxus ; nAIxus n'appelle pas votre système.

ModèleDirectionQui initie
Canal API (celui-ci)EntrantVotre système → nAIxus
Webhook sortant (non implémenté)SortantnAIxus → votre système

La livraison sortante (callbacks, webhooks poussés vers votre point d'accès) n'est pas disponible dans cette version.


Credentials serveur vs credentials publics

Le type de credential contrôle qui peut appeler le canal et depuis où.

Les credentials serveur (nx_live_, nx_test_) sont destinés aux backends de confiance. Votre serveur détient la clé ; elle n'est jamais exposée aux utilisateurs finaux. La clé accorde l'accès au canal quelle que soit l'adresse IP ou l'origine de la requête.

Les credentials publics (nx_pub_) sont destinés aux environnements où le credential est inévitablement visible - JavaScript navigateur, applications mobiles natives. Une clé publique peut être intégrée en toute sécurité dans une page ou un binaire d'application, mais uniquement parce qu'elle est limitée en portée :

  • Elle ne peut appeler que le canal spécifique pour lequel elle a été émise.
  • Les requêtes des navigateurs doivent inclure un en-tête Origin correspondant à la liste des origines autorisées du canal.

Les credentials publics ne contournent pas l'exigence d'un flow lié et publié. Ils exécutent le même flow que les credentials serveur.


Ce que les origines autorisées font et ne font pas

Les origines autorisées constituent un mécanisme de réduction des abus, pas un mécanisme de protection des secrets.

Ce qu'elles font :

  • Exiger que les requêtes navigateur incluent un en-tête Origin correspondant à la liste configurée.
  • Empêcher qu'une clé nx_pub_ soit utilisée trivialement sur un site non autorisé (un navigateur incluera automatiquement Origin via CORS).

Ce qu'elles ne font pas :

  • Protéger la clé contre son extraction du code source navigateur ou d'un binaire d'application mobile.
  • Empêcher un attaquant motivé de faire des requêtes curl qui omettent entièrement l'en-tête Origin (les clés serveur doivent être utilisées pour les opérations sensibles).
  • Offrir la même protection qu'un proxy backend.

Pour les opérations sensibles - où l'opération doit être authentifiée en tant qu'utilisateur vérifié spécifique - utilisez un proxy backend avec une clé serveur.


Pourquoi les applications natives ne peuvent pas cacher les credentials intégrés

Un credential intégré dans un binaire d'application mobile peut être extrait par décompilation ou inspection du binaire. Il s'agit d'une contrainte fondamentale de la distribution de code sur des appareils non fiables. Options :

  1. Proxy backend (recommandé) : l'application mobile envoie des requêtes à votre propre API ; votre API ajoute la clé nx_live_ et appelle nAIxus. Les utilisateurs finaux ne voient jamais la clé.
  2. Clé publique avec allowed_origins: ["*"] : la clé est visible, mais le canal n'exécute qu'un seul flow lié. Convient lorsque le flow ne contient pas de logique sensible et que le risque d'abus d'API est acceptable.
  3. Tokens de courte durée (pas encore implémenté) : des tokens de session limiteraient l'accès plus étroitement. Non disponible dans cette version.

Ce que la signature HMAC protège

Lorsqu'un canal a require_signature = true, chaque requête doit inclure un en-tête X-Naixus-Signature dérivé du secret de signature.

La signature HMAC fournit :

  • Intégrité du corps : toute modification du corps de la requête - même un seul octet - change le digest et amène le serveur à rejeter la requête.
  • Preuve d'origine : seul un appelant qui possède le secret de signature peut produire un digest valide.
  • Protection contre le rejeu bornée : l'horodatage dans la signature signifie qu'une requête capturée ne peut pas être rejouée plus de 300 secondes plus tard.

Ce que la signature HMAC ne protège pas

  • Confidentialité du contenu : le corps de la requête n'est pas chiffré. Utilisez HTTPS (obligatoire) pour la sécurité du transport.
  • Prévention illimitée du rejeu : il n'existe pas actuellement de base de données de nonce. Une requête capturée avec un horodatage valide peut être rejouée dans la fenêtre de 300 secondes.
  • Contre un serveur compromis : si votre serveur est compromis, le secret de signature est exposé avec tout le reste.
  • Distribution d'applications natives : le secret de signature doit rester sur un backend de confiance. L'intégrer dans un binaire d'application mobile l'expose.

Fenêtre de rejeu par horodatage

Le serveur accepte les requêtes où l'horodatage t satisfait |maintenant − t| ≤ 300 secondes. Cela signifie :

  • Une requête interceptée peut être rejouée pendant jusqu'à 5 minutes.
  • Une requête datée dans le futur (décalage d'horloge de plus de 300 s en avance) est également rejetée.

La fenêtre de 300 secondes a été choisie pour tolérer la latence réseau et le décalage d'horloge raisonnables entre systèmes indépendants. Une base de données de nonce éliminerait complètement la fenêtre mais n'est pas implémentée dans cette version.


Exécution JSON vs exécution SSE

Les deux modes exécutent le même flow via le même use case.

L'exécution JSON (stream: false ou valeur par défaut du canal) attend que le flow se termine et retourne le résultat complet dans un objet de réponse. Utilisez-la pour les intégrations synchrones où vous avez besoin de la réponse finale.

L'exécution SSE (stream: true) ouvre une connexion persistante et diffuse la sortie incrémentale en utilisant le protocole Vercel AI SDK UI Message Stream. Le premier événement (data-run) porte les identifiants stables run_id et conversation_id. Les événements suivants livrent des deltas de texte. Utilisez-la pour les mises à jour d'interface en temps réel.

Le protocole de streaming est spécifiquement l'AI SDK UI Message Stream (text-start, text-delta, text-end, finish, error). Ce n'est pas le format de streaming OpenAI.


Création de conversation vs reprise

Chaque requête démarre soit une nouvelle conversation, soit reprend une existante :

  • Nouvelle conversation : conversation_id est absent. Le serveur crée une nouvelle session et retourne son identifiant dans la réponse.
  • Reprise : conversation_id est présent. Le flow s'exécute dans la session existante, avec accès au contexte précédent.

Le conversation_id n'est pas simplement une balise de corrélation. C'est l'identifiant de la session avec état que le flow utilise pour maintenir le contexte (historique de conversation, variables, fenêtre de contexte).

La reprise est validée : la conversation doit appartenir au même tenant et au même canal que la requête. La reprise inter-canal retourne un 404 non-énumératif pour éviter de révéler l'existence de conversations sur d'autres canaux.


Comportement des environnements

CléEnvironnement du canalEffet
nx_live_prodExécute la version du flow publiée
nx_test_dev ou stagingExécute la version du flow appropriée au développement
nx_pub_QuelconqueDépend de l'environnement du canal

Une clé nx_live_ utilisée sur un canal d'environnement dev retourne environment_mismatch (403). Cela évite que le trafic de test atteigne accidentellement les flows de production.


Pourquoi la rotation de la clé d'API et du secret de signature sont indépendantes

La rotation de la clé d'API invalide l'ancienne clé - toute requête l'utilisant échouera avec invalid_api_key. La rotation du secret de signature invalide l'ancien secret - toute requête utilisant l'ancienne signature échouera avec invalid_signature.

Il s'agit de credentials distincts avec des objectifs distincts :

  • La clé d'API authentifie l'appelant et autorise le canal.
  • Le secret de signature vérifie l'intégrité du corps et la preuve d'origine de la requête.

Vous pouvez renouveler l'un ou l'autre indépendamment. Le renouvellement simultané des deux nécessite de déployer deux nouvelles valeurs, mais le canal continue de fonctionner tant que vous déployez les nouvelles valeurs avant que les anciennes cessent d'être acceptées (ce qui est immédiat après la rotation pour les deux).

On this page