Skip to content

feat(policy): freeze a sandbox's effective policy for its lifetime #4734

Open

Description

@shiju-nv

User Story

I use OpenShell to run AI agents. I want to verify an approved policy during deployment, create a sandbox with that policy, and keep its access fixed until I delete it. If the agent needs different access, I want to recreate the sandbox with a newly reviewed policy.

Problem Statement

OpenShell has no per-sandbox option to keep the initialized effective policy unchanged for the sandbox's lifetime.

The effective policy depends on more than the submitted policy file. Global policy, attached providers and provider profiles affect what OpenShell delivers. Network rules and middleware can change while a sandbox runs, including through policy updates and proposal approvals. Changes from an external provider-profile source can affect composition without a sandbox policy write.

Impact / Why This Matters

Today, a deployment that needs fixed access must keep intercepting policy-changing operations after creation. An interceptor can reject those operations, but protecting one sandbox from a shared global or profile change can require rejecting the change for other sandboxes too. Profile-source changes also occur outside the intercepted mutation RPCs.

This leaves the deployment maintaining ongoing enforcement logic across several inputs instead of verifying policy once and relying on OpenShell to preserve it. The additional service overhead is one consequence; the missing per-sandbox guarantee is the underlying problem.

Proposed Design

Allow a sandbox to be created in a frozen policy mode. The mode is chosen at creation and cannot be enabled, disabled or reset on an existing sandbox. A newer approved policy also requires recreation; live policy refresh is outside this mode. Hot reload remains the default, and frozen and live sandboxes can share a gateway.

Illustrative CLI:

openshell sandbox create --name review-bot \
  --policy ./approved-policy.yaml \
  --provider github \
  --frozen \
  -- claude

The sandbox freezes the effective policy associated with its first successfully accepted configuration. The freeze includes provider-contributed rules, the attached provider identities and their credential authorization scopes, and any global-policy override selected at initialization. It must capture the accepted configuration consistently, even when inputs change concurrently.

Inspect and compare the frozen policy

The CLI and SDKs should expose frozen state, the frozen runtime policy hash and the time it froze. For example:

Policy: frozen at initialization
Policy hash: sha256:…

The existing full-policy view, openshell policy get review-bot --full, should return the captured policy rather than recompose it from current inputs.

Deployment workflow and trust boundary

The intended workflow is:

  1. Verify the approved policy and provider-profile artifacts.
  2. Import the verified profiles into OpenShell's local store, then create a frozen sandbox with an explicit policy.
  3. Read back what froze and compare it with the verified inputs. Treat a mismatch as a failed deployment and remove the sandbox.
  4. Recreate the sandbox when a different policy is approved.

Acceptance Criteria

  • A creation-time frozen mode is available through the CLI and public SDKs, including template-based creation. Existing sandboxes keep their current default behavior.
  • Concurrent initialization, retries and later restarts cannot replace the first accepted frozen policy or reset the mode.
  • Direct policy changes, proposal approvals and provider attach/detach cannot change an initialized frozen sandbox, regardless of caller identity. Errors name the freeze and explain recreation.
  • Global-policy and provider-profile changes, including external profile-source changes, leave frozen policy unchanged while still applying to live sandboxes. Shared mutation responses identify the exception.
  • All supported configuration delivery paths return the same frozen policy and hash without consulting a live external policy or profile source. Credential delivery uses the same policy identity.
  • Credential rotation and refresh continue without expanding frozen credential authorization. Incompatible provider changes produce an actionable credential-withheld state.
  • The freeze survives stop/start, runtime replacement, gateway restart, upgrade and replica failover. An incompatible policy cannot be silently substituted or unfrozen during an upgrade.
  • Frozen startup and restart work without a policy write-back replacing the saved snapshot. Obsolete live policy inputs do not block gateway startup or unrelated changes.
  • Full-policy reads and SDKs return the frozen policy, state, hash and timestamp. A documented comparison lets a deployer check the policy and credential scope against verified creation inputs without gateway-assigned IDs.
  • Docs explain the freeze point, failed-deployment comparison, global-policy exception, credential behavior and delete/recreate workflow.

Alternatives Considered

  • Gateway interceptors. They remain appropriate for requiring an approved policy or a frozen mode at creation. They can also reject policy-changing RPCs. The remaining gap is preserving one sandbox's effective policy while shared inputs change: external profile sources are read during composition, and rejecting a shared write can affect every sandbox. A service is not ruled out merely because it adds overhead; the requested invariant belongs where OpenShell selects and delivers policy.
  • Managed maximum policies (Enterprise permission modes with managed maximum policies #2109, draft feat(policy): add managed maximum permission modes #2168). A ceiling allows changes within its boundary. This use case requires an exact policy that stays fixed. Frozen could be implemented as one of its modes if it preserves that behavior across composition and delivery.
  • Global policy. It is gateway-wide and mutable, so it cannot express frozen and live sandboxes side by side.
  • Supervisor middleware or providers. Middleware evaluates traffic after policy selection, and providers contribute access. Neither owns preservation of the complete policy across configuration delivery and restart.
  • A supervisor-verified pin. It could detect a gateway serving the wrong policy, but introduces a stronger trust model and a provisioning/version-negotiation contract. It can follow separately if needed.

Agent Investigation

No response

Checklist

  • I've reviewed existing issues and the published docs
  • This is a design proposal, not a "please build this" request

Activity

  1. added a commit that references this issue on Oct 20, 2026
    279ed1a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions