Credential proxy — technisch

Hoe de proxy werkt.

Waar het tegen beschermt. Waar het niet tegen beschermt.

Deze pagina is voor security reviewers, penetration testers en engineers die het dreigingsmodel van de proxy evalueren. Het beschrijft wat de proxy doet op protocolniveau, waar inloggegevens in het geheugen bestaan, en welke aanvalsoppervlakken overblijven.

Architectuur

De proxy is een HTTPS MITM proxy gebaseerd op CONNECT. Een AI-agent stelt HTTPS_PROXY in om ernaar te verwijzen. Wanneer de agent een HTTPS-verzoek doet, onderschept de proxy de TLS-verbinding, inspecteert request headers op verwijzingen naar inloggegevens, lost deze op tegen de Clavitor kluis, en stuurt het verzoek met ingevoegde inloggegevens door naar de upstream API.

De proxy luistert standaard op 127.0.0.1:1983 — het sidecar-patroon waarbij de proxy en de agent een host delen. Voor gedeelde implementaties (één proxy die meerdere agents bedient op een privénetwerk, container sidecar voor meerdere workloads, dedicated proxy host), is de luisterinterface configureerbaar via CLAVITOR_PROXY_LISTEN.

illustration: unknown name=proxy-sequence

De proxy is een standalone Go binary. Geen CGO. Alle Clavitor protocol cryptografie verloopt via een canonieke Rust implementatie gecompileerd naar WebAssembly en geladen via wazero bij opstarten.

TLS-afhandeling

De proxy genereert een zelfondertekende ECDSA P-256 root CA bij de eerste uitvoering, opgeslagen in de directory van de binary met modus 0600. Voor elke upstream host wordt een leaf-certificaat on-demand gemint, ondertekend door deze CA, en in het geheugen gecached met een beperkte verwijdering (1.000 hosts). Leaf-certificaten zijn 24 uur geldig en worden transparant opnieuw gegenereerd op het 23-uurs teken om mid-sessie verlopen te voorkomen.

De agent moet het CA-certificaat van de proxy vertrouwen. Exporteer het met clavitor-proxy ca.

Upstream verbindingen gebruiken minimaal TLS 1.3 met ALPN-onderhandeling voor HTTP/2 en HTTP/1.1. De systeemcertificaatpool wordt gebruikt voor upstream verificatie. Geen certificate pinning — de proxy vertrouwt wat het OS vertrouwt.

Credential lifecycle

Inloggegevens worden nooit gecached, nooit naar schijf geschreven en nooit langer dan één HTTP-verzoek bewaard.

FaseWaar de inloggegevens bestaanDuur
At rest in kluisAES-GCM ciphertext in de kluisdatabaseTot verwijdering
In transit naar proxyTLS-versleuteld JSON-antwoord van kluis APIEén HTTP round-trip
Ontcijferd in proxyProcess-geheugen (Go string op heap)Eén HTTP-verzoek
Ingevoegd in upstream verzoekTLS-versleutelde bytes op de wire naar upstreamEén HTTP-verzoek

De proxy houdt de credential-decryption key van de agent (16 bytes) in het geheugen gedurende de gehele runtime. Deze wordt geladen uit de versleutelde sidecar-configuratie (CLV1-formaat) bij opstarten en gewist bij een nette afsluiting. De sleutel verlaat het proces nooit.

De sidecar-configuratie is versleuteld met AES-128-GCM en HMAC-SHA256 met behulp van deterministische sleutels afgeleid van een statische seed. Dit is obfuscation, geen vertrouwelijkheid — de beveiligingsgrens zijn bestandspermissies (0600) en het bezit van het bestand. Het CLV1-formaat wordt gedeeld tussen de proxy, de CLI en de browser-extensie.

Resolutiemodi

Modus 1 — expliciete placeholder

De agent neemt een clavitor://Entry/field verwijzing op in een request header. De proxy zoekt in de kluis naar de entry op naam, haalt deze op, ontcijfert het benoemde veld, en vervangt de placeholder door de werkelijke waarde.

Als de zoekopdracht nul of meer dan één resultaat oplevert, retourneert de proxy 502 met een stabiele foutcode. De placeholder wordt nooit verwijderd en doorgestuurd zoals deze is.

Modus 2 — URL-match

Wanneer er geen placeholder aanwezig is, vraagt de proxy de kluis om entries waarvan het URL-veld overeenkomt met de upstream host. Als er precies één match bestaat met een herkende veldvorm, voegt de proxy automatisch inloggegevens in.

Nul matches → passthrough (geen verwachting van inloggegevens). Meerdere matches → 502 met disambiguatie-instructies. Onbekende veldvorm → 502.

De beslissingsboom is deterministisch: placeholder aanwezig → oplossen of falen. Geen placeholder → URL-match of passthrough. Er is geen stille fallback-pad waarbij een mislukte resolutie resulteert in een verzoek dat zonder inloggegevens naar upstream gaat.

Agent identity

Standaard ziet de kluis bij elk verzoek de eigen agent-ID van de proxy. Rate limits, scope checks en audit-entries worden toegeschreven aan de proxy.

Wanneer meerdere agents één proxy-instantie delen, kan de placeholder een agent-ID bevatten: clavitor://agentid@Entry/field. De proxy stuurt deze agent-ID naar de kluis, die de scopes en rate limits van die agent toepast en de toegang daartegen logt. De agent-ID is de 32-tekens hexadecimale waarde die wordt weergegeven op de agent-detailpagina in de kluis-UI.

# 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
ImplementatieIdentiteitsmodelIsolatie
Eén proxy per agentProxy ID = agent ID (standaard)Volledig — aparte binary, configuratie, scope, rate limits
Gedeelde proxy, geen agent ID in URLAlle agents delen de ID van de proxyGedeelde scope en rate limits
Gedeelde proxy + agentid@ in URLPer-agent identiteitPer-agent scope, rate limits en audit

De agent-ID in de URL is geen authenticatiemechanisme — de CVT-token van de proxy authenticeert de verbinding. De agent-ID bepaalt de attributie: wiens scopes van toepassing zijn, wiens rate limits tellen, wiens audit trail de toegang registreert. De kluis weigert onbekende agent-ID's met een duidelijke foutmelding.

Netwerkbeveiliging

SSRF-bescherming

Standaard blokkeert de proxy upstream verbindingen naar privénetwerken (RFC 1918), cloud-instantie metadata (169.254.169.254), loopback, link-local en carrier-grade NAT-bereiken. DNS wordt eerst opgelost; alle geretourneerde IP's worden gevalideerd voordat de TCP-verbinding wordt gemaakt, waardoor het DNS-rebinding TOCTOU-venster wordt gesloten.

Overschrijf met CLAVITOR_PROXY_ALLOW_PRIVATE=true voor agents die legitiem privé-API's bereiken.

Target pinning

De CONNECT-doelhost wordt vastgelegd bij het tot stand brengen van de tunnel en gebruikt voor de gehele levensduur van de tunnel. Latere verzoeken binnen de tunnel kunnen niet naar een andere host worden omgeleid door de Host-header te manipuleren. Een mismatch resulteert in 502.

Dit voorkomt dat een agent een tunnel opzet naar api.openai.com en vervolgens verzoeken stuurt naar internal-service.corp.

Header-afhandeling

Hop-by-hop headers worden uit zowel verzoeken als antwoorden verwijderd volgens RFC 7230 §6.1: Connection, Keep-Alive, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, TE, Trailers, Transfer-Encoding, Upgrade.

Set-Cookie wordt uit upstream antwoorden verwijderd om te voorkomen dat upstreams cookies in de HTTP-client van de agent plaatsen.

Request- en response-bodies streamen door zonder buffering. Request-bodies zijn standaard beperkt tot 64 MB (CLAVITOR_PROXY_MAX_BODY_MB). Response-bodies streamen zonder harde limiet; een waarschuwing wordt gelogd wanneer Content-Length 100 MB overschrijdt.

Field-to-header mapping

In URL-match modus, mapt de proxy kluis-veldlabels naar HTTP-headers:

VeldlabelIngevoegde header
key, apikey, api_key, token, secret, bearer, access_tokenAuthorization: Bearer <value>
x-api-key, api-keyX-API-Key: <value>
username + password (gepaard)Authorization: Basic base64(user:pass)
Al het andereAfgewezen — ERR-PROXY-052

In placeholder modus bepaalt de agent welk veld wordt opgelost en waar het naartoe gaat. De mapping hierboven is alleen van toepassing op de URL-match modus.

Error codes

Elke fout produceert een stabiele ERR-PROXY-NNN code. Deze codes maken deel uit van de publieke interface van de proxy — agents en operators kunnen erop matchen voor alerting en debugging.

