Network proxy path
The SDK is great when you control the agent’s code. When you don’t — a third-party tool, a browser-driven agent, an MCP server you didn’t write — the network proxy path is what you want. No code changes; just set one env var.
How it works
Section titled “How it works”- The agent’s process has
HTTPS_PROXY=http://lupid:7070in its environment. - Every outbound HTTPS request issues a
CONNECTto Lupid first. - Lupid authenticates the agent (JWT + revocation check), mints a leaf cert on the fly from its local CA, presents that cert to the agent’s TLS client.
- The agent’s TLS client trusts the cert because Lupid’s CA root is mounted into the agent’s trust store.
- Lupid sees the decrypted bytes, runs the enforcement pipeline (policy + DLP), then forwards the request upstream.
-
Make sure the agent runs inside the docker network. The HTTPS-CONNECT gateway is bound to the docker network, not the host. If your agent runs as a separate compose service, set:
services:my-agent:# ... your agent image ...environment:HTTPS_PROXY: http://lupid:7070HTTP_PROXY: http://lupid:7070networks:- lupid_defaultdepends_on:lupid:condition: service_healthynetworks:lupid_default:external: truename: lupid_default -
Mount the CA root into the agent’s trust store. The gateway generates its CA at startup and stores it in the
agentum-certsnamed volume. Mount it read-only:services:my-agent:volumes:- agentum-certs:/etc/ssl/lupid:roenvironment:# tell the agent's TLS lib where to find the CASSL_CERT_FILE: /etc/ssl/lupid/ca.crtREQUESTS_CA_BUNDLE: /etc/ssl/lupid/ca.crt # PythonNODE_EXTRA_CA_CERTS: /etc/ssl/lupid/ca.crt # Nodevolumes:agentum-certs:external: truename: lupid_agentum-certs -
Identify the agent. Set the JWT the agent presents to Lupid:
services:my-agent:environment:AGENTUM_SESSION_JWT: "eyJ0eXAi..." # from `agentum agent register`Your agent’s HTTP client needs to put this in an
Authorization: Bearerheader (orX-Agentum-Session-JWTfor rawCONNECTflows). Most LLM SDKs let you set default headers per client. -
Start the agent. Its outbound calls to OpenAI, Anthropic, etc. now go through Lupid. Watch the
/auditpage for the events.
Credential injection (the cleanest pattern)
Section titled “Credential injection (the cleanest pattern)”The proxy path supports a placeholder syntax that means the agent never sees the plaintext secret. Store the credential in the vault, then put the marker in your agent’s outbound headers:
Authorization: Bearer agentum://stripe-keyLupid sees the agentum:// prefix, resolves it to the real Stripe key via the
vault, and substitutes before the request leaves. The agent’s process has no
plaintext secret to leak.
Verifying it works
Section titled “Verifying it works”From inside the agent’s container:
curl -v https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_KEY"You should see:
- TLS certificate:
subject=CN=api.openai.com, issuer=CN=Lupid Local CA— confirms Lupid intercepted. - HTTP 200 from the upstream.
And on the dashboard’s /audit page, a tool_call event with outcome=allow (or
deny if your policy says so).
Caveats
Section titled “Caveats”- Not every HTTP client respects
HTTPS_PROXY. Java needs system properties (-Djavax.net.ssl.trustStore=). Go HTTP clients respect it. Most Python and Node libraries do. Test before you assume. - WebSockets and HTTP/2 prior knowledge connections aren’t proxied via
CONNECT. Lupid speaksCONNECTonly. - Agents outside the docker network can’t reach the gateway by default. Bridge
them in, or expose
:7070on the host (not recommended without TLS in front).