You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As an operator running an MCP client in an OpenShell sandbox, I want sandbox status to show the latest OpenShell-observed outcome for each identifiable MCP endpoint, so that I can determine whether a recent request stopped at local policy, credential resolution, TLS or transport setup, or reached the upstream server without correlating several log sources.
Problem Statement
OpenShell reports whether a sandbox runtime is usable through the gateway. It also emits specific errors and security events when sandbox egress is denied or fails inside the supervisor. MCP clients do not consistently preserve or present that information. A client may reduce a local policy rejection, credential-resolution failure, or upstream rejection to a generic connection or protocol error.
The platform therefore lacks a compact, out-of-band summary of the most recent MCP egress outcome for a sandbox. Operators must correlate sandbox lifecycle status, effective network policy, provider state, supervisor logs, and the client error to identify the failing boundary.
The known incident in OpenShell #2161 and NemoClaw #6379 proves this failure category: provider metadata appeared healthy while actual MCP traffic failed across different agent stacks.
Impact / Why This Matters
An operator troubleshooting a failed MCP request currently has to consult separate surfaces to determine whether the request matched an allowed MCP policy rule, whether an applicable OpenShell-managed credential was available and authorized, whether OpenShell completed its TLS and transport work, and whether an upstream HTTP server responded.
OpenShell already owns or observes these boundaries. A structured sandbox-status summary would make the latest outcome available to interactive users and automation without requiring every MCP client to reproduce OpenShell-specific diagnostics.
Proposed Design
Expose one McpRouteReady entry in Sandbox.status.conditions for each distinct canonical MCP route in the active effective policy. The condition is passive evidence from observed traffic. It does not change SandboxPhase::Ready, create a health lease, or prove that a later tool call will succeed.
Use SandboxCondition.type for the condition class and SandboxCondition.subject as its secondary route key. The subject is an opaque OpenShell-owned SHA-256 identifier derived only from the normalized configured host, canonical path, and sorted deduplicated effective port set. Equivalent declarations collapse to one subject. Different paths on the same authority remain distinct. One multi-port endpoint produces one condition for its complete effective port set. Consumers select conditions by type plus subject and must not parse the human-readable message as an identifier.
The route subject is deliberately not reversible to a structured policy endpoint. It does not include the requesting binary, a client session, credentials, payloads, headers, tool arguments, query values, or raw upstream errors. Runtime policy still authorizes the actual request, including any binary scope, before an outcome can be attributed to a configured route. The public condition describes sandbox-level evidence for that route and does not claim caller-specific readiness.
Each condition uses a stable status and reason pair:
Unknown/NoObservedExchange means no qualifying exchange has been observed for the current route state.
True/Reachable means OpenShell received a syntactically valid upstream HTTP status below 400.
False/PolicyDenied means OpenShell policy or SSRF controls rejected an attributable request.
False/CredentialUnavailable means an applicable OpenShell-managed credential could not be resolved or authorized.
False/TlsFailed means TLS establishment or verification failed at the boundary OpenShell owns or observes.
False/TransportFailed means name resolution or upstream transport failed before a valid HTTP response arrived.
False/UpstreamRejected means the upstream returned a syntactically valid HTTP status of 400 or greater.
Acceptance Criteria
Status shape and identity
Sandbox.status.conditions contains one McpRouteReady condition for each distinct canonical MCP route in the active policy.
Every route condition has an opaque deterministic subject derived only from normalized host, canonical path, and the complete effective port set.
Equivalent declarations deduplicate, different paths remain distinct, and a multi-port endpoint produces one subject for its sorted deduplicated port set.
Public route identity does not include binary identity or client-session state and is documented as sandbox-level prior evidence rather than caller-specific readiness.
Outcome semantics
A route with no qualifying traffic under the current policy, applicable provider environment, and supervisor state reports Unknown/NoObservedExchange.
OpenShell-attributable policy, credential, TLS, transport, and upstream-rejection outcomes produce distinct stable status and reason pairs.
A syntactically valid upstream HTTP status below 400 reports True/Reachable; a valid status of 400 or greater reports False/UpstreamRejected; malformed or incomplete HTTP reports False/TransportFailed.
The status does not claim MCP protocol success, session health, tool availability, or tool-call success without parsing and validating the corresponding MCP response.
Every observed condition includes an RFC 3339 observation time. New repeated evidence advances that time, an idempotent private retry does not, and transition time changes only when status or reason changes.
Freshness and attribution
A policy change invalidates all current observations. An applicable provider-environment change invalidates credential-dependent observations. Supervisor disconnect or replacement invalidates observations from the previous session.
Stale, reordered, conflicting, or replayed reports cannot restore an observation from an obsolete policy, provider state, supervisor session, or gateway process.
Public reads project route conditions to Unknown when the current gateway process has no initialized live observation authority.
Requests that cannot be attributed to a current configured endpoint remain structured denial events or logs and do not mutate an unrelated endpoint observation.
Safety and compatibility
Route conditions omit credential values, request and response bodies, tool arguments, arbitrary headers, query values, session identifiers, report cursors, and raw upstream error text.
SandboxPhase::Ready and its existing operation gates remain unchanged.
The CLI and supported SDKs expose the opaque subject, status, reason, transition time, and observation time without exposing an upstream status code.
Verification and publication
Focused tests cover canonical identity, duplicate routes, distinct paths, multi-port sets, credentialed and uncredentialed routes, supported credential bindings, policy denial, credential unavailability, TLS failure, resolution failure, transport failure, upstream success and rejection, policy/provider invalidation, authenticated session replacement, private report idempotency, public fail-closed projection, and gateway restart.
A deterministic integration test sends an authenticated report through the real gateway handler and store, reads the public sandbox condition, verifies an unchanged sibling route, exercises identical and conflicting retries, then proves disconnect and supervisor replacement reset authority.
The Linux-only sandbox sidecar caller compiles through the owning crate on a Linux target.
Before publication, the issue includes a current end-to-end transcript against the pinned OpenShell revision showing a supported MCP client that loses or obscures OpenShell's structured failure and explaining why current logs do not satisfy the workflow.
Alternatives Considered
Add a dedicated MCP observation collection
Rejected. SandboxCondition already carries status, reason, message, and transition time. Adding an opaque subject and observation time lets the existing collection represent route-scoped evidence without introducing a parallel status model. The McpRouteReady name does not change lifecycle readiness because SandboxPhase::Ready remains authoritative for sandbox usability.
Expose a reversible endpoint reference
Rejected. A public structured reference would couple clients to policy representation and could reveal more route configuration than diagnostics require. An opaque deterministic subject gives clients a stable secondary key while keeping route canonicalization and future policy representation under OpenShell ownership.
Publish one condition per effective port
Rejected. A configured endpoint authorizes its effective port set as one route scope. Hashing the complete sorted set preserves that scope, deduplicates equivalent declarations, and avoids presenting one policy endpoint as several independent health claims.
Include binary or client identity in the public subject
Rejected for the first version. Runtime authorization still evaluates the requesting binary and ancestry, but the public condition reports sandbox-level evidence for the configured route. Caller-specific subjects would add unbounded cardinality, expose process details, and still would not prove that another request will succeed.
Agent Investigation
No response
Checklist
I've reviewed existing issues and the architecture docs
This is a design proposal, not a "please build this" request
User Story
As an operator running an MCP client in an OpenShell sandbox, I want sandbox status to show the latest OpenShell-observed outcome for each identifiable MCP endpoint, so that I can determine whether a recent request stopped at local policy, credential resolution, TLS or transport setup, or reached the upstream server without correlating several log sources.
Problem Statement
OpenShell reports whether a sandbox runtime is usable through the gateway. It also emits specific errors and security events when sandbox egress is denied or fails inside the supervisor. MCP clients do not consistently preserve or present that information. A client may reduce a local policy rejection, credential-resolution failure, or upstream rejection to a generic connection or protocol error.
The platform therefore lacks a compact, out-of-band summary of the most recent MCP egress outcome for a sandbox. Operators must correlate sandbox lifecycle status, effective network policy, provider state, supervisor logs, and the client error to identify the failing boundary.
The known incident in OpenShell #2161 and NemoClaw #6379 proves this failure category: provider metadata appeared healthy while actual MCP traffic failed across different agent stacks.
Impact / Why This Matters
An operator troubleshooting a failed MCP request currently has to consult separate surfaces to determine whether the request matched an allowed MCP policy rule, whether an applicable OpenShell-managed credential was available and authorized, whether OpenShell completed its TLS and transport work, and whether an upstream HTTP server responded.
OpenShell already owns or observes these boundaries. A structured sandbox-status summary would make the latest outcome available to interactive users and automation without requiring every MCP client to reproduce OpenShell-specific diagnostics.
Proposed Design
Expose one
McpRouteReadyentry inSandbox.status.conditionsfor each distinct canonical MCP route in the active effective policy. The condition is passive evidence from observed traffic. It does not changeSandboxPhase::Ready, create a health lease, or prove that a later tool call will succeed.Use
SandboxCondition.typefor the condition class andSandboxCondition.subjectas its secondary route key. The subject is an opaque OpenShell-owned SHA-256 identifier derived only from the normalized configured host, canonical path, and sorted deduplicated effective port set. Equivalent declarations collapse to one subject. Different paths on the same authority remain distinct. One multi-port endpoint produces one condition for its complete effective port set. Consumers select conditions bytypeplussubjectand must not parse the human-readable message as an identifier.The route subject is deliberately not reversible to a structured policy endpoint. It does not include the requesting binary, a client session, credentials, payloads, headers, tool arguments, query values, or raw upstream errors. Runtime policy still authorizes the actual request, including any binary scope, before an outcome can be attributed to a configured route. The public condition describes sandbox-level evidence for that route and does not claim caller-specific readiness.
Each condition uses a stable status and reason pair:
Unknown/NoObservedExchangemeans no qualifying exchange has been observed for the current route state.True/Reachablemeans OpenShell received a syntactically valid upstream HTTP status below 400.False/PolicyDeniedmeans OpenShell policy or SSRF controls rejected an attributable request.False/CredentialUnavailablemeans an applicable OpenShell-managed credential could not be resolved or authorized.False/TlsFailedmeans TLS establishment or verification failed at the boundary OpenShell owns or observes.False/TransportFailedmeans name resolution or upstream transport failed before a valid HTTP response arrived.False/UpstreamRejectedmeans the upstream returned a syntactically valid HTTP status of 400 or greater.Acceptance Criteria
Status shape and identity
Sandbox.status.conditionscontains oneMcpRouteReadycondition for each distinct canonical MCP route in the active policy.Outcome semantics
Unknown/NoObservedExchange.True/Reachable; a valid status of 400 or greater reportsFalse/UpstreamRejected; malformed or incomplete HTTP reportsFalse/TransportFailed.Freshness and attribution
Safety and compatibility
SandboxPhase::Readyand its existing operation gates remain unchanged.Verification and publication
Alternatives Considered
Add a dedicated MCP observation collection
Rejected.
SandboxConditionalready carries status, reason, message, and transition time. Adding an opaque subject and observation time lets the existing collection represent route-scoped evidence without introducing a parallel status model. TheMcpRouteReadyname does not change lifecycle readiness becauseSandboxPhase::Readyremains authoritative for sandbox usability.Expose a reversible endpoint reference
Rejected. A public structured reference would couple clients to policy representation and could reveal more route configuration than diagnostics require. An opaque deterministic subject gives clients a stable secondary key while keeping route canonicalization and future policy representation under OpenShell ownership.
Publish one condition per effective port
Rejected. A configured endpoint authorizes its effective port set as one route scope. Hashing the complete sorted set preserves that scope, deduplicates equivalent declarations, and avoids presenting one policy endpoint as several independent health claims.
Include binary or client identity in the public subject
Rejected for the first version. Runtime authorization still evaluates the requesting binary and ancestry, but the public condition reports sandbox-level evidence for the configured route. Caller-specific subjects would add unbounded cardinality, expose process details, and still would not prove that another request will succeed.
Agent Investigation
No response
Checklist