Policy Schema Reference
Complete field reference for the sandbox policy YAML. Each field is documented with its type, whether it is required, and whether it is static (locked at sandbox creation) or dynamic (hot-reloadable on a running sandbox).
Top-Level Structure
A policy YAML file contains the following top-level fields:
Static fields are set at sandbox creation time. Changing them requires destroying and recreating the sandbox. Dynamic fields can be updated on a running sandbox with openshell policy update for incremental merges or openshell policy set for full replacement, and take effect without restarting.
Version
The version field identifies which schema the policy uses:
Filesystem Policy
Category: Static
Controls filesystem access inside the sandbox. Paths not listed in either read_only or read_write are inaccessible.
Validation constraints:
- Every path must be absolute (start with
/). - Paths must not contain
..traversal components. The server normalizes paths before storage, but rejects policies where traversal would escape the intended scope. - Read-write paths must not be overly broad (for example,
/alone is rejected). - Each individual path must not exceed 4096 characters.
- The combined total of
read_onlyandread_writepaths must not exceed 256.
Policies that violate these constraints are rejected with INVALID_ARGUMENT at creation or update time. Disk-loaded YAML policies that fail validation fall back to a restrictive default.
Example:
Landlock
Category: Static
Configures Landlock LSM enforcement at the kernel level. Landlock provides mandatory filesystem access control below what UNIX permissions allow.
Compatibility modes:
best_effort (the default) is appropriate for most deployments. It handles missing paths gracefully. For example, /app might not exist in every container image but is included in the baseline path set for containers that do have it. Individual missing paths are skipped while the remaining filesystem rules are still enforced.
hard_requirement is for environments where any gap in filesystem isolation is unacceptable. If a listed path cannot be opened for any reason (missing, permission denied, symlink loop), sandbox startup fails immediately rather than running with reduced protection.
When a path is skipped under best_effort, the sandbox logs a warning that includes the path, the specific error, and a human-readable reason (for example, “path does not exist” or “permission denied”).
Example:
Process
Category: Static
Sets the OS-level identity for the agent process inside the sandbox.
Validation constraint: Neither run_as_user nor run_as_group can be set to root or 0. Policies that request root process identity are rejected at creation or update time.
Example:
Network Policies
Category: Dynamic
A map of named network policy entries. Each entry declares a set of endpoints and a set of binaries. Only the listed binaries are permitted to connect to the listed endpoints. The map key is a logical identifier. The name field inside the entry is the display name used in logs.
Network Policy Entry
Each entry in the network_policies map has the following fields:
Endpoint Object
Each endpoint defines a reachable destination and optional inspection rules.
Credential rewrite recognizes the canonical openshell:resolve:env:KEY placeholder form and whole-token provider-shaped aliases such as provider-OPENSHELL-RESOLVE-ENV-API_TOKEN when the referenced environment key exists in the configured provider credentials.
Access Levels
The access field accepts one of the following values on REST, WebSocket, and GraphQL endpoints. MCP and JSON-RPC endpoints reject access because HTTP method/path presets cannot authorize JSON-RPC safely. Use explicit MCP rules, set mcp.allow_all_known_mcp_methods: true for the MCP method profile, or use explicit JSON-RPC rules.
For MCP endpoints, configure explicit rules with method, optional tool, and supported params. For generic JSON-RPC endpoints, configure explicit rules with method; JSON-RPC policy params matchers are not presently supported.
Allow Rule Objects
Used when access is not set. Each entry in rules contains an allow object. The tables below list the fields inside that allow object.
REST Allow Rule (protocol: rest)
REST allow rules match HTTP requests by method, path, and optional query parameters.
Example REST allow rules:
WebSocket Allow Rule (protocol: websocket)
WebSocket allow rules match the RFC 6455 HTTP upgrade by path and match client-to-server text messages on the same upgraded connection with the synthetic WEBSOCKET_TEXT method. Binary frames are relayed but are not rewritten.
Example WebSocket allow rules:
GraphQL Allow Rule (protocol: graphql or GraphQL-over-WebSocket)
GraphQL allow rules match parsed GraphQL operations by operation type, optional operation name, and optional root fields. On protocol: graphql, they apply to GraphQL-over-HTTP GET and POST requests. On protocol: websocket, include a separate GET allow rule for the RFC 6455 upgrade, then use GraphQL allow rules for client operation messages using the graphql-transport-ws subscribe message type or the legacy graphql-ws start message type.
Example GraphQL allow rules:
Example GraphQL-over-WebSocket allow rules:
Do not combine method, path, or query with operation_type, operation_name, or fields inside the same WebSocket rule. When a WebSocket endpoint has GraphQL operation policy, use GraphQL rules for client messages instead of a raw WEBSOCKET_TEXT allow rule.
MCP Allow And Deny Rules (protocol: mcp)
MCP rules match sandbox-to-server MCP Streamable HTTP request bodies by MCP method and optional tool selectors. OpenShell parses the underlying JSON-RPC 2.0 envelope, validates known MCP request and notification params, and preserves unknown extension methods as policy-addressable literal method strings. Until OpenShell exposes explicit MCP version profiles, mcp.allow_all_known_mcp_methods defaults to false, so endpoints require explicit MCP method rules. Set mcp.allow_all_known_mcp_methods: true to enable the endpoint method profile; in that mode, rules can omit method, and tool selectors are normalized to tools/call internally. By default, tools/call params.name must match the MCP-recommended tool-name pattern ^[A-Za-z0-9_.-]{1,128}$; configure mcp.strict_tool_names: false on the endpoint only to allow a server that intentionally uses names outside that pattern. Wildcard tool matchers require mcp.strict_tool_names to remain enabled. JSON-RPC responses and server-to-client MCP messages on response bodies or SSE streams are relayed but are not currently parsed for policy enforcement.
Use rules for MCP allow rules and deny_rules for MCP deny rules. Deny rules take precedence over allow rules. If an MCP endpoint sets mcp.allow_all_known_mcp_methods: true and omits rules, OpenShell allows all MCP-family methods and all tools, then applies any deny_rules. Otherwise, the endpoint must define explicit rules. A broad allow or deny rule whose method matcher includes tools/call cannot be combined with tool-specific allow rules because it would bypass or erase the tool filter; add tool or params.name to scope tools/call, or remove the tool-specific rules. In a batch request, one denied call denies the full batch.
An MCP client first sends initialize. After the server returns a successful response, the client sends notifications/initialized. After initialization completes and the server advertises the tools capability, the client can call an advertised tool. The response does not need an allow rule because these rules inspect messages sent from the client to the server. This example adds both client initialization messages to the existing tool rules. It omits tools/list because it assumes the client already knows the tool names; add that method when the client performs discovery.
JSON-RPC Allow Rule (protocol: json-rpc)
JSON-RPC allow rules match sandbox-to-server JSON-RPC-over-HTTP request objects by RPC method. They apply to single JSON-RPC requests and batch requests. For a batch, OpenShell evaluates each call independently. Client-to-server JSON-RPC response frames in POST bodies are denied. Server-to-client messages on HTTP response bodies or MCP SSE streams are relayed but are not currently parsed for policy enforcement.
Generic JSON-RPC policy params matchers are not supported. Allow rules match only the JSON-RPC method.
Example JSON-RPC allow rules:
Deny Rule Objects
Blocks specific operations on endpoints that otherwise have broad access. Deny rules are evaluated after allow rules and take precedence: if a request matches any deny rule, it is blocked regardless of what the allow rules or access preset permit.
REST Deny Rule (protocol: rest)
REST deny rules use the same field names as REST allow rules, but they appear directly under each deny_rules entry instead of under an allow wrapper.
Example REST deny rules:
WebSocket Deny Rule (protocol: websocket)
WebSocket deny rules use the same field names as WebSocket allow rules, but they appear directly under each deny_rules entry instead of under an allow wrapper.
Example WebSocket deny rules:
GraphQL Deny Rule (protocol: graphql or GraphQL-over-WebSocket)
GraphQL deny rules use the same field names as GraphQL allow rules, but they appear directly under each deny_rules entry instead of under an allow wrapper. On WebSocket GraphQL endpoints, they apply only to classified GraphQL operation messages; protocol lifecycle messages such as connection_init, ping, pong, and complete are allowed as WebSocket control-plane messages and are not payload-logged.
Example GraphQL deny rules:
JSON-RPC Deny Rule (protocol: json-rpc)
JSON-RPC deny rules use the same field names as JSON-RPC allow rules, but they appear directly under each deny_rules entry instead of under an allow wrapper. Deny rules take precedence over allow rules. In a batch request, one denied call denies the full batch.
JSON-RPC deny rules do not support policy params matchers yet. Use MCP tool rules for MCP tool calls, or deny generic JSON-RPC methods by method.
Example JSON-RPC deny rules:
Binary Object
Identifies an executable that is permitted to use the associated endpoints.
Full Example
The following policy grants read-only GitHub API access and npm registry access: