pip install. The Gateway needs a base URL you can
change. The egress node needs neither, which makes it the answer to the
two workloads every security team eventually finds: the Go binary
nobody documented, and the vendor container you cannot open.
It is a forward proxy you run on your own network. Point a workload at
it with the environment variables it already understands and every
model call it makes shows up in EgisAI.
Setting one up
Mint a workload token under Connect → Egress, then run the container on the network your agents already use:Two modes
Observe is the default and the mode to leave it in for a while. It tunnels every connection without opening it, and reports the destination only. That turns “4,000 connections to 172.64.x.x” into “this workload is talking to Anthropic” without the node ever being able to read a request. Rows written in observe mode carryenforcement_status = "advisory"
and inspection = "metadata_only", because a node that never opened
the tunnel did not gate anything and could not have read anything.
Enforce lets the node refuse a call that breaks a policy. To do
that it has to read what was sent, so it terminates TLS — for model
vendors only. Everything else your workloads talk to stays a tunnel
it cannot see into.
What enforce mode requires
The node generates its own certificate authority on first start. The private key is written with0600 permissions and never leaves the
node — not to us, not to another node in the same fleet.
Workloads have to trust that CA before they can talk to a model vendor
through an enforcing node. A workload that doesn’t will fail its
handshake to those vendors rather than quietly going ungoverned, and
the errors show up on the Egress page.
The dashboard shows the CA’s SHA-256 fingerprint next to each node.
Check it against the node itself before you distribute anything:
Streaming
When no response-phase policy is active the node streams the response straight through, so first-token latency is unchanged. When one is, the response is buffered, evaluated, and then released or refused — which is the only way a response policy can mean anything, and is the reason to keep response-phase rules narrow.Running the SDK and a node together
They co-exist without double-governing. The SDK stampsX-Egis-Decision: governed on requests it has already evaluated, and
the node skips those — one call, one audit row, whichever control saw
it first.
Failure posture
Fail open, loudly. If the node cannot reach the control plane it keeps forwarding traffic and queues what it saw; if it cannot evaluate a policy it forwards rather than refusing. A governance product that takes a customer’s product down when our backend has a bad day is not a governance product anybody keeps. The one exception is the handshake in enforce mode, which fails closed by construction: a workload that does not trust the node’s CA cannot reach the vendor at all.Forced proxy: forward every AI app to Egis
Enforce mode governs on the node. Forward-to-Egis mode turns the node into a forward proxy for a whole device fleet: it intercepts the call, keeps it in its native provider shape (OpenAI, Anthropic Messages, GooglegenerateContent), and hands it to the Egis Gateway,
which runs the full policy engine, attributes an owner, forwards to the
real provider, and returns the response. One governance engine across
the SDK, the Gateway, and the proxy — no drift, and nothing to
configure per app.
Turn it on with one setting (EGIS_FORWARD_TARGET=egis) or by pushing
a managed config to the fleet.
The privacy posture
In forward mode the raw prompt transits the Egis endpoint you choose. Point it at our cloud for convenience, or setEGIS_GATEWAY_URL to a
self-hosted backend so nothing leaves the building. The code path
is identical; only the destination changes.
Fail-open holds: if the Gateway is unreachable the node drops to local
governance and a direct vendor connection, so your product never goes
down because governance had a bad day. PII detection stays local, so
this fail-open never lets raw PII through.
The name-constrained CA
The node’s CA carries a critical X.509NameConstraints extension that
boxes it to AI-vendor domains (openai.com, anthropic.com,
googleapis.com, …). A leaked copy of the key cannot impersonate a
bank, an IdP, or an email host — a compliant client refuses any chain
outside that list. This is the control a security team reads before
distributing the certificate fleet-wide.
Automatic owner attribution
Your MDM templates each employee’s identity into the managed config aspersonEmail: ${user_email}. The node stamps it on every forwarded
call, and the Gateway resolves it to a workspace user, so proxied
agents appear on the dashboard with owners already attached — the
same automatic attribution as the API-key path, at fleet scale.
MDM setup (Intune / Jamf)
Push three things to the device group:- A trusted-certificate profile carrying the node’s name-constrained CA (its fingerprint is shown on the Egress page).
- A proxy / PAC profile pointing the fleet at the node.
- The managed config below (the schema ships at
managed-schema.jsonin the egress package):
The certificate-pinning caveat
Some desktop apps pin their provider certificate. The node cannot read a pinned connection — the handshake fails visibly on the node’s row rather than downgrading silently. The right response is to allow-list the app (see it, don’t read it) or block it, never to weaken the trust store. HTTP/2 and gRPC interception are out of scope today.What’s next
Coverage
Where this fits among the five surfaces.
Gateway
The in-line alternative when you can change a base URL.