Les passerelles d'agents se situent entre des clients peu fiables et des effets de bord coûteux. En 2026, les déploiements OpenClaw matures traitent les clés d'idempotence comme des obligations contractuelles pour éviter doubles facturations et mutations fichiers dupliquées. Associez des claims Redis atomiques à la validation JSON Schema, au drain nginx progressif, aux budgets 429 Retry-After et aux diagnostics de timeout avant d'appliquer les sections suivantes.
Contrat client et grammaire
Exposez un seul canal canonique : Idempotency-Key pour les passerelles de style HTTP ou idempotency_key pour les charges JSON de style gRPC. Rejetez les clés dont l'entropie post-décodage base64url est inférieure à 16 octets et imposez une longueur maximale de 128 caractères ASCII pour protéger journaux et équilibreurs. Après trim et filtrage des caractères de contrôle, calculez SHA-256 pour alimenter Redis sans exposer la valeur brute. Liez chaque opération au tuple (tenant_id, route_id, key_hash, schema_version) afin qu'une montée de version de schéma invalide explicitement les anciens rejouages.
Stockage et verrou atomique
Le premier appel exécute SET idempo:{tenant}:{hash}:claim NX EX 172800. Les workers concurrents lisent l'enveloppe et répondent sans rappeler l'amont. Après succès, persistez le code HTTP, un sous-ensemble d'en-têtes sûr et une empreinte BLAKE3 ou SHA-256 du corps. Au-delà de 1 MiB, déplacez le corps vers l'objet stockage et ne conservez qu'un pointeur horodaté.
# pseudo OpenResty
local key = "idempo:" .. tenant .. ":" .. idem_hash
if redis:set(key..":claim", pid, "NX", "EX", 172800) == nil then
return replay(key)
end
proxy_pass http://openclaw_upstream;
Matrice topologique
| Topologie | Avantages | Risques | Cas d'usage |
|---|---|---|---|
| LRU en processus | Latence minimale | Cerveau divisé | Développement local |
| Cluster Redis | TTL et NX matures | Clés brûlantes | Production générique |
| Verrous SQL | Piste d'audit | Latence plus haute | Finance régulée |
| Baux etcd | Intégration mesh | Complexité ops | Grandes entreprises mesh |
Fenêtres TTL 172800/259200 s
Quarante-huit heures correspondent aux usages courants des API de paiement. Soixante-douze heures couvrent les traitements de nuit qui débordent sur un troisième jour. Après expiration, traitez chaque requête comme neuve et faites tourner les clés lorsque l'utilisateur choisit explicitement « réessayer comme nouvelle opération ». Harmonisez SLA marketing, contrats juridiques et valeur EX Redis pour éviter les écarts d'audit.
Archivez les enveloppes expirées dans un stockage froid lorsque la conformité exige plusieurs années de rétention mais que la RAM ne peut suivre. Étiquetez chaque archive avec la version de schéma et l'empreinte Git du bundle passerelle.
Enveloppe de rejeu
Les rejouages doivent rester identiques octet pour octet lorsque c'est possible. Si la compression gzip introduit de la variabilité, stockez le JSON canonique avant compression et compressez à la volée en sortie. Ajoutez un en-tête interne dedupe_hit: true pour le support, puis retirez-le avant la frontière publique. Pour les flux d'outils, incluez des numéros de fragment afin qu'un flux partiel ne soit jamais confondu avec une réponse complète. Déclenchez une alerte majeure si le taux d'incohérence de somme dépasse 0,01 % pendant dix minutes.
Coordination nginx
Terminez TLS à la périphérie, normalisez les clés et propagez un en-tête interne dérivé du hachage vers OpenClaw. Pendant le drain, conservez le même DSN Redis pour que les clients mobiles lents retrouvent leur contexte. Réglez proxy_read_timeout légèrement au-dessus du budget amont interne, en accord avec les diagnostics de timeout. Exemptez les réponses de rejeu interne des compteurs limit_req afin de ne pas pénaliser le trafic légitime.
Liste de contrôle numérotée
- Inventorier toutes les routes mutantes et poser l'attribut
requires_idempotency=true. - Forcer les SDK à émettre UUIDv4 par défaut et rejeter les clés manuelles de moins de 22 caractères base64url.
- Exiger au moins trois shards primaires Redis en production avec AOF
everysec. - Écrire des tests d'intégration à vingt requêtes concurrentes identiques garantissant un seul effet de bord.
- Organiser un jeu de rôle où 50 % des pods tournent pendant un drain actif et un flot dupliqué.
- Publier les codes d'erreur pour clé expirée, corps divergent et locataire incorrect.
- Superviser part de rejeu, p99 des revendications et clés évictées par minute.
Télémétrie et SLO
Émettez idempo_claim_total, idempo_replay_total et idempo_conflict_total avec des étiquettes de locataire hachées pour limiter la cardinalité. Séparez la latence Redis de la latence modèle afin de ne pas attribuer à tort une régression de cache à un fournisseur LLM. Si la part de rejeu dépasse 35 % pendant plus de trente minutes, examinez d'abord une boucle cliente. Revue hebdomadaire des conflits pour alerter tôt les intégrateurs externes.
Pour la facturation, distinguez « coup d'idempotence servi » et « événement facturable » afin de ne pas gonfler artificiellement la marge. Les tableaux de bord clients peuvent afficher une moyenne mobile sur sept jours pour aider les équipes succès.
Ajoutez des histogrammes séparant les latences de revendication « à froid » et « à chaud » : un pic froid indique souvent des clés neuves à chaque retry plutôt qu'une réutilisation saine. Croisez ces courbes avec les files fournisseurs pour prouver, pendant les ponts, que le goulet n'est pas la passerelle. N'exportez vers le SIEM que des hachages et des identifiants de corrélation.
Documentez aussi quels en-têtes participent au hachage du corps afin d'éviter les faux conflits introduits par des proxys mobiles.
Préparez un modèle d'incident d'une ligne qui résume hachage, route, version de schéma et locataires impactés pour accélérer les post-mortems.
Partition réseau
Si Redis tombe, choisissez explicitement entre fermeture contrôlée et mode dégradé. Les flux monétaires doivent répondre 503 avec instructions de backoff. Côté client, plafonnez à cinq tentatives avec jitter et plafond de 32 secondes sauf si Retry-After impose plus, comme expliqué dans l'article 429. Tenez un journal compensateur keyed par le même hachage lorsque l'amont réussit mais l'enveloppe échoue, afin de reconstruire l'état sans refacturer.
Les pannes régionales imposent aussi de documenter quels en-têtes entrent dans le hachage du corps et lesquels sont ignorés délibérément, sinon des clients mobiles ajoutant un en-tête cache provoqueront de faux conflits. Planifiez un chaos trimestriel qui injecte de la latence Redis pour détecter les régressions à chaud.
Couplez Redis à un disjoncteur applicatif : si le taux d'erreurs de claim dépasse un seuil pendant cinq minutes, basculez vers une file offline qui rejoue plus tard avec les mêmes clés.
FAQ
Les GET ont-ils besoin de clés ?
Non en général ; interdisez les effets destructeurs via GET.
Même clé sur deux routes ?
Interdit ; incluez toujours l'identifiant de route.
Files hors ligne ?
Attribuez la clé à l'enfilement et réutilisez-la au flush.
Les hôtes Mac mini Apple Silicon offrent un environnement silencieux pour répéter charges dupliquées, scripts Lua et bascules Redis sans toucher la production. macOS reproduit launchd, trousseau et sandbox observés en salle blanche, ce qui rassure sécurité et plateforme. Louer un Mac mini cloud chez MacHTML coûte environ 16,9 USD par jour, un coût modeste comparé à une bridge téléphonique incident nocturne.
Le même hôte permet des vérifications TLS parallèles avec openssl s_client, ce qui aligne nginx et la passerelle avant la mise en ligne.
Répéter la dédup sur Mac cloud
Louez un Mac mini, clonez Redis et nginx, injectez des requêtes dupliquées vers OpenClaw puis ajustez les TTL en confiance.