fix(proxy): fall through to OPA on identity resolution failure#10
Merged
Conversation
The CONNECT proxy's process-identity resolution fails in Kubernetes/ container deployments because the ephemeral port seen by peer_addr doesn't match entries in /proc/<entrypoint_pid>/net/tcp due to network namespace boundary timing issues. Previously this caused a hard deny without ever evaluating OPA policy. Additionally, policies that declare endpoints without a `binaries` field (the field is optional and defaults to empty) were unconditionally denied because the Rego binary_allowed rule iterates policy.binaries with `some b` which yields nothing on an empty array. This commit: - Adds a fallback in evaluate_opa_tcp that constructs a sentinel "<unresolved>" identity and lets OPA decide (instead of hard-deny) - Adds a Rego rule: empty binaries list means "any binary is allowed" (the endpoint declaration itself is the access gate) - Adds unit tests for both the happy path and security constraint The sentinel path "<unresolved>" contains angle brackets which are invalid filesystem characters, so it can never match a real binary entry — policies with explicit binary restrictions remain enforced. Signed-off-by: Paolo Dettori <paolo@dettori.dev> Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
pdettori
commented
Jun 5, 2026
Author
pdettori
left a comment
There was a problem hiding this comment.
Self-review notes:
Good fix for the identity-resolution + empty-binaries interaction. Rego logic is correct, sentinel is safe, tests cover the security invariant.
Blocking issue — CI clippy failure:
error: fields `binary`, `binary_pid`, and `ancestors` are never read
--> crates/openshell-sandbox/src/proxy.rs:1219:5
The IdentityError struct (line 1217) has fields that are written but never read after this change. Fix options:
- Include these fields in the
warn!()message so they provide diagnostics (preferred — helps debug identity resolution in prod) - Prefix with
_if they're for future use
Once clippy passes, this LGTM.
Include binary, binary_pid, and ancestors from IdentityError in the warn!() structured fields so they provide diagnostics in production. Fixes clippy dead_code lint on IdentityError fields. Signed-off-by: Paolo Dettori <paolo@dettori.dev> Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
pdettori
added a commit
to kagenti/kagenti
that referenced
this pull request
Jun 6, 2026
Update gateway and supervisor images to v0.0.56 which includes the identity resolution fallback fix (kagenti/OpenShell#10). This allows sandbox egress policies to work without requiring explicit binary restrictions in the policy YAML. Signed-off-by: Paolo Dettori <paolo@dettori.dev> Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
--policyexplicitly allows an endpoint but nobinariesare specified/proc/net/tcplookup failurebinariesin a network policy rule is treated as "any binary allowed" (the endpoint itself is the gate)Root Cause
Two interacting bugs:
Identity resolution fails in K8s —
peer_addr.port()returns ports outside the ephemeral range (4337, 5204, 5952) due to namespace boundary timing in the privileged container + veth setup. The/proc/<pid>/net/tcplookup never finds them.Empty binaries = unconditional deny — The Rego
binary_allowedrule usessome b := policy.binaries[_]which yields nothing on an empty array, so even successful identity resolution would be denied.Changes
sandbox-policy.regobinary_allowed(policy, _)rule for empty binariesproxy.rs<unresolved>identity fallbackopa.rstestdata/sandbox-policy.yamlSecurity
<unresolved>contains angle brackets — invalid filesystem path, can never match a real binary entrybinariesrestrictions remain enforced (the sentinel won't match)Test plan
cargo test -p openshell-sandboxpasses (new + existing tests)openshell sandbox create --policy egress-allow.yaml, verifycurl https://github.comworks insideAssisted-By: Claude Code