BereikCategorie
001–019Setup (config, init, CA-generatie, WASM)
020–029Daemon lifecycle
030–049Placeholder resolutie (clavitor:// URIs)
050–069URL-match injectie
070–089Upstream / TLS

Identiteitsvelden zijn onbereikbaar

Kluis-entries ondersteunen drie versleutelingsniveaus. Kluisversleuteling-velden zijn plaintext metadata. Versleuteling van inloggegevens-velden worden ontsleuteld met de sleutel van de agent. Identiteitsversleuteling-velden worden versleuteld met een sleutel die de server en de proxy nooit hebben gezien. Alleen de kluiseigenaar, via hun hardwaresleutel, kan ze ontsleutelen.

Als een placeholder verwijst naar een Identiteitsversleuteling-veld, retourneert de proxy ERR-PROXY-035. Geen fallback, geen gedeeltelijk resultaat. Het veld is architectonisch onbereikbaar vanuit de proxy.

Waar de proxy niet tegen beschermt

Het dreigingsmodel van de proxy is een gecompromitteerde skill of prompt injectie die een geauthenticeerde agent in staat stelt inloggegevens te oogsten. De per-agent rate limits van de kluis, unieke entry quota's en de two-strike lockdown zijn de primaire verdedigingen. De proxy voegt een netwerklaag-handhavingspunt toe waar inloggegevens per-verzoek worden opgelost en nooit door de agent worden bewaard.

Een gecompromitteerde host

De proxy draait op dezelfde machine als de agent. Een aanvaller met root-toegang kan process-geheugen lezen, een debugger koppelen of loopback-verkeer onderscheppen. De proxy is een credential-injectielaag, geen hardware security-grens.

Exfiltratie van inloggegevens via de API-respons

Als de upstream API de inloggegevens teruggeeft in zijn respons (bijv. een "whoami" endpoint), ziet de agent deze. De proxy voegt inloggegevens in verzoeken in, niet in responsen. Het filtert niet wat terugkomt.

Logging

De proxy logt één regel per geaccepteerde CONNECT en geeft foutregels weer voor mislukkingen. Het logt nooit:

  • Ontcijferde inloggegevenswaarden
  • Volledige request URL's (query strings kunnen geheimen bevatten — alleen schema + host + pad worden gelogd)
  • Request- of response-bodies
  • De credential-decryption key of de inhoud van de sidecar-configuratie

Wanneer de proxy detecteert dat een 400-respons van upstream auth-gerelateerde trefwoorden bevat (unauthorized, invalid token, etc.), logt het een diagnostische hint die suggereert dat de ingevoegde inloggegevens verouderd kunnen zijn. De respons wordt ongewijzigd doorgestuurd.

Cryptografie

Alle Clavitor protocol cryptografie — AES-GCM veldontcijfering, HKDF sleutelafleiding, base62 codering, CVT token minting, CLV1 config pack/unpack — wordt uitgevoerd binnen een enkele WebAssembly module (clavis_crypto.wasm) geladen via wazero, een pure-Go WASM runtime. Geen CGO. Geen Go herimplementatie van Clavitor primitives.

De WASM-module is gecompileerd uit dezelfde Rust crate (clavis-crypto) die wordt gebruikt door de browser, de CLI en de browser-extensies. Eén bron van waarheid, één binary, één audit-oppervlak.

De proxy gebruikt Go's crypto/tls voor de TLS-wire en crypto/ecdsa voor MITM-certificaatgeneratie. Dit zijn transportzorgen, geen Clavitor protocoloperaties.

Configuration

Geheimen (credential-decryption key, agent ID, device ID, vault URL) bevinden zich in de versleutelde CLV1 sidecar-configuratie, eenmalig geschreven tijdens clavitor-proxy init. Operationele knoppen bevinden zich in omgevingsvariabelen:

VariabeleStandaardDoel
CLAVITOR_PROXY_LISTEN127.0.0.1Luisterinterface. Instellen op 0.0.0.0 voor gedeelde implementaties, of op een specifiek interface-IP.
CLAVITOR_PROXY_PORT1983Luisterpoort
CLAVITOR_PROXY_ALLOW_PRIVATEfalseSta verbindingen toe met RFC-1918 / privénetwerken
CLAVITOR_PROXY_MAX_BODY_MB64Limiet voor request body-grootte
CLAVITOR_PROXY_WRITE_TIMEOUT300Response write timeout in seconden
CLAVITOR_CONFIG(exe dir)Pad naar sidecar-configuratie overschrijven

Operationele knoppen zijn geen geheimen. Ze horen niet thuis in de versleutelde configuratie. Ze horen thuis waar deployment tools ze al beheren — de omgeving.

Beoordeel dit zelf.

De cryptografie is een enkel auditeerbaar WASM-artefact. Het dreigingsmodel is gedocumenteerd. Als je iets vindt dat wij hebben gemist, willen we het graag horen.