How a request flows
Say one of your agents is about to call OpenAI. Here’s what actually happens.
-
The agent sends an HTTPS
CONNECTto the Lupid gateway on:7070because itsHTTPS_PROXYis pointed at Lupid (or, on the SDK path, the SDK’sfetchinterceptor routes the request internally). -
Lupid authenticates the agent. It verifies the JWT signature, checks the token’s not on the revocation blocklist (a bloom-filtered Postgres-backed list refreshed via LISTEN/NOTIFY), and binds the session to the agent’s network context.
-
TLS is intercepted. The gateway mints a leaf certificate on the fly from its local CA and presents it to the agent. The agent talks TLS to Lupid; Lupid talks TLS to OpenAI. From the agent’s perspective the trust chain ends at Lupid’s CA, which the agent’s container trusts via a mounted root.
-
The request body is classified. DLP scans the prompt for 17 detector kinds (emails, phone numbers, SSNs, credit cards, AWS / OpenAI / Anthropic / GitHub / Slack tokens, JWTs, bearer tokens, PEM private keys, and high-entropy generic secrets). Hits become
data_classeson the eventual audit row. -
The policy engine evaluates
(principal=agent, action=call_tool, resource=tool_name)and returnsallow,deny, orrequire_hitl. The decision is served from an in-memory cache, but the exact latency is implementation detail you shouldn’t depend on. -
Optional HITL gate. If the policy emitted
@advice("require_hitl:…"), the request parks in the approval queue, an HMAC-signed webhook fires to any URL the operator has configured, and the agent either blocks (synchronous wait) or gets a202with a poll URL. -
The request is proxied upstream. The response streams back through the same pipeline. DLP can redact secrets on the way out too — useful when the LLM has echoed a system-prompt fragment that contained credentials.
-
An audit event is written. One row in Postgres (or ClickHouse, if you enabled the audit profile) with: agent id, tool, resource, decision, the policy hash that was evaluated against, data classes detected, redactions applied, and chunk hashes of the prompt and response.
When the chain breaks
Section titled “When the chain breaks”| Step that failed | What the agent sees | What lands in audit |
|---|---|---|
| JWT invalid or revoked | HTTP 401 | auth_failed event |
Policy returns deny | HTTP 403 with the policy id | policy_denied event |
| DLP severity ≥ critical (block) | The request is dropped; agent sees a 403 | dlp_blocked event + finding list |
| HITL approver said deny | HTTP 403 (sync mode) or the poll returns deny | hitl_denied event |
| Upstream LLM returned 5xx | The 5xx is forwarded to the agent transparently | upstream_error event |
Every event has a stable schema; you can query them from the dashboard’s audit page
or via agentum audit query from the CLI.