Proxy di credenziali — tecnico

Come funziona il proxy.

Contro cosa protegge. Contro cosa non protegge.

Questa pagina è destinata a revisori della sicurezza, penetration tester e ingegneri che valutano il modello di minaccia del proxy. Descrive cosa fa il proxy a livello di protocollo, dove risiedono le credenziali in memoria e quali superfici di attacco rimangono.

Architettura

Il proxy è un proxy HTTPS MITM basato su CONNECT. Un agente IA imposta HTTPS_PROXY per puntare ad esso. Quando l'agente effettua una richiesta HTTPS, il proxy intercetta la connessione TLS, ispeziona gli header della richiesta per riferimenti alle credenziali, li risolve rispetto alla cassaforte Clavitor e inoltra la richiesta con le credenziali iniettate all'API upstream.

Il proxy ascolta su 127.0.0.1:1983 per impostazione predefinita — il pattern sidecar in cui il proxy e l'agente condividono un host. Per distribuzioni condivise (un proxy che serve più agenti su una rete privata, sidecar di container per più carichi di lavoro, host proxy dedicato), l'interfaccia di ascolto è configurabile tramite CLAVITOR_PROXY_LISTEN.

illustration: unknown name=proxy-sequence

Il proxy è un binario Go standalone. Nessun CGO. Tutta la crittografia del protocollo Clavitor passa attraverso un'implementazione canonica Rust compilata in WebAssembly e caricata tramite wazero all'avvio.

Gestione TLS

Il proxy genera una CA root ECDSA P-256 autofirmata al primo avvio, persistita nella directory del binario con modalità 0600. Per ogni host upstream, un certificato foglia viene emesso su richiesta, firmato da questa CA e memorizzato nella cache in memoria con rimozione limitata (1.000 host). I certificati foglia sono validi per 24 ore e rigenerati in modo trasparente alla 23ª ora per prevenire la scadenza a metà sessione.

L'agente deve fidarsi del certificato CA del proxy. Esportarlo con clavitor-proxy ca.

Le connessioni upstream utilizzano TLS 1.3 minimo con negoziazione ALPN per HTTP/2 e HTTP/1.1. Il pool di certificati di sistema viene utilizzato per la verifica upstream. Nessun certificate pinning — il proxy si fida di ciò di cui si fida il sistema operativo.

Credential lifecycle

Le credenziali non vengono mai memorizzate nella cache, mai scritte su disco e mai conservate più a lungo di una richiesta HTTP.

