Skip to content

Commit 8392047

Browse files
committed
docs(rfc): clarify relay flow diagram
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
1 parent 26a29a2 commit 8392047

1 file changed

Lines changed: 47 additions & 39 deletions

File tree

  • rfc/0005-sandbox-proxy-egress-adapter

rfc/0005-sandbox-proxy-egress-adapter/README.md

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -182,57 +182,65 @@ adapter renders it for its protocol.
182182
```mermaid
183183
flowchart TD
184184
Start["Authorized egress + destination connector"]
185-
Start --> FirstReq{"Forward HTTP adapter supplied first request?"}
185+
Start --> FirstReq{"Forward HTTP adapter<br/>already has first request?"}
186186
187-
FirstReq -- Yes --> ForwardMode{"decision.endpoint.enforcement"}
188-
ForwardMode -- "None" --> HttpCred["HTTP relay<br/>credential injection only"]
189-
ForwardMode -- "Http" --> HttpL7["HTTP relay<br/>REST/GraphQL/JSON-RPC/MCP/WebSocket policy"]
190-
ForwardMode -- "ProtocolProcessor" --> BadForward["Deny: HTTP request for native protocol endpoint"]
187+
FirstReq -- Yes --> ForwardEnforcement{"Endpoint enforcement"}
188+
ForwardEnforcement -- "None or HTTP" --> HttpReq["Parsed HTTP request"]
189+
ForwardEnforcement -- "Protocol processor" --> BadForward["Deny: HTTP request for native protocol endpoint"]
191190
192-
FirstReq -- No --> TlsPolicy{"TLS handling skipped?"}
193-
TlsPolicy -- Yes --> Readable["Readable client stream"]
194-
TlsPolicy -- No --> Peek["Peek client bytes"]
191+
FirstReq -- No --> Prepare["Prepare readable client stream"]
192+
Prepare --> TlsPolicy{"TLS handling enabled?"}
193+
TlsPolicy -- No --> Readable["Client stream"]
194+
TlsPolicy -- Yes --> Peek["Peek client bytes"]
195195
Peek --> Tls{"TLS ClientHello?"}
196196
Tls -- Yes --> Terminate["Shared TLS terminator"]
197197
Tls -- No --> Readable
198198
Terminate --> Readable
199199
200-
Readable --> Enforce{"decision.endpoint.enforcement"}
201-
Enforce -- "None" --> Sniff{"Looks like HTTP?"}
202-
Sniff -- Yes --> HttpCred
203-
Sniff -- No --> TcpRelay["TcpRelay<br/>byte copy"]
200+
Readable --> Enforce{"Endpoint enforcement"}
201+
Enforce -- "None" --> Sniff{"HTTP request detected?"}
202+
Sniff -- Yes --> ParseHttp["Parse HTTP request"]
203+
Sniff -- No --> TcpRelay["TcpRelay<br/>connect upstream and copy bytes"]
204+
ParseHttp --> HttpReq
204205
205-
Enforce -- "Http" --> MustHttp{"Looks like HTTP?"}
206-
MustHttp -- Yes --> HttpL7
206+
Enforce -- "HTTP" --> MustHttp{"HTTP request detected?"}
207+
MustHttp -- Yes --> ParseHttp
207208
MustHttp -- No --> DenyHttp["Deny: expected HTTP"]
208209
209-
Enforce -- "ProtocolProcessor" --> Processor["TcpRelay<br/>protocol processor owns loop"]
210-
211-
HttpCred --> ReqLoop["HTTP request loop"]
212-
HttpL7 --> ReqLoop
213-
ReqLoop --> ReqPolicy{"Request allowed?"}
214-
ReqPolicy -- No --> ReqDeny["Local HTTP deny<br/>no upstream write"]
215-
ReqPolicy -- Yes --> Middleware{"Supervisor middleware chain configured?"}
216-
Middleware -- Yes --> MwEval["Evaluate HTTP_REQUEST / PRE_CREDENTIALS<br/>allow, deny, or mutate"]
217-
Middleware -- No --> StaticCreds["Resolve static placeholders"]
218-
MwEval --> MwAllowed{"Middleware allowed?"}
219-
MwAllowed -- No --> MwDeny["Local middleware deny<br/>no credential injection"]
220-
MwAllowed -- Yes --> StaticCreds
221-
StaticCreds --> TokenGrant["Apply endpoint token grant if configured"]
222-
TokenGrant --> Rewrite["Rewrite configured credential slots"]
223-
Rewrite --> HttpDial["Connect or reuse upstream"]
224-
HttpDial --> HttpResponse["Write request and relay response"]
225-
HttpResponse --> Upgrade{"101 WebSocket upgrade?"}
226-
Upgrade -- No --> ReqLoop
227-
Upgrade -- Yes --> WsInspect{"WebSocket inspection or rewrite configured?"}
228-
WsInspect -- No --> RawUpgrade["Raw upgraded stream"]
229-
WsInspect -- Yes --> WsRelay["WebSocket relay<br/>text-frame rewrite / message policy"]
230-
231-
Processor --> ProcessorDial["Processor calls connector when protocol allows"]
232-
TcpRelay --> TcpDial["Connect upstream"]
233-
TcpDial --> ByteCopy["Copy bytes"]
210+
Enforce -- "Protocol processor" --> Processor["TcpRelay hands stream to protocol processor"]
211+
Processor --> ProcessorOwns["Processor owns message loop<br/>and calls connector when allowed"]
212+
213+
subgraph HttpLoop["HTTP relay request loop"]
214+
HttpReq --> HttpMode{"HTTP endpoint policy?"}
215+
HttpMode -- "L4-only HTTP" --> ReqAllowed["Request admitted by connection decision"]
216+
HttpMode -- "REST / GraphQL / JSON-RPC / MCP / WebSocket" --> ReqPolicy{"Request policy allowed?"}
217+
ReqPolicy -- No --> ReqDeny["Local HTTP deny<br/>no upstream write"]
218+
ReqPolicy -- Yes --> ReqAllowed
219+
ReqAllowed --> Middleware{"Supervisor middleware<br/>configured?"}
220+
Middleware -- Yes --> MwEval["Run HTTP_REQUEST / PRE_CREDENTIALS middleware"]
221+
Middleware -- No --> Creds["Resolve static placeholders<br/>and token grants"]
222+
MwEval --> MwAllowed{"Middleware allowed?"}
223+
MwAllowed -- No --> MwDeny["Local middleware deny<br/>no credential injection"]
224+
MwAllowed -- Yes --> Creds
225+
Creds --> Rewrite["Inject credentials into configured slots"]
226+
Rewrite --> HttpDial["Connect or reuse upstream"]
227+
HttpDial --> HttpResponse["Write request and relay response"]
228+
HttpResponse --> Upgrade{"101 WebSocket upgrade?"}
229+
Upgrade -- No --> NextReq{"Another HTTP request<br/>on this connection?"}
230+
NextReq -- Yes --> HttpReq
231+
NextReq -- No --> Done["HTTP relay done"]
232+
Upgrade -- Yes --> WsInspect{"WebSocket inspection<br/>or rewrite configured?"}
233+
WsInspect -- No --> RawUpgrade["Raw upgraded stream"]
234+
WsInspect -- Yes --> WsRelay["WebSocket relay<br/>text-frame rewrite / message policy"]
235+
end
234236
```
235237

238+
Read this as two phases. The top half chooses the relay shape from the adapter
239+
surface and endpoint enforcement. The `HTTP relay request loop` only receives a
240+
parsed HTTP request. Supervisor middleware is not another policy funnel; it is
241+
an optional request-path hook after HTTP policy allows the request and before
242+
OpenShell-managed credential injection.
243+
236244
Relay rules:
237245

238246
- HTTP credential injection happens in both HTTP modes: L4-only HTTP and

0 commit comments

Comments
 (0)