nAIxus Docs
Guides pratiques

Signer les requêtes avec HMAC

Guide pratique - ajouter la signature HMAC-SHA256 aux appels de canal API serveur à serveur pour l'intégrité du corps et la protection contre le rejeu.

Utilisez ce guide lorsque vous souhaitez protéger les appels de canal API serveur à serveur avec la signature HMAC-SHA256. La signature vérifie que le corps de la requête est authentique et n'a pas été modifié.

Résultat attendu : chaque requête envoyée à votre canal API inclut un en-tête X-Naixus-Signature valide, et le serveur rejette les requêtes sans cet en-tête.


Activer la signature sur le canal

La signature n'est disponible que pour les canaux à clé serveur (nx_live_ / nx_test_) ; elle est refusée pour un canal à clé publique (nx_pub_).

  1. Dans la console, ouvrez les paramètres du canal et activez Signature HMAC obligatoire.
  2. La console retourne un secret de signature à usage unique commençant par whs_. Copiez-le immédiatement - il ne peut pas être récupéré ultérieurement.
  3. Stockez-le avec votre clé d'API dans votre gestionnaire de secrets :
    export NXAIXUS_SIGNING_SECRET="whs_votre_secret_ici"

Une fois activée, chaque requête POST /public/v1/api/execute vers ce canal doit inclure un en-tête X-Naixus-Signature valide. Les requêtes GET de lecture ne nécessitent pas de signature. Une écriture sans cet en-tête reçoit signature_required (401).


Calculer la signature

Pour chaque requête :

  1. Capturez le corps brut de la requête en octets, exactement tel qu'il sera envoyé.
  2. Obtenez l'horodatage Unix actuel en secondes : t = floor(time.now() / 1000).
  3. Calculez : HMAC-SHA256(clé=secret, données=f"{t}.{corps_brut}").
  4. Définissez l'en-tête : X-Naixus-Signature: t=<t>,v1=<digest_hex_minuscules>.

Le corps que vous signez doit être identique octet par octet au corps que vous envoyez. Ne re-sérialisez pas et n'embellissez pas le JSON.

TypeScript / Node.js

import { createHmac } from 'crypto';

function signRequest(body: string, secret: string): string {
  const ts = Math.floor(Date.now() / 1000);
  const digest = createHmac('sha256', secret).update(`${ts}.${body}`).digest('hex');
  return `t=${ts},v1=${digest}`;
}

const body = JSON.stringify({ payload: { user_message: 'Bonjour' }, stream: false });
const signature = signRequest(body, process.env.NXAIXUS_SIGNING_SECRET!);

await fetch('https://api.example.com/public/v1/api/execute', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NXAIXUS_API_KEY}`,
    'Content-Type': 'application/json',
    'X-Naixus-Signature': signature,
  },
  body,
});

Python

import hashlib
import hmac
import os
import time

def sign_request(body: bytes, secret: str) -> str:
    ts = str(int(time.time()))
    signed = ts.encode("ascii") + b"." + body
    digest = hmac.new(secret.encode("utf-8"), signed, hashlib.sha256).hexdigest()
    return f"t={ts},v1={digest}"

body = b'{"payload":{"user_message":"Bonjour"},"stream":false}'
signature = sign_request(body, os.environ["NXAIXUS_SIGNING_SECRET"])

Shell / curl

BODY='{"payload":{"user_message":"Bonjour"},"stream":false}'
SECRET="$NXAIXUS_SIGNING_SECRET"
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | \
  openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')

curl -X POST "https://api.example.com/public/v1/api/execute" \
  -H "Authorization: Bearer $NXAIXUS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Naixus-Signature: t=$TS,v1=$SIG" \
  -d "$BODY"

Tolérance d'horodatage

Le serveur rejette les requêtes où |maintenant − t| > 300 secondes. Assurez-vous que l'horloge de votre serveur est synchronisée (NTP). Si vous recevez signature_expired, vérifiez que l'horodatage calculé correspond à l'horloge système au moment où la requête est envoyée.


Désactiver la signature

Pour arrêter d'exiger des signatures sans supprimer le secret stocké :

PATCH /api/v1/channels/{channel_id}
Authorization: Bearer <admin_jwt>
X-Tenant-ID: <tenant_id>
{ "config": { "require_signature": false } }

La réactivation ultérieure retourne un nouveau secret à usage unique.


Renouveler le secret de signature

Si le secret de signature est compromis, renouvelez-le immédiatement :

POST /api/v1/channels/{channel_id}/rotate-signing-secret

Le secret précédent est immédiatement invalidé. Le nouveau secret en clair est retourné une seule fois dans signing_secret. Mettez à jour le secret de votre serveur avant la prochaine requête.

Voir Renouveler les credentials pour la procédure complète de rotation.


Référence

Pour les codes d'erreur et la signature, voir la référence d'API - Signature HMAC.

On this page