The request path
Updated July 22, 2026
Hangar is a proxy. A client’s tools/call goes in one side, the upstream MCP
server’s result comes back the other, and every control Hangar enforces gets its
turn on the same path the call already travels. There is no side channel and no
background pass. Governance is whatever fires between the client and the upstream,
in order, synchronously, on the way through.
This page is that path, drawn once. Open a stage to read what fires there — the explanations live inside the diagram, in the order the call meets them.
ClientClient / agentA tools/call arrives, carrying a token.
A tool call enters carrying a token. Nothing about it is trusted yet.
Enforcement seam · the Hangar proxy
IdentityThe front door resolves the caller to a tenant and a principal.unauthenticated: rejected here
The front door authenticates the caller and resolves it to a tenant and principal. This binding is what every later control keys off. An unauthenticated caller never reaches stage 2 — it is rejected at the door.
ContractThe tool-schema digest pinned for this caller is verified.drift fails closed
The call is checked against the tool-schema digest pinned for the exact contract the caller was authorized for — resolved at invoke time from the tool-projection registry. If the upstream tool has drifted from that pinned digest, the path fails closed rather than invoke a contract nobody signed off on.
Egress policy (L7)Tool-name globs and an argument scan produce the verdict.deny always winsaudit is the default
This is the semantic gate. Tool names are matched by glob in a fixed precedence — deny beats requireApproval beats allow beats the policy’s default action — and arguments are scanned for configured secret patterns and an oversized payload. A secret or an outsized payload denies the call even when the tool name is allowed: deny always wins.
requireApprovalis a hard gate — the call is blocked pending out-of-band approval. It is enforcement, not an interactive queue; the request stops, it does not hang waiting for a click.Whether this stage blocks at all is opt-in. A policy’s
spec.modedefaults toAudit— every verdict above is computed and recorded, but nothing is refused; the seam observes. Only undermode: Enforcedo deny andrequireApprovalactually stop the call. The blocking picture on this page is the Enforce-mode picture; Audit is the adoption path you start on.Network · L3/L4The network backstopNetworkPolicy or Cilium — the seam cannot be bypassed.no backstop: fails closed
Underneath the L7 seam, the operator compiles the same policy into a
NetworkPolicy(or aCiliumNetworkPolicyfor FQDN upstreams) that default-denies the server’s egress to everything but the allow-listed hosts. This is the layer that makes the whole path enforcement rather than a suggestion: a policy without the backstop is bypassable, and Hangar fails it closed rather than open when the backstop can’t be applied.UpstreamUpstream MCP serverAllowed calls are relayed untouched. The upstream owns the work.
Only an allowed, in-contract call arrives here, relayed untouched. Hangar does not run the work — it relays and governs. The upstream owns execution.
ResponseThe return tripResult → redact secrets → audit → client.
The result comes back up the same seam: output is scanned and secret values are redacted, reusing the redactor’s deterministic value-patterns — the same ones argument scanning refuses on the way in, plus one inbound-only PEM addition the redactor does not carry — and the governed result is recorded as a governance event. So most of what the redactor masks on the way out is what a policy refuses on the way in — largely one set of rules, both directions. (A call the policy denies raises
EgressPolicyDeniedErrorbefore it reaches the wire, short-circuiting this return trip.)
Every verdict is deterministic — no scores, no heuristics — and recorded as an attributed governance event.
Why it’s drawn as one line
Every control lives on the call path and nowhere else. There is no anomaly score being computed in the background, no separate policy engine the request detours through, no asynchronous approval the call waits on. The verdicts are deterministic functions of the request, the pinned contract, and the policy — which is what makes the path auditable: the same inputs always produce the same verdict, and every verdict leaves a line in the chain. Governance is credible here precisely because it is thin. It binds where the call already flows, and the call flows through exactly one seam.
Grounded in ADR-013 (the egress
enforcement model) and the MCPEgressPolicy guide. Everything is MIT and
self-hosted — no SaaS tier.