FaseDove esiste la credenzialeDurata
A riposo nella cassaforteTesto cifrato AES-GCM nel database della cassaforteFino all'eliminazione
In transito verso il proxyRisposta JSON crittografata TLS dall'API della cassaforteUn round-trip HTTP
Decifrata nel proxyMemoria del processo (stringa Go sull'heap)Una richiesta HTTP
Iniettata nella richiesta upstreamByte crittografati TLS sul filo verso l'upstreamUna richiesta HTTP

Il proxy detiene la chiave di decrittografia delle credenziali dell'agente (16 byte) in memoria per tutta la sua durata di esecuzione. Viene caricata dalla configurazione sidecar crittografata (formato CLV1) all'avvio e cancellata allo spegnimento grazioso. La chiave non lascia mai il processo.

La configurazione sidecar è crittografata con AES-128-GCM e HMAC-SHA256 utilizzando chiavi deterministiche derivate da un seed statico. Questo è un offuscamento, non riservatezza — il confine di sicurezza sono i permessi del file (0600) e il possesso del file. Il formato CLV1 è condiviso tra il proxy, la CLI e l'estensione del browser.

Modalità di risoluzione

Modalità 1 — placeholder esplicito

L'agente include un riferimento clavitor://Entry/field in un header di richiesta. Il proxy cerca nella cassaforte la voce per nome, la recupera, decifra il campo nominato e sostituisce il placeholder con il valore reale.

Se la ricerca restituisce zero o più di un risultato, il proxy restituisce 502 con un codice di errore stabile. Il placeholder non viene mai rimosso e inoltrato così com'è.

Modalità 2 — corrispondenza URL

Quando non è presente alcun placeholder, il proxy chiede alla cassaforte le voci il cui campo URL corrisponde all'host upstream. Se esiste esattamente una corrispondenza con una forma di campo riconosciuta, il proxy inietta automaticamente le credenziali.

Zero corrispondenze → passthrough (nessuna aspettativa di credenziali). Corrispondenze multiple → 502 con indicazioni di disambiguazione. Forma di campo sconosciuta → 502.

L'albero decisionale è deterministico: placeholder presente → risolvi o fallisci. Nessun placeholder → corrispondenza URL o passthrough. Non esiste un percorso di fallback silenzioso in cui una risoluzione fallita comporta una richiesta all'upstream senza credenziali.

Agent identity

Per impostazione predefinita, la cassaforte vede l'ID agente del proxy su ogni richiesta. Limiti di frequenza, controlli di ambito e voci di audit sono attribuiti al proxy.

Quando più agenti condividono un'istanza proxy, il placeholder può includere un ID agente: clavitor://agentid@Entry/field. Il proxy invia questo ID agente alla cassaforte, che applica gli ambiti e i limiti di frequenza di quell'agente e registra l'accesso ad esso. L'ID agente è il valore esadecimale di 32 caratteri mostrato nella pagina dei dettagli dell'agente nell'interfaccia utente della cassaforte.

# 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
DistribuzioneModello di identitàIsolamento
Un proxy per agenteID proxy = ID agente (predefinito)Completo — binario separato, configurazione, ambito, limiti di frequenza
Proxy condiviso, nessun ID agente nell'URLTutti gli agenti condividono l'ID del proxyAmbito e limiti di frequenza condivisi
Proxy condiviso + agentid@ nell'URLIdentità per agenteAmbito, limiti di frequenza e audit per agente

L'ID agente nell'URL non è un meccanismo di autenticazione — il token CVT del proxy autentica la connessione. L'ID agente determina l'attribuzione: quali ambiti si applicano, quali limiti di frequenza contano, quale traccia di audit registra l'accesso. La cassaforte rifiuta gli ID agente sconosciuti con un errore evidente.

Sicurezza di rete

Protezione SSRF

Per impostazione predefinita, il proxy blocca le connessioni upstream verso reti private (RFC 1918), metadati delle istanze cloud (169.254.169.254), loopback, link-local e intervalli carrier-grade NAT. Il DNS viene risolto per primo; tutti gli IP restituiti vengono convalidati prima che venga stabilita la connessione TCP, chiudendo la finestra TOCTOU di reindirizzamento DNS.

Sovrascrivere con CLAVITOR_PROXY_ALLOW_PRIVATE=true per gli agenti che accedono legittimamente ad API private.

Pinning del target

L'host di destinazione CONNECT viene catturato all'instaurazione del tunnel e utilizzato per l'intera durata del tunnel. Le richieste successive all'interno del tunnel non possono reindirizzare a un host diverso manipolando l'header Host. Una mancata corrispondenza comporta 502.

Ciò impedisce a un agente di stabilire un tunnel verso api.openai.com e quindi inviare richieste a internal-service.corp.

Gestione degli header

Gli header hop-by-hop vengono rimossi sia dalle richieste che dalle risposte secondo RFC 7230 §6.1: Connection, Keep-Alive, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, TE, Trailers, Transfer-Encoding, Upgrade.

Set-Cookie viene rimosso dalle risposte upstream per impedire agli upstream di inserire cookie nel client HTTP dell'agente.

I corpi delle richieste e delle risposte fluiscono senza buffering. I corpi delle richieste sono limitati a 64 MB per impostazione predefinita (CLAVITOR_PROXY_MAX_BODY_MB). I corpi delle risposte fluiscono senza un limite rigido; viene emesso un avviso di log quando Content-Length supera i 100 MB.

Field-to-header mapping

In modalità di corrispondenza URL, il proxy mappa le etichette dei campi della cassaforte agli header HTTP:

Etichetta del campoHeader iniettato
key, apikey, api_key, token, secret, bearer, access_tokenAuthorization: Bearer <value>
x-api-key, api-keyX-API-Key: <value>
username + password (accoppiati)Authorization: Basic base64(user:pass)
Qualsiasi altra cosaRifiutato — ERR-PROXY-052

In modalità placeholder, l'agente controlla quale campo viene risolto e dove va. La mappatura sopra si applica solo alla modalità di corrispondenza URL.

Error codes

Ogni errore produce un codice stabile ERR-PROXY-NNN. Questi codici fanno parte dell'interfaccia pubblica del proxy — gli agenti e gli operatori possono confrontarli per avvisi e debug.

IntervalloCategoria
001–019Configurazione (config, init, generazione CA, WASM)
020–029Ciclo di vita del demone
030–049Risoluzione placeholder (URI clavitor://)
050–069Iniezione tramite corrispondenza URL
070–089Upstream / TLS

I campi di identità sono irraggiungibili

Le voci della cassaforte supportano tre livelli di crittografia. I campi crittografati dalla cassaforte sono metadati in testo chiaro. I campi crittografati dalle credenziali vengono decifrati con la chiave dell'agente. I campi crittografati dall'identità sono crittografati con una chiave che il server e il proxy non hanno mai visto. Solo il proprietario della cassaforte, tramite la propria chiave hardware di sicurezza, può decifrarli.

Se un placeholder fa riferimento a un campo crittografato dall'identità, il proxy restituisce ERR-PROXY-035. Nessun fallback, nessun risultato parziale. Il campo è architettonicamente irraggiungibile dal proxy.

Contro cosa il proxy non protegge

Il modello di minaccia del proxy è un'abilità compromessa o un'iniezione di prompt che induce un agente autenticato a raccogliere credenziali. I limiti di frequenza per agente della cassaforte, le quote di voci uniche e il blocco a due tentativi sono le difese primarie. Il proxy aggiunge un punto di applicazione a livello di rete in cui le credenziali vengono risolte per richiesta e mai detenute dall'agente.

Un host compromesso

Il proxy viene eseguito sulla stessa macchina dell'agente. Un attaccante con accesso root può leggere la memoria del processo, allegare un debugger o intercettare il traffico di loopback. Il proxy è un livello di iniezione di credenziali, non un confine di sicurezza hardware.

Esfiltrazione di credenziali tramite la risposta API

Se l'API upstream ripete la credenziale nella sua risposta (ad esempio, un endpoint "whoami"), l'agente la vede. Il proxy inietta le credenziali nelle richieste, non nelle risposte. Non filtra ciò che ritorna.

Logging

Il proxy registra una riga per ogni CONNECT accettato ed emette righe di errore per i fallimenti. Non registra mai:

  • Valori delle credenziali decifrate
  • URL completi delle richieste (le stringhe di query possono contenere segreti — vengono registrati solo schema + host + percorso)
  • Corpi delle richieste o delle risposte
  • La chiave di decrittografia delle credenziali o il contenuto della configurazione sidecar

Quando il proxy rileva che una risposta 400 dall'upstream contiene parole chiave relative all'autenticazione (unauthorized, invalid token, ecc.), registra un suggerimento diagnostico che suggerisce che la credenziale iniettata potrebbe essere obsoleta. La risposta viene inoltrata invariata.

Crittografia

Tutta la crittografia del protocollo Clavitor — decrittografia dei campi AES-GCM, derivazione delle chiavi HKDF, codifica base62, emissione di token CVT, pacchettizzazione/depacchettizzazione della configurazione CLV1 — viene eseguita all'interno di un singolo modulo WebAssembly (clavis_crypto.wasm) caricato tramite wazero, un runtime WASM puro Go. Nessun CGO. Nessuna reimplementazione Go delle primitive Clavitor.

Il modulo WASM è compilato dalla stessa crate Rust (clavis-crypto) utilizzata dal browser, dalla CLI e dalle estensioni del browser. Un'unica fonte di verità, un unico binario, un'unica superficie di audit.

Il proxy utilizza crypto/tls di Go per il wire TLS e crypto/ecdsa per la generazione dei certificati MITM. Queste sono preoccupazioni di trasporto, non operazioni del protocollo Clavitor.

Configuration

I segreti (chiave di decrittografia delle credenziali, ID agente, ID dispositivo, URL cassaforte) risiedono nella configurazione sidecar CLV1 crittografata, scritta una volta durante clavitor-proxy init. Le manopole operative risiedono nelle variabili d'ambiente:

VariabilePredefinitoScopo
CLAVITOR_PROXY_LISTEN127.0.0.1Interfaccia di ascolto. Impostata su 0.0.0.0 per distribuzioni condivise, o su un IP di interfaccia specifico.
CLAVITOR_PROXY_PORT1983Porta di ascolto
CLAVITOR_PROXY_ALLOW_PRIVATEfalseConsenti connessioni a reti RFC-1918 / private
CLAVITOR_PROXY_MAX_BODY_MB64Limite dimensione corpo richiesta
CLAVITOR_PROXY_WRITE_TIMEOUT300Timeout di scrittura risposta in secondi
CLAVITOR_CONFIG(directory eseguibile)Sovrascrive il percorso della configurazione sidecar

Le manopole operative non sono segreti. Non appartengono alla configurazione crittografata. Appartengono a dove gli strumenti di distribuzione li gestiscono già — l'ambiente.

Rivedere autonomamente.

La crittografia è un singolo artefatto WASM auditabile. Il modello di minaccia è documentato. Se trovate qualcosa che ci è sfuggito, vogliamo saperlo.