Runtime adapter stack
Crabbox can sit behind a fleet UI without teaching that UI how each provider creates, inspects, or deletes a workspace. Three crabbox adapter processes split the job into a provider lifecycle API, an authenticated browser ingress, and an optional outbound coordinator connection.
Use this stack when:
- a browser-facing service needs to create and stop Crabbox workspaces;
- the provider host should remain on loopback or behind NAT;
- browser identity and TLS terminate at an existing trusted proxy; and
- provider credentials must stay on the adapter host.
It is not a general reverse proxy, identity provider, WAF, or remote shell.
#Components
| Component | Responsibility | Network exposure |
|---|---|---|
| Fleet UI | User workflow and workspace metadata | Usually loopback behind ingress |
adapter ingress | Authenticate proxy assertions, enforce origin and route policy, sanitize headers, proxy HTTP/WebSocket traffic | Listener reachable only by the trusted proxy |
adapter serve | Authenticated, provider-neutral workspace lifecycle API | Loopback HTTP plus an optional private Unix socket |
adapter connect | Relay a narrow typed lifecycle API to a coordinator | Outbound WebSocket plus the private Unix socket |
| Provider adapter | Create, inspect, connect to, and delete the actual workspace | Local child process or configured provider API |
The fleet UI and provider adapter are deployment choices. The three adapter commands are reusable Crabbox building blocks.
#Topology
browser
|
| HTTPS
v
trusted identity-aware proxy
|
| exact identity + secret assertions
v
adapter ingress
|
| sanitized HTTP / WebSocket on loopback
v
fleet UI ---------------------> adapter serve ----------------> provider
^
| private Unix socket
|
coordinator <--- outbound WSS --- adapter connect
The browser path and coordinator path are independent. adapter ingress protects the fleet UI. adapter connect lets a coordinator reach the lifecycle API without opening an inbound route to adapter serve.
#Request paths
#Browser traffic
- The trusted proxy authenticates the browser and terminates TLS.
- The proxy sends exactly one configured identity header and one configured
adapter ingressrejects denied routes before authentication, checks the- The request reaches the loopback fleet UI. Streaming responses and valid
secret header to adapter ingress.
assertions and request origin, removes unsafe forwarding and private headers, then installs the configured upstream assertions.
WebSocket upgrades remain streaming end to end.
The proxy is responsible for user authentication and TLS. adapter ingress trusts only the configured assertion pair; it does not validate browser login sessions itself.
#Workspace lifecycle
- The fleet UI sends a bearer-authenticated request to
adapter serve. adapter servevalidates the fixed deployment policy, persists lifecycle- The provider returns a workspace identity and connection metadata.
- Later reads and deletes resolve the persisted workspace record rather than
state, and invokes the configured provider.
accepting arbitrary provider commands from the request.
The API exposes workspace operations, not shell commands, argv, environment, files, or provider credentials. Keep the bearer token between the fleet UI and adapter serve private.
#Outbound coordinator control
adapter connectauthenticates to the coordinator using normal Crabbox- It opens an outbound WebSocket and accepts only the documented typed
- Each operation is forwarded through the verified, current-user-owned Unix
- The local token, remote cookies, and proxy credentials never cross the
configuration and obtains a short-lived relay ticket. A new adapter ID starts with a ten-minute provisional owner/org claim; agent connection or successful lease registration makes it durable. Only expired inactive provisional claims are recoverable, and existing adapter claims remain durable across upgrades.
workspace operations.
socket to adapter serve with the local bearer token.
relay.
The relay is optional. Omit it when only the local fleet UI needs lifecycle access.
#Trust boundaries
| Boundary | Required proof | Keep private |
|---|---|---|
| Browser to trusted proxy | Deployment-specific user authentication | Browser session |
Trusted proxy to adapter ingress | Exact identity assertion, exact secret assertion, exact public origin | Proxy secret and assertion policy |
Fleet UI to adapter serve | Bearer token from the private token file | Adapter bearer token |
adapter connect to local adapter | Unix-socket owner, mode, peer UID, and bearer token | Socket and adapter bearer token |
adapter connect to coordinator | Normal Crabbox login or token command, then short-lived relay ticket | Coordinator credential |
adapter serve to provider | Deployment-owned provider configuration | Provider credentials and lifecycle state |
Do not reuse one secret across boundaries. In particular, the proxy secret, adapter bearer token, and coordinator credential serve different principals and rotation paths.
#Configuration and rotation
- Keep the
adapter servetoken, state, and Unix-socket parent in - Keep the
adapter ingressJSON config and secret as current-user-owned - Use one literal listener IP, one exact loopback HTTP upstream, and one exact
- Bind the fleet UI and
adapter serveto loopback. The trusted proxy should be - Restart
adapter ingressafter rotating its config or proxy secret; both are adapter connectreloads normal Crabbox config and its local token file when
current-user-owned private paths.
regular files with mode 0400 or 0600.
non-loopback HTTPS public origin for ingress.
the only peer that can reach the ingress listener.
loaded when the process starts.
reconnecting. It also reloads the local token before each forwarded request.
#Start and stop order
Recommended startup:
- Start
adapter serveand wait for its loopback health check. - Start the fleet UI and verify it can reach the lifecycle API.
- Start
adapter ingressbehind the trusted proxy. - Optionally start
adapter connectand verify coordinator registration. - Expose the trusted proxy route only after every required health check passes.
Shutdown in reverse. Remove or disable the public proxy route first, stop the outbound connector, stop the fleet UI, then stop adapter serve. This prevents new browser or coordinator work from arriving while lifecycle state is being quiesced.
#Health and failure signals
| Signal | Meaning |
|---|---|
adapter serve /healthz succeeds | Lifecycle process is serving; it does not prove every provider operation will succeed |
Loopback adapter ingress /healthz succeeds | Ingress can reach the upstream health endpoint |
401 from ingress | Missing, duplicate, or incorrect proxy assertions |
403 from ingress | Request origin does not exactly match the configured public origin |
404 from ingress | Route is denied, or a non-loopback peer requested /healthz |
502 from ingress | The loopback upstream is unavailable or failed during proxying |
| Connector reconnect loop | Coordinator, local socket, local token, or coordinator authentication is unavailable |
Treat a healthy process as one layer of evidence, not proof of the full path. For a deployment smoke test, verify an authenticated browser request, one workspace lifecycle operation, and the outbound coordinator path when enabled.
#Related reference
adaptercommand: complete flags, config schema,- Broker auth and routing: coordinator and portal
- Security: repository-wide trust and secret boundaries.
API, relay protocol, and file-safety requirements.
authentication models.