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_).
- Dans la console, ouvrez les paramètres du canal et activez Signature HMAC obligatoire.
- 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. - 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 :
- Capturez le corps brut de la requête en octets, exactement tel qu'il sera envoyé.
- Obtenez l'horodatage Unix actuel en secondes :
t = floor(time.now() / 1000). - Calculez :
HMAC-SHA256(clé=secret, données=f"{t}.{corps_brut}"). - 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-secretLe 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.