Proxy d'identifiants — technique

Comment fonctionne le proxy.

Ce contre quoi il protège. Ce contre quoi il ne protège pas.

Cette page s'adresse aux réviseurs de sécurité, aux testeurs d'intrusion et aux ingénieurs évaluant le modèle de menace du proxy. Elle décrit ce que fait le proxy au niveau du protocole, où se trouvent les identifiants en mémoire et quelles surfaces d'attaque subsistent.

Architecture

Le proxy est un proxy HTTPS MITM basé sur CONNECT. Un agent IA configure HTTPS_PROXY pour qu'il pointe vers lui. Lorsque l'agent effectue une requête HTTPS, le proxy intercepte la connexion TLS, inspecte les en-têtes de requête pour les références d'identifiants, les résout par rapport au coffre-fort Clavitor et transmet la requête avec les identifiants injectés à l'API en amont.

Le proxy écoute par défaut sur 127.0.0.1:1983 — le modèle sidecar où le proxy et l'agent partagent un hôte. Pour les déploiements partagés (un proxy servant plusieurs agents sur un réseau privé, un sidecar de conteneur pour plusieurs charges de travail, un hôte proxy dédié), l'interface d'écoute est configurable via CLAVITOR_PROXY_LISTEN.

illustration: unknown name=proxy-sequence

Le proxy est un binaire Go autonome. Pas de CGO. Toute la cryptographie du protocole Clavitor passe par une implémentation canonique en Rust compilée en WebAssembly et chargée via wazero au démarrage.

Gestion TLS

Le proxy génère une autorité de certification racine ECDSA P-256 auto-signée lors de la première exécution, persistée dans le répertoire du binaire avec le mode 0600. Pour chaque hôte en amont, un certificat feuille est frappé à la demande, signé par cette AC, et mis en cache en mémoire avec une éviction bornée (1 000 hôtes). Les certificats feuilles sont valides pendant 24 heures et régénérés de manière transparente à la marque des 23 heures pour éviter l'expiration en milieu de session.

L'agent doit faire confiance au certificat CA du proxy. Exportez-le avec clavitor-proxy ca.

Les connexions en amont utilisent TLS 1.3 minimum avec négociation ALPN pour HTTP/2 et HTTP/1.1. Le pool de certificats système est utilisé pour la vérification en amont. Pas d'épinglage de certificat — le proxy fait confiance à ce en quoi le système d'exploitation a confiance.

Credential lifecycle

Les identifiants ne sont jamais mis en cache, jamais écrits sur disque et jamais conservés plus d'une requête HTTP.

PhaseOù se trouve l'identifiantDurée
Au repos dans le coffre-fortChiffrement AES-GCM dans la base de données du coffre-fortJusqu'à suppression
En transit vers le proxyRéponse JSON chiffrée TLS de l'API du coffre-fortUn aller-retour HTTP
Déchiffré dans le proxyMémoire du processus (chaîne Go sur le tas)Une requête HTTP
Injecté dans la requête en amontOctets chiffrés TLS sur le fil vers l'amontUne requête HTTP

Le proxy conserve la clé de déchiffrement des identifiants de l'agent (16 octets) en mémoire pendant toute sa durée d'exécution. Elle est chargée à partir de la configuration sidecar chiffrée (format CLV1) au démarrage et effacée lors d'un arrêt propre. La clé ne quitte jamais le processus.

La configuration sidecar est chiffrée avec AES-128-GCM et HMAC-SHA256 en utilisant des clés déterministes dérivées d'une graine statique. Il s'agit d'une obfuscation, pas d'une confidentialité — la frontière de sécurité réside dans les permissions de fichier (0600) et la possession du fichier. Le format CLV1 est partagé entre le proxy, la CLI et l'extension de navigateur.

Modes de résolution

Mode 1 — espace réservé explicite

L'agent inclut une référence clavitor://Entry/field dans un en-tête de requête. Le proxy recherche l'entrée dans le coffre-fort par son nom, la récupère, déchiffre le champ nommé et substitue l'espace réservé par la valeur réelle.

Si la recherche renvoie zéro ou plus d'un résultat, le proxy renvoie 502 avec un code d'erreur stable. L'espace réservé n'est jamais supprimé et transmis tel quel.

Mode 2 — correspondance d'URL

Lorsqu'aucun espace réservé n'est présent, le proxy demande au coffre-fort les entrées dont le champ URL correspond à l'hôte en amont. S'il existe exactement une correspondance avec une forme de champ reconnue, le proxy injecte automatiquement les identifiants.

