Gateway-lifecycle SANDBOX CAPABILITY: ONE shared loopback egress proxy and ONE ephemeral MITM CA for the WHOLE daemon, keyed PER SESSION.
Why shared, not per-session (turn 32): the gateway is multi-tenant — many clients/sessions hit one daemon. A per-session proxy+CA thrashes listeners and mints a fresh CA per session; worse, every child would carry a different trust root. Instead there is ONE listener and ONE CA (the "same certs" property — every child trusts the same root), plus a REGISTRY mapping a per-session TOKEN → that session's live policy fn.
How a connection is attributed to a session: the jailed child's proxy env carries
its unguessable token in the proxy URL userinfo
(http://<token>:vis@127.0.0.1:<port>); curl/git/requests/… send it back as
Proxy-Authorization: Basic base64(<token>:vis) and the password is ignored;
the proxy hands the token to resolve-policy, which looks up the registry.
FAIL-CLOSED: a request whose token is missing or not registered to a LIVE session
is DENIED (a :deny-all? sentinel policy) — the shared door never serves a policy
it cannot attribute. The token is a random UUID, so one session cannot reach
another's (broader) policy by guessing.
Lazy: the proxy listener and the CA keygen happen only on first ensure-proxy! /
ensure-ca! — a gateway that never jails a shell child opens neither.
Gateway-lifecycle SANDBOX CAPABILITY: ONE shared loopback egress proxy and ONE ephemeral MITM CA for the WHOLE daemon, keyed PER SESSION. Why shared, not per-session (turn 32): the gateway is multi-tenant — many clients/sessions hit one daemon. A per-session proxy+CA thrashes listeners and mints a fresh CA per session; worse, every child would carry a different trust root. Instead there is ONE listener and ONE CA (the "same certs" property — every child trusts the same root), plus a REGISTRY mapping a per-session TOKEN → that session's live policy fn. How a connection is attributed to a session: the jailed child's proxy env carries its unguessable token in the proxy URL userinfo (`http://<token>:vis@127.0.0.1:<port>`); curl/git/requests/… send it back as `Proxy-Authorization: Basic base64(<token>:vis)` and the password is ignored; the proxy hands the token to `resolve-policy`, which looks up the registry. FAIL-CLOSED: a request whose token is missing or not registered to a LIVE session is DENIED (a `:deny-all?` sentinel policy) — the shared door never serves a policy it cannot attribute. The token is a random UUID, so one session cannot reach another's (broader) policy by guessing. Lazy: the proxy listener and the CA keygen happen only on first `ensure-proxy!` / `ensure-ca!` — a gateway that never jails a shell child opens neither.
(ensure-ca!)Lazily create the ONE shared ephemeral MITM CA. Returns its PEM path.
Lazily create the ONE shared ephemeral MITM CA. Returns its PEM path.
(ensure-java-trust!)Return the shared CA's ephemeral PKCS12 truststore credentials for managed JVM children. The store is deleted with the gateway capability.
Return the shared CA's ephemeral PKCS12 truststore credentials for managed JVM children. The store is deleted with the gateway capability.
(ensure-proxy!)Lazily start the ONE shared loopback egress proxy bound to the token-keyed resolver + the shared CA. Returns its port. Idempotent + thread-safe.
Lazily start the ONE shared loopback egress proxy bound to the token-keyed resolver + the shared CA. Returns its port. Idempotent + thread-safe.
(ensure-session-proxy! token owner)Give token of session owner a session-attributed compatibility front door for
managed language processes whose HTTP stacks do not reliably send Proxy-Authorization
from URL userinfo (notably urllib and JVM dependency resolvers). The listener is bound
to loopback, resolves exactly token's live policy, and shares the gateway CA and
proxy implementation. Unknown/disposed sessions fail closed. Returns its port, or nil
when every reserved front door has another owner.
A door has one owner for the gateway's life: a new environment of the same session gets it again, and a process that outlives its session never finds another session on its port. While two environments of the session live, the door serves the newer.
Give `token` of session `owner` a session-attributed compatibility front door for managed language processes whose HTTP stacks do not reliably send Proxy-Authorization from URL userinfo (notably urllib and JVM dependency resolvers). The listener is bound to loopback, resolves exactly `token`'s live policy, and shares the gateway CA and proxy implementation. Unknown/disposed sessions fail closed. Returns its port, or nil when every reserved front door has another owner. A door has one owner for the gateway's life: a new environment of the same session gets it again, and a process that outlives its session never finds another session on its port. While two environments of the session live, the door serves the newer.
(jailed-peer? server-port peer-port)True when a jailed child of any Vis process opened the loopback connection from
peer-port to the gateway API on server-port. A child of this process cannot connect
at all. False when the runtime cannot tell, so local clients keep their gateway.
True when a jailed child of any Vis process opened the loopback connection from `peer-port` to the gateway API on `server-port`. A child of this process cannot connect at all. False when the runtime cannot tell, so local clients keep their gateway.
(loopback-grant network-policy)Jail policy keys that let a confined child connect to loopback directly, or nil
(#469). Granted only when network-policy already passes all loopback traffic
through the proxy. The deny list holds every gateway port a child must never reach:
the control plane, the shared proxy and each front door, also one that a later
session takes, because all front doors are reserved before the list is read.
Jail policy keys that let a confined child connect to loopback directly, or nil (#469). Granted only when `network-policy` already passes all loopback traffic through the proxy. The deny list holds every gateway port a child must never reach: the control plane, the shared proxy and each front door, also one that a later session takes, because all front doors are reserved before the list is read.
(proxy-port)The running shared proxy's port, or nil if it was never started.
The running shared proxy's port, or nil if it was never started.
(register-session! token policy-fn)Register policy-fn (0-arg → the session's compiled policy value or nil) under
token. The shared proxy resolves this session's policy from here per request.
Register `policy-fn` (0-arg → the session's compiled policy value or nil) under `token`. The shared proxy resolves this session's policy from here per request.
(registered? token)True when token maps to a live session policy fn.
True when `token` maps to a live session policy fn.
(resolve-policy token)Token-keyed resolver handed to the shared proxy's :policy-fn. Returns the
session's compiled policy, or a :deny-all? sentinel when the token is absent or
unregistered (FAIL-CLOSED — an unattributable request reaches nothing).
Token-keyed resolver handed to the shared proxy's `:policy-fn`. Returns the session's compiled policy, or a `:deny-all?` sentinel when the token is absent or unregistered (FAIL-CLOSED — an unattributable request reaches nothing).
(set-reserved-ports! ports)Register loopback ports a jailed child must never reach (the gateway's own control plane) even though loopback is allowed by default. The shared proxy's own port is reserved automatically. Idempotent.
Register loopback ports a jailed child must never reach (the gateway's own control plane) even though loopback is allowed by default. The shared proxy's own port is reserved automatically. Idempotent.
(shutdown!)Stop every gateway proxy listener, delete the shared ephemeral trust files, and clear all session policy state. Idempotent.
Stop every gateway proxy listener, delete the shared ephemeral trust files, and clear all session policy state. Idempotent.
(unregister-session! token)Drop a session's policy. Its optional session front door then serves the newest other live token of the same session, or refuses every request until that session registers again; no other session gets it. Idempotent; the shared proxy + CA remain gateway-owned.
Drop a session's policy. Its optional session front door then serves the newest other live token of the same session, or refuses every request until that session registers again; no other session gets it. Idempotent; the shared proxy + CA remain gateway-owned.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |