Skip to content

Commit 26a29a2

Browse files
committed
docs(rfc): make process identity optional
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
1 parent 25da561 commit 26a29a2

4 files changed

Lines changed: 79 additions & 10 deletions

File tree

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

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ enforcement contracts.
9292
policy evaluation.
9393
2. **Egress intent and decision.** Shared authorization evaluates L4 policy and
9494
endpoint selection once per connection intent and returns one decision
95-
containing the matched policy, matched endpoint, process identity, allowed
96-
IP metadata, TLS behavior, protocol enforcement, and credential injection
97-
and middleware plans.
95+
containing the matched policy, matched endpoint, optional process identity
96+
evidence used for evaluation, allowed IP metadata, TLS behavior, protocol
97+
enforcement, and credential injection and middleware plans.
9898
3. **Relays.** Relays receive an authorized destination connector, not an
9999
already-open upstream socket. HTTP relays evaluate every request before
100100
upstream write. TCP relays copy bytes for L4-only endpoints or hand the
@@ -342,6 +342,18 @@ If supervisor middleware is configured, the proxy runtime must also receive the
342342
effective middleware service registry, validate/refresh bindings, enforce
343343
`fail_open` and `fail_closed`, buffer within configured caps, invoke middleware
344344
on the request path, and emit middleware OCSF events.
345+
346+
Process identity is mode-dependent. Embedded supervisor mode can usually
347+
resolve the workload process, binary, and ancestors. Network-only, standalone,
348+
and sidecar modes may intentionally have no local process identity. In those
349+
modes the adapter should pass an explicit unavailable identity envelope, and
350+
the decision should record identity as unavailable rather than treating it as
351+
an accidental lookup failure. Authorization must not turn a missing identity
352+
into a broader allow. Process-scoped predicates should either be treated as
353+
non-matching for that runtime or rejected during policy/capability validation.
354+
Policies that require binary/path scoping need an explicit capability check or
355+
fallback rule before they are allowed to run in identity-less modes.
356+
345357
The nftables rules that force or reject userland traffic belong to the sandbox
346358
network boundary even if the proxy process later moves into a standalone binary
347359
or sidecar.
@@ -376,7 +388,9 @@ The intended order is:
376388
endpoints. Failures should remain fail-closed and sanitized.
377389
- Transparent TCP capture adds network namespace interception complexity and
378390
must coexist with the nftables bypass reject/log table.
379-
- Sidecar mode needs a reliable identity source for binary/path scoped policy.
391+
- Sidecar mode may intentionally lack process identity. Binary/path scoped
392+
policy needs a reliable identity source or must be rejected/ignored for that
393+
deployment mode.
380394
- Metadata loopback and `policy.local` expand sandbox-local control surfaces
381395
and need strict route validation, body limits, redaction, and authentication
382396
boundaries.
@@ -436,8 +450,8 @@ adapter wire middleware separately.
436450
2. Should direct IP connects to a policy-DNS-resolved TCP endpoint be accepted,
437451
or should DNS query correlation be required for stricter modes?
438452
3. What TTL cap and stale-generation grace period should policy DNS use?
439-
4. Which process identity source should sidecar mode use when it cannot inspect
440-
payload process metadata through local `/proc`?
453+
4. Which policy features should be disabled, rejected, or treated as
454+
non-matching when the proxy runtime advertises no process identity support?
441455
5. Which proxy capabilities should be negotiated with the gateway at startup?
442456
6. Should metadata loopback be modeled as an adapter inside
443457
`openshell-supervisor-network`, or remain orchestrated by `openshell-sandbox`

rfc/0005-sandbox-proxy-egress-adapter/current-shape.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ routes, identity cache, provider credential injection, and token grants.
3939
helpers, nftables bypass rules, and the bypass monitor that turns nftables LOG
4040
entries into OCSF events.
4141

42+
In embedded supervisor mode, the network leaf can usually use process metadata
43+
resolved by the process/orchestrator side for binary-scoped policy and OCSF
44+
context. Future network-only, standalone, or sidecar proxy modes may
45+
intentionally lack that metadata. The adapter model should preserve this as an
46+
explicit "identity unavailable" state rather than fabricating an empty binary
47+
identity.
48+
4249
## Current Userland-Facing Surfaces
4350

4451
The networking surface currently includes:

rfc/0005-sandbox-proxy-egress-adapter/implementation-plan.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ direction-focused.
1414
paths.
1515
- Add tests for exact declared private endpoint trust and `allowed_ips`
1616
behavior across CONNECT and forward HTTP.
17+
- Add tests for identity-less runtime modes where process identity is
18+
intentionally unavailable and binary/path scoped policy does not
19+
accidentally match.
1720
- Add tests proving static credential injection works in L4-only HTTP and
1821
HTTP-inspected paths.
1922
- Add tests proving token grant success injects the configured header and token
@@ -42,6 +45,9 @@ direction-focused.
4245
local-service internal.
4346
- Include protocol enforcement, supervisor middleware, and credential injection
4447
plans on the decision.
48+
- Include process identity availability and fields used on the decision. Treat
49+
missing process identity as an explicit runtime mode, not as an implicit
50+
lookup failure.
4551
- Fail closed when required endpoint metadata cannot be materialized.
4652
- Emit consistent OCSF network denial events from the shared boundary.
4753