Zéro correspondance → passage (aucune attente d'identifiant). Correspondances multiples → 502 avec instructions de désambiguïsation. Forme de champ inconnue → 502.

L'arbre de décision est déterministe : espace réservé présent → résoudre ou échouer. Pas d'espace réservé → correspondance d'URL ou passage. Il n'y a pas de chemin de repli silencieux où une résolution échouée entraîne une requête vers l'amont sans identifiants.

Agent identity

Par défaut, le coffre-fort voit l'ID d'agent du proxy à chaque requête. Les limites de débit, les vérifications de portée et les entrées d'audit sont attribuées au proxy.

Lorsque plusieurs agents partagent une instance de proxy, l'espace réservé peut inclure un ID d'agent : clavitor://agentid@Entry/field. Le proxy envoie cet ID d'agent au coffre-fort, qui applique les portées et les limites de débit de cet agent et enregistre l'accès à son nom. L'ID d'agent est la valeur hexadécimale de 32 caractères affichée sur la page de détails de l'agent dans l'interface utilisateur du coffre-fort.

# Without agent ID — attributed to the proxy
Authorization: Bearer clavitor://OpenAI/key

# With agent ID — attributed to agent 0102030405060708090a0b0c0d0e0f10
Authorization: Bearer clavitor://0102030405060708090a0b0c0d0e0f10@OpenAI/key
DéploiementModèle d'identitéIsolation
Un proxy par agentID du proxy = ID de l'agent (par défaut)Complet — binaire, configuration, portée, limites de débit séparés
Proxy partagé, pas d'ID d'agent dans l'URLTous les agents partagent l'ID du proxyPortée et limites de débit partagées
Proxy partagé + agentid@ dans l'URLIdentité par agentPortée, limites de débit et audit par agent

L'ID d'agent dans l'URL n'est pas un mécanisme d'authentification — le jeton CVT du proxy authentifie la connexion. L'ID d'agent détermine l'attribution : quelles portées s'appliquent, quelles limites de débit comptent, quelle piste d'audit enregistre l'accès. Le coffre-fort rejette les ID d'agent inconnus avec un échec bruyant.

Sécurité réseau

Protection SSRF

Par défaut, le proxy bloque les connexions en amont vers les réseaux privés (RFC 1918), les métadonnées d'instance cloud (169.254.169.254), les boucles locales, les réseaux locaux et les plages NAT de type carrier-grade. Le DNS est résolu en premier ; toutes les IP retournées sont validées avant l'établissement de la connexion TCP, fermant la fenêtre TOCTOU de re-liaison DNS.

Remplacez avec CLAVITOR_PROXY_ALLOW_PRIVATE=true pour les agents qui accèdent légitimement à des API privées.

Épinglage de cible

L'hôte cible CONNECT est capturé à l'établissement du tunnel et utilisé pendant toute la durée de vie du tunnel. Les requêtes ultérieures dans le tunnel ne peuvent pas être redirigées vers un autre hôte en manipulant l'en-tête Host. Une divergence entraîne un 502.

Cela empêche un agent d'établir un tunnel vers api.openai.com puis d'envoyer des requêtes à internal-service.corp.

Gestion des en-têtes

Les en-têtes de saut en saut sont supprimés des requêtes et des réponses conformément à la RFC 7230 §6.1 : Connection, Keep-Alive, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, TE, Trailers, Transfer-Encoding, Upgrade.

Set-Cookie est supprimé des réponses en amont pour empêcher les systèmes en amont d'insérer des cookies dans le client HTTP de l'agent.

Les corps de requête et de réponse transitent sans mise en mémoire tampon. Les corps de requête sont limités à 64 Mo par défaut (CLAVITOR_PROXY_MAX_BODY_MB). Les corps de réponse transitent sans limite stricte ; un avertissement de journal est émis lorsque Content-Length dépasse 100 Mo.

Field-to-header mapping

En mode de correspondance d'URL, le proxy mappe les étiquettes de champ du coffre-fort aux en-têtes HTTP :

Étiquette de champEn-tête injecté
key, apikey, api_key, token, secret, bearer, access_tokenAuthorization: Bearer <value>
x-api-key, api-keyX-API-Key: <value>
username + password (appariés)Authorization: Basic base64(user:pass)
Tout le resteRejeté — ERR-PROXY-052

En mode espace réservé, l'agent contrôle quel champ est résolu et où il va. Le mappage ci-dessus ne s'applique qu'au mode de correspondance d'URL.

Error codes

Chaque échec produit un code stable ERR-PROXY-NNN. Ces codes font partie de l'interface publique du proxy — les agents et les opérateurs peuvent les faire correspondre pour l'alerte et le débogage.

PlageCatégorie
001–019Configuration (config, init, génération CA, WASM)
020–029Cycle de vie du démon
030–049Résolution d'espace réservé (URI clavitor://)
050–069Injection par correspondance d'URL
070–089Amont / TLS

Les champs d'identité sont inaccessibles

Les entrées du coffre-fort prennent en charge trois niveaux de chiffrement. Les champs relevant du Chiffrement du coffre-fort sont des métadonnées en clair. Les champs relevant du Chiffrement des identifiants sont déchiffrés avec la clé de l'agent. Les champs relevant du Chiffrement de l'identité sont chiffrés avec une clé que le serveur et le proxy n'ont jamais vue. Seul le propriétaire du coffre-fort, via sa clé matérielle de sécurité, peut les déchiffrer.

Si un espace réservé fait référence à un champ relevant du Chiffrement de l'identité, le proxy renvoie ERR-PROXY-035. Pas de repli, pas de résultat partiel. Le champ est architecturalement inaccessible depuis le proxy.

Ce contre quoi le proxy ne protège pas

Le modèle de menace du proxy est une compétence compromise ou une injection de prompt qui amène un agent authentifié à récolter des identifiants. Les limites de débit par agent du coffre-fort, les quotas d'entrées uniques et le verrouillage en deux étapes sont les principales défenses. Le proxy ajoute un point d'application au niveau réseau où les identifiants sont résolus par requête et jamais conservés par l'agent.

Un hôte compromis

Le proxy s'exécute sur la même machine que l'agent. Un attaquant ayant un accès root peut lire la mémoire du processus, attacher un débogueur ou intercepter le trafic de boucle locale. Le proxy est une couche d'injection d'identifiants, pas une frontière de sécurité matérielle.

Exfiltration d'identifiants via la réponse API

Si l'API en amont renvoie l'identifiant dans sa réponse (par exemple, un point de terminaison "whoami"), l'agent le voit. Le proxy injecte les identifiants dans les requêtes, pas dans les réponses. Il ne filtre pas ce qui revient.

Journalisation

Le proxy enregistre une ligne par CONNECT accepté et émet des lignes d'erreur pour les échecs. Il n'enregistre jamais :

  • Valeurs d'identifiants déchiffrées
  • URL de requête complètes (les chaînes de requête peuvent contenir des secrets — seuls le schéma, l'hôte et le chemin sont enregistrés)
  • Corps de requête ou de réponse
  • Clé de déchiffrement des identifiants ou contenu de la configuration sidecar

Lorsque le proxy détecte qu'une réponse 400 de l'amont contient des mots-clés liés à l'authentification (unauthorized, invalid token, etc.), il enregistre un indice de diagnostic suggérant que l'identifiant injecté peut être obsolète. La réponse est transmise inchangée.

Cryptographie

Toute la cryptographie du protocole Clavitor — déchiffrement de champ AES-GCM, dérivation de clé HKDF, encodage base62, frappe de jeton CVT, empaquetage/dépaquetage de configuration CLV1 — s'exécute dans un seul module WebAssembly (clavis_crypto.wasm) chargé via wazero, un runtime WASM pur Go. Pas de CGO. Pas de réimplémentation Go des primitives Clavitor.

Le module WASM est compilé à partir de la même crate Rust (clavis-crypto) utilisée par le navigateur, la CLI et les extensions de navigateur. Une seule source de vérité, un seul binaire, une seule surface d'audit.

Le proxy utilise crypto/tls de Go pour le fil TLS et crypto/ecdsa pour la génération de certificats MITM. Ce sont des préoccupations de transport, pas des opérations du protocole Clavitor.

Configuration

Les secrets (clé de déchiffrement des identifiants, ID d'agent, ID de périphérique, URL du coffre-fort) résident dans la configuration sidecar CLV1 chiffrée, écrite une fois lors de clavitor-proxy init. Les boutons de commande opérationnels résident dans les variables d'environnement :

VariableDéfautObjectif
CLAVITOR_PROXY_LISTEN127.0.0.1Interface d'écoute. Définir sur 0.0.0.0 pour les déploiements partagés, ou sur l'IP d'une interface spécifique.
CLAVITOR_PROXY_PORT1983Port d'écoute
CLAVITOR_PROXY_ALLOW_PRIVATEfalseAutoriser les connexions aux réseaux RFC-1918 / privés
CLAVITOR_PROXY_MAX_BODY_MB64Limite de taille du corps de requête
CLAVITOR_PROXY_WRITE_TIMEOUT300Délai d'attente d'écriture de réponse en secondes
CLAVITOR_CONFIG(répertoire de l'exécutable)Remplacer le chemin de configuration sidecar

Les boutons de commande opérationnels ne sont pas des secrets. Ils n'appartiennent pas à la configuration chiffrée. Ils appartiennent là où les outils de déploiement les gèrent déjà — l'environnement.

Examinez cela vous-même.

La cryptographie est un artefact WASM unique et auditable. Le modèle de menace est documenté. Si vous trouvez quelque chose que nous avons manqué, nous voulons en être informés.