@@ -144,7 +150,10 @@ direction-focused.
144150
configured listeners, policy updates, provider credentials, token grants,
145151
supervisor middleware registry, gateway calls, telemetry, denial/activity
146152
events, and shutdown.
147-
- Identify process identity requirements for standalone and sidecar modes.
153+
- Advertise process identity capability for embedded, network-only,
154+
standalone, and sidecar modes. Reject policies that require unavailable
155+
identity dimensions, or define those predicates as non-matching for the
156+
runtime mode.
148157
- Add capability negotiation with the gateway if standalone proxy versions can
149158
differ from gateway versions.
150159

@@ -164,6 +173,7 @@ direction-focused.
164173
- Unit-test authorization precedence for overlapping policy and endpoint rules.
165174
- Unit-test provider-derived rule namespace handling and `policy.local`
166175
filtering.
176+
- Unit-test identity-available and identity-unavailable authorization inputs.
167177
- Integration-test shared destination validation across CONNECT, forward HTTP,
168178
and transparent TCP.
169179
- Integration-test HTTP keep-alive and pipelined requests with REST, GraphQL,

rfc/0005-sandbox-proxy-egress-adapter/technical-design.md

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ It should carry:
2727
- entry transport: CONNECT, forward HTTP, transparent TCP, local HTTP, policy
2828
DNS, or metadata loopback;
2929
- requested destination host/port or captured original IP/port;
30-
- process identity inputs collected by the adapter/runtime;
30+
- optional process identity inputs collected by the adapter/runtime;
3131
- optional first HTTP request for forward proxy traffic;
3232
- optional local service route;
3333
- policy generation or DNS mapping generation when relevant.
@@ -46,7 +46,7 @@ It should carry:
4646
- whether the policy is user-authored, provider-derived, or local-service
4747
internal;
4848
- deterministic matched endpoint identifier and endpoint metadata;
49-
- process identity used for evaluation;
49+
- process identity availability and any identity fields used for evaluation;
5050
- destination and allowed IP constraints;
5151
- TLS behavior;
5252
- protocol enforcement;
@@ -94,7 +94,7 @@ enum EgressTransport {
9494
struct EgressIntent {
9595
transport: EgressTransport,
9696
destination: RequestedDestination,
97-
process: ProcessIdentity,
97+
process: ProcessIdentityEvidence,
9898
first_request: Option<ParsedHttpRequest>,
9999
local_route: Option<LocalRoute>,
100100
generation: Option<PolicyGeneration>,
@@ -104,10 +104,27 @@ struct EgressDecision {
104104
outcome: PolicyOutcome,
105105
matched_policy: Option<MatchedPolicy>,
106106
endpoint: Option<MatchedEndpoint>,
107+
process: EvaluatedProcessIdentity,
107108
request_processing: RequestProcessingPlan,
108109
log_context: EgressLogContext,
109110
}
110111

112+
enum ProcessIdentityEvidence {
113+
Available(ProcessIdentity),
114+
Unavailable(ProcessIdentityUnavailableReason),
115+
}
116+
117+
enum ProcessIdentityUnavailableReason {
118+
RuntimeMode,
119+
UnsupportedAdapter,
120+
LookupFailed,
121+
}
122+
123+
struct EvaluatedProcessIdentity {
124+
evidence: ProcessIdentityEvidence,
125+
fields_used: Vec<ProcessIdentityField>,
126+
}
127+
111128
struct MatchedPolicy {
112129
id: PolicyId,
113130
source: PolicySource,
@@ -213,6 +230,27 @@ struct RelayContext {
213230
validated destination and lets relays/processors open an upstream connection
214231
only after protocol policy allows it.
215232

233+
## Process Identity Availability
234+
235+
Process identity is evidence, not an always-present input. Embedded supervisor
236+
mode can usually populate binary, PID, ancestry, command-line path, and binary
237+
hash data. Network-only, standalone binary, or sidecar proxy modes may
238+
intentionally have no local process metadata. That should be represented as
239+
`ProcessIdentityEvidence::Unavailable(RuntimeMode)`, not as an empty string
240+
that accidentally matches policy.
241+
242+
Authorization should evaluate only identity dimensions that are available. If
243+
no identity is available, binary/path scoped policy should either be skipped as
244+
non-matching or rejected at policy/capability validation time, depending on the
245+
runtime mode contract. The important invariant is that missing identity must
246+
not produce a synthetic binary, broaden a binary-scoped allow rule, or cause
247+
the relay to query process metadata later. During `EgressDecision` hydration,
248+
absent process evidence should be carried forward as unavailable identity and
249+
process-derived fields should be omitted from the hydrated decision. The
250+
decision should record identity availability and fields used so OCSF logs and
251+
deny responses can distinguish "policy denied this binary" from "this runtime
252+
did not provide process identity."
253+
216254
## Current Owners And Proposed Cleanup
217255

218256
| Current owner | Current responsibility | Proposed cleanup |

0 commit comments

Comments
 (0)