Deploy preview for PR 257 🛫

This commit is contained in:
pimlock
2026-03-12 23:38:45 +00:00
parent 172a61a075
commit 777413101e
38 changed files with 208 additions and 142 deletions
+1 -1
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
+1 -1
View File
@@ -1 +1 @@
{"id":"about/architecture","title":"How OpenShell Works","url":"about/architecture.html","last_modified":"2026-03-12T09:12:26.557006+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"OpenShell architecture overview covering the gateway, sandbox, policy engine, and privacy router.","tags":["AI Agents","Sandboxing","Security","Architecture"],"topics":["Generative AI","Cybersecurity"],"content_type":"concept","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"How OpenShell Works OpenShell runs as a K3s Kubernetes cluster inside a Docker container. Each sandbox is an isolated Kubernetes pod managed through the gateway. Four components work together to keep agents secure. Components The following table describes each component and its role in the system: Component Role Gateway Control-plane API that coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers requests across the platform. Sandbox Isolated runtime that includes container supervision and policy-enforced egress routing. Policy Engine Policy definition and enforcement layer for filesystem, network, and process constraints. Defense in depth enforces policies from the application layer down to infrastructure and kernel layers. Privacy Router Privacy-aware LLM routing layer that keeps sensitive context on sandbox compute and routes based on cost and privacy policy. How a Request Flows Every outbound connection from agent code passes through the same decision path: The agent process opens an outbound connection (API call, package install, git clone, and so on). The proxy inside the sandbox intercepts the connection and identifies which binary opened it. The proxy queries the policy engine with the destination, port, and calling binary. The policy engine returns one of three decisions: Allow — the destination and binary match a policy block. Traffic flows directly to the external service. Route for inference — no policy block matched, but inference routing is configured. The privacy router intercepts the request, strips the original credentials, injects the configured backend credentials, and forwards to the managed model endpoint. Deny — no match and no inference route. The connection is blocked and logged. For REST endpoints with TLS termination enabled, the proxy also decrypts TLS and checks each HTTP request against per-method, per-path rules before allowing it through. Deployment Modes OpenShell can run locally or on a remote host. The architecture is identical in both cases — only the Docker container location changes. Local : the k3s cluster runs inside Docker on your workstation. The CLI provisions it automatically on first use. Remote : the cluster runs on a remote host. Deploy with openshell gateway start --remote user@host . For example, connect to your DGX Spark. $ openshell gateway start --remote <username>@<spark-ssid>.local\nopenshell status\nNext Steps Continue with one of the following: To create your first sandbox, refer to the Quickstart . To learn how OpenShell enforces isolation across all protection layers, refer to Sandboxes","format":"text","summary":"OpenShell runs as a K3s Kubernetes cluster inside a Docker container. Each sandbox is an isolated Kubernetes pod managed through the gateway. Four components work together to keep agents secure.","headings":[{"text":"How OpenShell Works","level":1},{"text":"Components","level":2},{"text":"How a Request Flows","level":2},{"text":"Deployment Modes","level":2},{"text":"Next Steps","level":2}]}
{"id":"about/architecture","title":"How OpenShell Works","url":"about/architecture.html","last_modified":"2026-03-12T23:38:42.336639+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"OpenShell architecture overview covering the gateway, sandbox, policy engine, and privacy router.","tags":["AI Agents","Sandboxing","Security","Architecture"],"topics":["Generative AI","Cybersecurity"],"content_type":"concept","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"How OpenShell Works OpenShell runs as a K3s Kubernetes cluster inside a Docker container. Each sandbox is an isolated Kubernetes pod managed through the gateway. Four components work together to keep agents secure. Components The following table describes each component and its role in the system: Component Role Gateway Control-plane API that coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers requests across the platform. Sandbox Isolated runtime that includes container supervision and policy-enforced egress routing. Policy Engine Policy definition and enforcement layer for filesystem, network, and process constraints. Defense in depth enforces policies from the application layer down to infrastructure and kernel layers. Privacy Router Privacy-aware LLM routing layer that keeps sensitive context on sandbox compute and routes based on cost and privacy policy. How a Request Flows Every outbound connection from agent code passes through the same decision path: The agent process opens an outbound connection (API call, package install, git clone, and so on). The proxy inside the sandbox intercepts the connection and identifies which binary opened it. The proxy queries the policy engine with the destination, port, and calling binary. The policy engine returns one of three decisions: Allow — the destination and binary match a policy block. Traffic flows directly to the external service. Route for inference — no policy block matched, but inference routing is configured. The privacy router intercepts the request, strips the original credentials, injects the configured backend credentials, and forwards to the managed model endpoint. Deny — no match and no inference route. The connection is blocked and logged. For REST endpoints with TLS termination enabled, the proxy also decrypts TLS and checks each HTTP request against per-method, per-path rules before allowing it through. Deployment Modes OpenShell can run locally or on a remote host. The architecture is identical in both cases — only the Docker container location changes. Local : the k3s cluster runs inside Docker on your workstation. The CLI provisions it automatically on first use. Remote : the cluster runs on a remote host. Deploy with openshell gateway start --remote user@host . For example, connect to your DGX Spark. $ openshell gateway start --remote <username>@<spark-ssid>.local\nopenshell status\nNext Steps Continue with one of the following: To create your first sandbox, refer to the Quickstart . To learn how OpenShell enforces isolation across all protection layers, refer to Sandboxes","format":"text","summary":"OpenShell runs as a K3s Kubernetes cluster inside a Docker container. Each sandbox is an isolated Kubernetes pod managed through the gateway. Four components work together to keep agents secure.","headings":[{"text":"How OpenShell Works","level":1},{"text":"Components","level":2},{"text":"How a Request Flows","level":2},{"text":"Deployment Modes","level":2},{"text":"Next Steps","level":2}]}
+1 -1
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
+1 -1
View File
@@ -1 +1 @@
{"id":"about/overview","title":"Overview of NVIDIA OpenShell","url":"about/overview.html","last_modified":"2026-03-12T09:12:26.562681+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"OpenShell is the safe, private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure.","tags":["AI Agents","Sandboxing","Security","Privacy","Inference Routing"],"topics":["Generative AI","Cybersecurity"],"content_type":"concept","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"Overview of NVIDIA OpenShell NVIDIA OpenShell is an open-source runtime for executing autonomous AI agents in sandboxed environments with kernel-level isolation. It combines sandbox runtime controls and a declarative YAML policy so teams can run agents without giving them unrestricted access to local files, credentials, and external networks. Why OpenShell Exists AI agents are most useful when they can read files, install packages, call APIs, and use credentials. That same access can create material risk. OpenShell is designed for this tradeoff: preserve agent capability while enforcing explicit controls over what the agent can access. Common Risks and Controls The table below summarizes common failure modes and how OpenShell mitigates them. Threat Without controls With OpenShell Data exfiltration Agent uploads source code or internal files to unauthorized endpoints. Network policies allow only approved destinations; other outbound traffic is denied. Credential theft Agent reads local secrets such as SSH keys or cloud credentials. Filesystem restrictions (Landlock) confine access to declared paths only. Unauthorized API usage Agent sends prompts or data to unapproved model providers. Privacy routing and network policies control where inference traffic can go. Privilege escalation Agent attempts sudo , setuid paths, or dangerous syscall behavior. Unprivileged process identity and seccomp restrictions block escalation paths. Protection Layers at a Glance OpenShell applies defense in depth across the following policy domains. Layer What it protects When it applies Filesystem Prevents reads/writes outside allowed paths. Locked at sandbox creation. Network Blocks unauthorized outbound connections. Hot-reloadable at runtime. Process Blocks privilege escalation and dangerous syscalls. Locked at sandbox creation. Inference Reroutes model API calls to controlled backends. Hot-reloadable at runtime. For details, refer to Built-in Default Policy and Customize Sandbox Policies . Common Use Cases OpenShell supports a range of agent deployment patterns. Use Case Description Secure coding agents Run Claude Code, OpenCode, or OpenClaw with constrained file and network access. Private enterprise development Route inference to self-hosted or private backends while keeping sensitive context under your control. Compliance and audit Treat policy YAML as version-controlled security controls that can be reviewed and audited. Reusable environments Use community sandbox images or bring your own containerized runtime. Next Steps Explore these topics to go deeper: To understand the components that make up the OpenShell runtime, refer to the Architecture Overview . To install the CLI and create your first sandbox, refer to the Quickstart . To learn how OpenShell enforces isolation across all protection layers, refer to Sandboxes","format":"text","summary":"NVIDIA OpenShell is an open-source runtime for executing autonomous AI agents in sandboxed environments with kernel-level isolation. It combines sandbox runtime controls and a declarative YAML policy so teams can run agents without giving them unrestricted access to local files, credentials, and ...","headings":[{"text":"Overview of NVIDIA OpenShell","level":1},{"text":"Why OpenShell Exists","level":2},{"text":"Common Risks and Controls","level":2},{"text":"Protection Layers at a Glance","level":2},{"text":"Common Use Cases","level":2},{"text":"Next Steps","level":2}]}
{"id":"about/overview","title":"Overview of NVIDIA OpenShell","url":"about/overview.html","last_modified":"2026-03-12T23:38:42.323972+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"OpenShell is the safe, private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure.","tags":["AI Agents","Sandboxing","Security","Privacy","Inference Routing"],"topics":["Generative AI","Cybersecurity"],"content_type":"concept","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"Overview of NVIDIA OpenShell NVIDIA OpenShell is an open-source runtime for executing autonomous AI agents in sandboxed environments with kernel-level isolation. It combines sandbox runtime controls and a declarative YAML policy so teams can run agents without giving them unrestricted access to local files, credentials, and external networks. Why OpenShell Exists AI agents are most useful when they can read files, install packages, call APIs, and use credentials. That same access can create material risk. OpenShell is designed for this tradeoff: preserve agent capability while enforcing explicit controls over what the agent can access. Common Risks and Controls The table below summarizes common failure modes and how OpenShell mitigates them. Threat Without controls With OpenShell Data exfiltration Agent uploads source code or internal files to unauthorized endpoints. Network policies allow only approved destinations; other outbound traffic is denied. Credential theft Agent reads local secrets such as SSH keys or cloud credentials. Filesystem restrictions (Landlock) confine access to declared paths only. Unauthorized API usage Agent sends prompts or data to unapproved model providers. Privacy routing and network policies control where inference traffic can go. Privilege escalation Agent attempts sudo , setuid paths, or dangerous syscall behavior. Unprivileged process identity and seccomp restrictions block escalation paths. Protection Layers at a Glance OpenShell applies defense in depth across the following policy domains. Layer What it protects When it applies Filesystem Prevents reads/writes outside allowed paths. Locked at sandbox creation. Network Blocks unauthorized outbound connections. Hot-reloadable at runtime. Process Blocks privilege escalation and dangerous syscalls. Locked at sandbox creation. Inference Reroutes model API calls to controlled backends. Hot-reloadable at runtime. For details, refer to Built-in Default Policy and Customize Sandbox Policies . Common Use Cases OpenShell supports a range of agent deployment patterns. Use Case Description Secure coding agents Run Claude Code, OpenCode, or OpenClaw with constrained file and network access. Private enterprise development Route inference to self-hosted or private backends while keeping sensitive context under your control. Compliance and audit Treat policy YAML as version-controlled security controls that can be reviewed and audited. Reusable environments Use community sandbox images or bring your own containerized runtime. Next Steps Explore these topics to go deeper: To understand the components that make up the OpenShell runtime, refer to the Architecture Overview . To install the CLI and create your first sandbox, refer to the Quickstart . To learn how OpenShell enforces isolation across all protection layers, refer to Sandboxes","format":"text","summary":"NVIDIA OpenShell is an open-source runtime for executing autonomous AI agents in sandboxed environments with kernel-level isolation. It combines sandbox runtime controls and a declarative YAML policy so teams can run agents without giving them unrestricted access to local files, credentials, and ...","headings":[{"text":"Overview of NVIDIA OpenShell","level":1},{"text":"Why OpenShell Exists","level":2},{"text":"Common Risks and Controls","level":2},{"text":"Protection Layers at a Glance","level":2},{"text":"Common Use Cases","level":2},{"text":"Next Steps","level":2}]}
+1 -1
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
+1 -1
View File
@@ -1 +1 @@
{"id":"about/release-notes","title":"NVIDIA OpenShell Release Notes","url":"about/release-notes.html","last_modified":"2026-03-12T09:12:26.578386+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Track the latest changes and improvements to NVIDIA OpenShell.","tags":["Release Notes","Changelog","AI Agents"],"topics":["Generative AI","Cybersecurity"],"content_type":"reference","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"NVIDIA OpenShell Release Notes Track the latest changes and improvements to NVIDIA OpenShell\nThis page covers the highlights of the release\nFor more details, refer to the OpenShell GitHub Releases . 0.1.0 This is the first release of NVIDIA OpenShell. It introduces sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. Highlights Introduces sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. Introduces the openshell CLI for creating, managing, and customizing sandboxes. Introduces the openshell-gateway service for managing the gateway and sandboxes. Introduces the openshell-sandbox service for running the sandboxed agent","format":"text","summary":"Track the latest changes and improvements to NVIDIA OpenShell. This page covers the highlights of the release. For more details, refer to the OpenShell GitHub Releases.","headings":[{"text":"NVIDIA OpenShell Release Notes","level":1},{"text":"0.1.0","level":2},{"text":"Highlights","level":3}]}
{"id":"about/release-notes","title":"NVIDIA OpenShell Release Notes","url":"about/release-notes.html","last_modified":"2026-03-12T23:38:42.327741+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Track the latest changes and improvements to NVIDIA OpenShell.","tags":["Release Notes","Changelog","AI Agents"],"topics":["Generative AI","Cybersecurity"],"content_type":"reference","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"NVIDIA OpenShell Release Notes Track the latest changes and improvements to NVIDIA OpenShell\nThis page covers the highlights of the release\nFor more details, refer to the OpenShell GitHub Releases . 0.1.0 This is the first release of NVIDIA OpenShell. It introduces sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. Highlights Introduces sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. Introduces the openshell CLI for creating, managing, and customizing sandboxes. Introduces the openshell-gateway service for managing the gateway and sandboxes. Introduces the openshell-sandbox service for running the sandboxed agent","format":"text","summary":"Track the latest changes and improvements to NVIDIA OpenShell. This page covers the highlights of the release. For more details, refer to the OpenShell GitHub Releases.","headings":[{"text":"NVIDIA OpenShell Release Notes","level":1},{"text":"0.1.0","level":2},{"text":"Highlights","level":3}]}
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="current nav bd-sidenav">
<li class="toctree-l1 current active"><a class="current reference internal" href="#">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
@@ -1 +1 @@
{"id":"get-started/quickstart","title":"Quickstart","url":"get-started/quickstart.html","last_modified":"2026-03-12T09:12:26.567481+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Install the OpenShell CLI and create your first sandboxed AI agent in two commands.","tags":["AI Agents","Sandboxing","Installation","Quickstart"],"topics":["Generative AI","Cybersecurity"],"content_type":"get_started","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"Quickstart This page gets you from zero to a running, policy-enforced sandbox in two commands. Prerequisites Before you begin, make sure you have: Python 3.12 or later uv installed Docker Desktop running on your machine Install the OpenShell CLI Install the openshell package into a virtual environment. Activate your virtual environment: uv venv && source .venv/bin/activate\nInstall the CLI: uv pip install openshell\nConnect to a Remote Gateway (Optional) If you’re running locally, skip this step. The OpenShell CLI creates a gateway automatically when you create your first sandbox. Brev Deploy an OpenShell gateway on Brev by hitting Deploy on the OpenShell Launchable . After the instance is running, find the gateway URL in the Brev console under Using Secure Links . Copy the shareable URL for port 8080 — this is the gateway endpoint. $ openshell gateway add https://<your-port-8080-url>.brevlab.com\nopenshell status\nDGX Spark Set up your Spark with NVIDIA Sync first, or make sure SSH access is configured (such as SSH keys added to the host). Deploy to a DGX Spark machine over SSH: $ openshell gateway start --remote <username>@<spark-ssid>.local\nopenshell status\nAfter openshell status shows the gateway as healthy, all subsequent commands route through the SSH tunnel. Create Your First OpenShell Sandbox Choose the tab that matches your agent: Claude Code Run the following command to create a sandbox with Claude Code: $ openshell sandbox create -- claude\nThe CLI prompts you to create a provider from local credentials — type yes to continue. If ANTHROPIC_API_KEY is set in your environment, it is picked up automatically. If not, you can configure it from inside the sandbox after it launches. OpenCode Run the following command to create a sandbox with OpenCode: $ openshell sandbox create -- opencode\nThe CLI prompts you to create a provider from local credentials. Type yes to continue. If OPENAI_API_KEY or OPENROUTER_API_KEY is set in your environment, it is picked up automatically. If not, you can configure it from inside the sandbox after it launches. Codex Run the following command to create a sandbox with Codex: $ openshell sandbox create -- codex\nThe CLI prompts you to create a provider from local credentials. Type yes to continue. If OPENAI_API_KEY is set in your environment, it is picked up automatically. If not, you can configure it from inside the sandbox after it launches. OpenClaw Run the following command to create a sandbox with OpenClaw: $ openshell sandbox create --from openclaw\nThe --from flag pulls a pre-built sandbox definition from the OpenShell Community catalog. Each definition bundles a container image, a tailored policy, and optional skills into a single package. Community Sandbox You can use the --from flag to pull other OpenShell sandbox images from the NVIDIA Container Registry . For example, to pull the base image, run the following command: $ openshell sandbox create --from base","format":"text","summary":"This page gets you from zero to a running, policy-enforced sandbox in two commands.","headings":[{"text":"Quickstart","level":1},{"text":"Prerequisites","level":2},{"text":"Install the OpenShell CLI","level":2},{"text":"Connect to a Remote Gateway (Optional)","level":2},{"text":"Create Your First OpenShell Sandbox","level":2}]}
{"id":"get-started/quickstart","title":"Quickstart","url":"get-started/quickstart.html","last_modified":"2026-03-12T23:38:42.392461+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Install the OpenShell CLI and create your first sandboxed AI agent in two commands.","tags":["AI Agents","Sandboxing","Installation","Quickstart"],"topics":["Generative AI","Cybersecurity"],"content_type":"get_started","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"Quickstart This page gets you from zero to a running, policy-enforced sandbox in two commands. Prerequisites Before you begin, make sure you have: Python 3.12 or later uv installed Docker Desktop running on your machine Install the OpenShell CLI Install the openshell package into a virtual environment. Activate your virtual environment: uv venv && source .venv/bin/activate\nInstall the CLI: uv pip install openshell\nConnect to a Remote Gateway (Optional) If you’re running locally, skip this step. The OpenShell CLI creates a gateway automatically when you create your first sandbox. Brev Deploy an OpenShell gateway on Brev by hitting Deploy on the OpenShell Launchable . After the instance is running, find the gateway URL in the Brev console under Using Secure Links . Copy the shareable URL for port 8080 — this is the gateway endpoint. $ openshell gateway add https://<your-port-8080-url>.brevlab.com\nopenshell status\nDGX Spark Set up your Spark with NVIDIA Sync first, or make sure SSH access is configured (such as SSH keys added to the host). Deploy to a DGX Spark machine over SSH: $ openshell gateway start --remote <username>@<spark-ssid>.local\nopenshell status\nAfter openshell status shows the gateway as healthy, all subsequent commands route through the SSH tunnel. Create Your First OpenShell Sandbox Choose the tab that matches your agent: Claude Code Run the following command to create a sandbox with Claude Code: $ openshell sandbox create -- claude\nThe CLI prompts you to create a provider from local credentials — type yes to continue. If ANTHROPIC_API_KEY is set in your environment, it is picked up automatically. If not, you can configure it from inside the sandbox after it launches. OpenCode Run the following command to create a sandbox with OpenCode: $ openshell sandbox create -- opencode\nThe CLI prompts you to create a provider from local credentials. Type yes to continue. If OPENAI_API_KEY or OPENROUTER_API_KEY is set in your environment, it is picked up automatically. If not, you can configure it from inside the sandbox after it launches. Codex Run the following command to create a sandbox with Codex: $ openshell sandbox create -- codex\nThe CLI prompts you to create a provider from local credentials. Type yes to continue. If OPENAI_API_KEY is set in your environment, it is picked up automatically. If not, you can configure it from inside the sandbox after it launches. OpenClaw Run the following command to create a sandbox with OpenClaw: $ openshell sandbox create --from openclaw\nThe --from flag pulls a pre-built sandbox definition from the OpenShell Community catalog. Each definition bundles a container image, a tailored policy, and optional skills into a single package. Community Sandbox You can use the --from flag to pull other OpenShell sandbox images from the NVIDIA Container Registry . For example, to pull the base image, run the following command: $ openshell sandbox create --from base","format":"text","summary":"This page gets you from zero to a running, policy-enforced sandbox in two commands.","headings":[{"text":"Quickstart","level":1},{"text":"Prerequisites","level":2},{"text":"Install the OpenShell CLI","level":2},{"text":"Connect to a Remote Gateway (Optional)","level":2},{"text":"Create Your First OpenShell Sandbox","level":2}]}
+1 -1
View File
@@ -386,7 +386,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
+1 -1
View File
@@ -1 +1 @@
{"id":"inference/configure","title":"Configure Inference Routing","url":"inference/configure.html","last_modified":"2026-03-12T09:12:26.623340+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Set up the managed local inference endpoint with provider credentials and model configuration.","tags":["Inference Routing","Configuration","Privacy","LLM","Provider"],"topics":["Generative AI","Cybersecurity"],"content_type":"how_to","learning_level":"technical_intermediate","audience":["engineer"],"content":"Configure Inference Routing This page covers the managed local inference endpoint ( https://inference.local ). External inference endpoints go through sandbox network_policies — refer to Network Access Rules for details. The configuration consists of two values: Value Description Provider record The credential backend OpenShell uses to authenticate with the upstream model host. Model ID The model to use for generation requests. Step 1: Create a Provider Create a provider that holds the backend credentials you want OpenShell to use. NVIDIA API Catalog $ openshell provider create --name nvidia-prod --type nvidia --from-existing\nThis reads NVIDIA_API_KEY from your environment. Local / self-hosted endpoint $ openshell provider create\nname my-local-model\ntype openai\ncredential OPENAI_API_KEY=empty-if-not-required\nconfig OPENAI_BASE_URL=http://192.168.10.15/v1\nUse --config OPENAI_BASE_URL to point to any OpenAI-compatible server running on your network. Set OPENAI_API_KEY to a dummy value if the server does not require authentication. Anthropic $ openshell provider create --name anthropic-prod --type anthropic --from-existing\nThis reads ANTHROPIC_API_KEY from your environment. Step 2: Set Inference Routing Point inference.local at that provider and choose the model to use: $ openshell inference set\nprovider nvidia-prod\nmodel nvidia/nemotron-3-nano-30b-a3b\nStep 3: Verify the Active Config Confirm that the provider and model are set correctly: $ openshell inference get\nGateway inference\nProvider: nvidia-prod\nModel: nvidia/nemotron-3-nano-30b-a3b\nVersion: 1\nStep 4: Update Part of the Config Use update when you want to change only one field: $ openshell inference update --model nvidia/nemotron-3-nano-30b-a3b\nOr switch providers without repeating the current model: $ openshell inference update --provider openai-prod\nUse It from a Sandbox After inference is configured, code inside any sandbox can call https://inference.local directly: from openai import OpenAI\nclient = OpenAI(base_url=\"https://inference.local/v1\", api_key=\"dummy\nresponse = client.chat.completions.create\nmodel=\"anything\nmessages=[{\"role\": \"user\", \"content\": \"Hello\nThe client-supplied model is ignored for generation requests. OpenShell rewrites it to the configured model before forwarding upstream. Use this endpoint when inference should stay local to the host for privacy and security reasons. External providers that should be reached directly belong in network_policies instead. Verify the Endpoint from a Sandbox openshell inference get confirms the configuration was saved, but does not verify the upstream endpoint is reachable. To confirm end-to-end connectivity, connect to a sandbox and run: curl https://inference.local/v1/responses\nH \"Content-Type: application/json\"\nd\ninstructions\": \"You are a helpful assistant\ninput\": \"Hello\nA successful response confirms the privacy router can reach the configured backend and the model is serving requests. Gateway-scoped — every sandbox on the active gateway sees the same inference.local backend. HTTPS only — inference.local is intercepted only for HTTPS traffic. Next Steps Explore related topics: To understand the inference routing flow and supported API patterns, refer to index . To control external endpoints, refer to Network Access Rules . To manage provider records, refer to ../sandboxes/providers . To view openshell inference commands, refer to ../reference/cli","format":"text","summary":"This page covers the managed local inference endpoint (https://inference.local). External inference endpoints go through sandbox network_policies — refer to Network Access Rules for details.","headings":[{"text":"Configure Inference Routing","level":1},{"text":"Step 1: Create a Provider","level":2},{"text":"Step 2: Set Inference Routing","level":2},{"text":"Step 3: Verify the Active Config","level":2},{"text":"Step 4: Update Part of the Config","level":2},{"text":"Use It from a Sandbox","level":2},{"text":"Verify the Endpoint from a Sandbox","level":3},{"text":"Next Steps","level":2}]}
{"id":"inference/configure","title":"Configure Inference Routing","url":"inference/configure.html","last_modified":"2026-03-12T23:38:42.358178+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Set up the managed local inference endpoint with provider credentials and model configuration.","tags":["Inference Routing","Configuration","Privacy","LLM","Provider"],"topics":["Generative AI","Cybersecurity"],"content_type":"how_to","learning_level":"technical_intermediate","audience":["engineer"],"content":"Configure Inference Routing This page covers the managed local inference endpoint ( https://inference.local ). External inference endpoints go through sandbox network_policies — refer to Network Access Rules for details. The configuration consists of two values: Value Description Provider record The credential backend OpenShell uses to authenticate with the upstream model host. Model ID The model to use for generation requests. Step 1: Create a Provider Create a provider that holds the backend credentials you want OpenShell to use. NVIDIA API Catalog $ openshell provider create --name nvidia-prod --type nvidia --from-existing\nThis reads NVIDIA_API_KEY from your environment. Local / self-hosted endpoint $ openshell provider create\nname my-local-model\ntype openai\ncredential OPENAI_API_KEY=empty-if-not-required\nconfig OPENAI_BASE_URL=http://192.168.10.15/v1\nUse --config OPENAI_BASE_URL to point to any OpenAI-compatible server running on your network. Set OPENAI_API_KEY to a dummy value if the server does not require authentication. Anthropic $ openshell provider create --name anthropic-prod --type anthropic --from-existing\nThis reads ANTHROPIC_API_KEY from your environment. Step 2: Set Inference Routing Point inference.local at that provider and choose the model to use: $ openshell inference set\nprovider nvidia-prod\nmodel nvidia/nemotron-3-nano-30b-a3b\nStep 3: Verify the Active Config Confirm that the provider and model are set correctly: $ openshell inference get\nGateway inference\nProvider: nvidia-prod\nModel: nvidia/nemotron-3-nano-30b-a3b\nVersion: 1\nStep 4: Update Part of the Config Use update when you want to change only one field: $ openshell inference update --model nvidia/nemotron-3-nano-30b-a3b\nOr switch providers without repeating the current model: $ openshell inference update --provider openai-prod\nUse It from a Sandbox After inference is configured, code inside any sandbox can call https://inference.local directly: from openai import OpenAI\nclient = OpenAI(base_url=\"https://inference.local/v1\", api_key=\"dummy\nresponse = client.chat.completions.create\nmodel=\"anything\nmessages=[{\"role\": \"user\", \"content\": \"Hello\nThe client-supplied model is ignored for generation requests. OpenShell rewrites it to the configured model before forwarding upstream. Use this endpoint when inference should stay local to the host for privacy and security reasons. External providers that should be reached directly belong in network_policies instead. Verify the Endpoint from a Sandbox openshell inference get confirms the configuration was saved, but does not verify the upstream endpoint is reachable. To confirm end-to-end connectivity, connect to a sandbox and run: curl https://inference.local/v1/responses\nH \"Content-Type: application/json\"\nd\ninstructions\": \"You are a helpful assistant\ninput\": \"Hello\nA successful response confirms the privacy router can reach the configured backend and the model is serving requests. Gateway-scoped — every sandbox on the active gateway sees the same inference.local backend. HTTPS only — inference.local is intercepted only for HTTPS traffic. Next Steps Explore related topics: To understand the inference routing flow and supported API patterns, refer to index . To control external endpoints, refer to Network Access Rules . To manage provider records, refer to ../sandboxes/providers . To view openshell inference commands, refer to ../reference/cli","format":"text","summary":"This page covers the managed local inference endpoint (https://inference.local). External inference endpoints go through sandbox network_policies — refer to Network Access Rules for details.","headings":[{"text":"Configure Inference Routing","level":1},{"text":"Step 1: Create a Provider","level":2},{"text":"Step 2: Set Inference Routing","level":2},{"text":"Step 3: Verify the Active Config","level":2},{"text":"Step 4: Update Part of the Config","level":2},{"text":"Use It from a Sandbox","level":2},{"text":"Verify the Endpoint from a Sandbox","level":3},{"text":"Next Steps","level":2}]}
+1 -1
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
File diff suppressed because one or more lines are too long
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
@@ -758,6 +758,35 @@
</table>
</div>
<p>Only the following binaries can use these endpoints: <code class="docutils literal notranslate"><span class="pre">/usr/bin/curl</span></code>, <code class="docutils literal notranslate"><span class="pre">/usr/bin/wget</span></code>, <code class="docutils literal notranslate"><span class="pre">/sandbox/.cursor-server/**</span></code>.</p>
<h3>opencode</h3>
<div class="pst-scrollable-table-container"><table class="table">
<thead>
<tr class="row-odd"><th class="head"><p>Endpoint</p></th>
<th class="head"><p>Port</p></th>
<th class="head"><p>TLS</p></th>
<th class="head"><p>Access</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">registry.npmjs.org</span></code></p></td>
<td><p>443</p></td>
<td><p>—</p></td>
<td><p>L4 passthrough</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">opencode.ai</span></code></p></td>
<td><p>443</p></td>
<td><p>—</p></td>
<td><p>L4 passthrough</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">integrate.api.nvidia.com</span></code></p></td>
<td><p>443</p></td>
<td><p>—</p></td>
<td><p>L4 passthrough</p></td>
</tr>
</tbody>
</table>
</div>
<p>Only the following binaries can use these endpoints: <code class="docutils literal notranslate"><span class="pre">/usr/lib/node_modules/opencode-ai/bin/.opencode</span></code>, <code class="docutils literal notranslate"><span class="pre">/usr/bin/node</span></code>, <code class="docutils literal notranslate"><span class="pre">/usr/local/bin/opencode</span></code>.</p>
</section>
</section>
File diff suppressed because one or more lines are too long
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
File diff suppressed because one or more lines are too long
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
@@ -1 +1 @@
{"id":"reference/support-matrix","title":"Support Matrix","url":"reference/support-matrix.html","last_modified":"2026-03-12T09:12:26.597241+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"content":"Support Matrix This page lists the platform, software, runtime, and kernel requirements for running OpenShell. Supported Platforms OpenShell publishes multi-architecture container images for linux/amd64 and linux/arm64 . The CLI is supported on the following host platforms: Platform Architecture Status Linux (Debian/Ubuntu) x86_64 (amd64) Supported Linux (Debian/Ubuntu) aarch64 (arm64) Supported macOS (Docker Desktop) Apple Silicon (arm64) Supported macOS (Docker Desktop) Intel (amd64) Supported Windows (WSL 2 + Docker Desktop) x86_64 Untested Software Prerequisites The following software must be installed on the host before using the OpenShell CLI: Component Minimum Version Notes Python 3.12 Python 3.12 and 3.13 are supported. uv 0.9 Used to install the CLI ( uv pip install openshell ). Docker Desktop or Docker Engine — Must be running before any openshell command. No minimum version is enforced. Sandbox Runtime Versions The base sandbox container image ships the following components. These versions apply to sandboxes created with the default image ( ghcr.io/nvidia/openshell/sandbox ). Component Version Base OS Debian Bookworm Python 3.12.13 Node.js 22.22.1 npm 11.11.0 uv 0.10.8 Claude Code Latest (installed at image build time) OpenCode 1.2.18 Codex 0.111.0 Container Images OpenShell uses several container images that are pulled automatically during gateway startup and sandbox creation. All images are published for linux/amd64 and linux/arm64 . Image Registry Reference Pulled When Cluster ghcr.io ghcr.io/nvidia/openshell/cluster:latest openshell gateway start Gateway ghcr.io ghcr.io/nvidia/openshell/gateway:latest Cluster startup (via Helm chart) Sandbox ghcr.io ghcr.io/nvidia/openshell/sandbox:latest First sandbox creation (via Helm chart) Community sandboxes GHCR ghcr.io/nvidia/openshell-community/sandboxes/{name}:latest openshell sandbox create --from <name> The cluster image is based on rancher/k3s:v1.35.2-k3s1 and bundles the Helm charts and Kubernetes manifests required to bootstrap the control plane. The server and sandbox images are pulled separately at runtime. To override the default image references, set the following environment variables: Variable Purpose OPENSHELL_CLUSTER_IMAGE Override the cluster image reference. OPENSHELL_COMMUNITY_REGISTRY Override the registry for community sandbox images. Kernel Requirements OpenShell enforces sandbox isolation through two Linux kernel security modules: Module Requirement Details Landlock LSM Recommended Enforces filesystem access restrictions at the kernel level. The best_effort compatibility mode uses the highest Landlock ABI the host kernel supports. The hard_requirement mode fails sandbox creation if the required ABI is unavailable. seccomp Required Filters dangerous system calls. Available on all modern Linux kernels (3.17+). On macOS, these kernel modules run inside the Docker Desktop Linux VM, not on the host kernel. Agent Compatibility For the full list of supported agents and their default policy coverage, refer to the Supported Agents table","format":"text","summary":"This page lists the platform, software, runtime, and kernel requirements for running OpenShell.","headings":[{"text":"Support Matrix","level":1},{"text":"Supported Platforms","level":2},{"text":"Software Prerequisites","level":2},{"text":"Sandbox Runtime Versions","level":2},{"text":"Container Images","level":2},{"text":"Kernel Requirements","level":2},{"text":"Agent Compatibility","level":2}]}
{"id":"reference/support-matrix","title":"Support Matrix","url":"reference/support-matrix.html","last_modified":"2026-03-12T23:38:42.375601+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"content":"Support Matrix This page lists the platform, software, runtime, and kernel requirements for running OpenShell. Supported Platforms OpenShell publishes multi-architecture container images for linux/amd64 and linux/arm64 . The CLI is supported on the following host platforms: Platform Architecture Status Linux (Debian/Ubuntu) x86_64 (amd64) Supported Linux (Debian/Ubuntu) aarch64 (arm64) Supported macOS (Docker Desktop) Apple Silicon (arm64) Supported macOS (Docker Desktop) Intel (amd64) Supported Windows (WSL 2 + Docker Desktop) x86_64 Untested Software Prerequisites The following software must be installed on the host before using the OpenShell CLI: Component Minimum Version Notes Python 3.12 Python 3.12 and 3.13 are supported. uv 0.9 Used to install the CLI ( uv pip install openshell ). Docker Desktop or Docker Engine — Must be running before any openshell command. No minimum version is enforced. Sandbox Runtime Versions The base sandbox container image ships the following components. These versions apply to sandboxes created with the default image ( ghcr.io/nvidia/openshell/sandbox ). Component Version Base OS Debian Bookworm Python 3.12.13 Node.js 22.22.1 npm 11.11.0 uv 0.10.8 Claude Code Latest (installed at image build time) OpenCode 1.2.18 Codex 0.111.0 Container Images OpenShell uses several container images that are pulled automatically during gateway startup and sandbox creation. All images are published for linux/amd64 and linux/arm64 . Image Registry Reference Pulled When Cluster ghcr.io ghcr.io/nvidia/openshell/cluster:latest openshell gateway start Gateway ghcr.io ghcr.io/nvidia/openshell/gateway:latest Cluster startup (via Helm chart) Sandbox ghcr.io ghcr.io/nvidia/openshell/sandbox:latest First sandbox creation (via Helm chart) Community sandboxes GHCR ghcr.io/nvidia/openshell-community/sandboxes/{name}:latest openshell sandbox create --from <name> The cluster image is based on rancher/k3s:v1.35.2-k3s1 and bundles the Helm charts and Kubernetes manifests required to bootstrap the control plane. The server and sandbox images are pulled separately at runtime. To override the default image references, set the following environment variables: Variable Purpose OPENSHELL_CLUSTER_IMAGE Override the cluster image reference. OPENSHELL_COMMUNITY_REGISTRY Override the registry for community sandbox images. Kernel Requirements OpenShell enforces sandbox isolation through two Linux kernel security modules: Module Requirement Details Landlock LSM Recommended Enforces filesystem access restrictions at the kernel level. The best_effort compatibility mode uses the highest Landlock ABI the host kernel supports. The hard_requirement mode fails sandbox creation if the required ABI is unavailable. seccomp Required Filters dangerous system calls. Available on all modern Linux kernels (3.17+). On macOS, these kernel modules run inside the Docker Desktop Linux VM, not on the host kernel. Agent Compatibility For the full list of supported agents and their default policy coverage, refer to the Supported Agents table","format":"text","summary":"This page lists the platform, software, runtime, and kernel requirements for running OpenShell.","headings":[{"text":"Support Matrix","level":1},{"text":"Supported Platforms","level":2},{"text":"Software Prerequisites","level":2},{"text":"Sandbox Runtime Versions","level":2},{"text":"Container Images","level":2},{"text":"Kernel Requirements","level":2},{"text":"Agent Compatibility","level":2}]}
+1 -1
View File
@@ -382,7 +382,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
+1 -1
View File
@@ -1 +1 @@
{"id":"resources/eula","title":"License","url":"resources/eula.html","last_modified":"2026-03-12T09:12:26.607534+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"NVIDIA OpenShell license agreement and terms of use.","tags":["License","EULA"],"topics":["Legal"],"content_type":"reference","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"License","format":"text","summary":"<!-- SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 --> License","headings":[{"text":"License","level":1}]}
{"id":"resources/eula","title":"License","url":"resources/eula.html","last_modified":"2026-03-12T23:38:42.435768+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"NVIDIA OpenShell license agreement and terms of use.","tags":["License","EULA"],"topics":["Legal"],"content_type":"reference","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"License","format":"text","summary":"<!-- SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 --> License","headings":[{"text":"License","level":1}]}
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="current nav bd-sidenav">
@@ -1 +1 @@
{"id":"sandboxes/community-sandboxes","title":"Community Sandboxes","url":"sandboxes/community-sandboxes.html","last_modified":"2026-03-12T09:12:26.635368+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Use pre-built sandboxes from the OpenShell Community catalog or contribute your own.","tags":["Community","Sandbox","Container Image","Open Source"],"topics":["Generative AI","Cybersecurity"],"content_type":"concept","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"Community Sandboxes Use pre-built sandboxes from the OpenShell Community catalog, or contribute your\nown. What Are Community Sandboxes Community sandboxes are ready-to-use environments published in the\nOpenShell Community repository\nEach sandbox bundles a Dockerfile, policy, optional skills, and startup scripts\ninto a single package that you can launch with one command. Current Catalog The following community sandboxes are available in the catalog. Sandbox Description base Foundational image with system tools and dev environment openclaw Open agent manipulation and control sdg Synthetic data generation workflows simulation General-purpose simulation sandboxes Use a Community Sandbox Launch a community sandbox by name with the --from flag: $ openshell sandbox create --from openclaw\nWhen you pass --from with a community sandbox name, the CLI: Resolves the name against the\nOpenShell Community repository. Pulls the Dockerfile, policy, skills, and any startup scripts. Builds the container image locally. Creates the sandbox with the bundled configuration applied. You end up with a running sandbox whose image, policy, and tooling are all\npreconfigured by the community package. Other Sources The --from flag also accepts: Local directory paths: Point to a directory on disk that contains a\nDockerfile and optional policy/skills: $ openshell sandbox create --from ./my-sandbox-dir\nContainer image references: Use an existing container image directly: $ openshell sandbox create --from my-registry.example.com/my-image:latest\nContribute a Community Sandbox Each community sandbox is a directory under sandboxes/ in the\nOpenShell Community repository\nAt minimum, a sandbox directory must contain: Dockerfile : Defines the container image README.md : Describes the sandbox and how to use it Optional files: policy.yaml : Default policy applied when the sandbox launches skills/ : Agent skill definitions bundled with the sandbox Startup scripts: Any scripts the Dockerfile or entrypoint invokes To contribute, fork the repository, add your sandbox directory, and open a pull\nrequest. Refer to the repository’s\nCONTRIBUTING.md\nfor submission guidelines. The community catalog is designed to grow. If you have built a sandbox that\nsupports a particular workflow (data processing, simulation, code review\nor anything else), consider contributing it back so others can use it. Next Steps Explore related topics: Need to supply API keys or tokens? Set up providers for credential management. Want to customize the sandbox policy? Write custom rules in policies","format":"text","summary":"Use pre-built sandboxes from the OpenShell Community catalog, or contribute your own.","headings":[{"text":"Community Sandboxes","level":1},{"text":"What Are Community Sandboxes","level":2},{"text":"Current Catalog","level":2},{"text":"Use a Community Sandbox","level":2},{"text":"Other Sources","level":3},{"text":"Contribute a Community Sandbox","level":2},{"text":"Next Steps","level":2}]}
{"id":"sandboxes/community-sandboxes","title":"Community Sandboxes","url":"sandboxes/community-sandboxes.html","last_modified":"2026-03-12T23:38:42.409112+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Use pre-built sandboxes from the OpenShell Community catalog or contribute your own.","tags":["Community","Sandbox","Container Image","Open Source"],"topics":["Generative AI","Cybersecurity"],"content_type":"concept","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"Community Sandboxes Use pre-built sandboxes from the OpenShell Community catalog, or contribute your\nown. What Are Community Sandboxes Community sandboxes are ready-to-use environments published in the\nOpenShell Community repository\nEach sandbox bundles a Dockerfile, policy, optional skills, and startup scripts\ninto a single package that you can launch with one command. Current Catalog The following community sandboxes are available in the catalog. Sandbox Description base Foundational image with system tools and dev environment openclaw Open agent manipulation and control sdg Synthetic data generation workflows simulation General-purpose simulation sandboxes Use a Community Sandbox Launch a community sandbox by name with the --from flag: $ openshell sandbox create --from openclaw\nWhen you pass --from with a community sandbox name, the CLI: Resolves the name against the\nOpenShell Community repository. Pulls the Dockerfile, policy, skills, and any startup scripts. Builds the container image locally. Creates the sandbox with the bundled configuration applied. You end up with a running sandbox whose image, policy, and tooling are all\npreconfigured by the community package. Other Sources The --from flag also accepts: Local directory paths: Point to a directory on disk that contains a\nDockerfile and optional policy/skills: $ openshell sandbox create --from ./my-sandbox-dir\nContainer image references: Use an existing container image directly: $ openshell sandbox create --from my-registry.example.com/my-image:latest\nContribute a Community Sandbox Each community sandbox is a directory under sandboxes/ in the\nOpenShell Community repository\nAt minimum, a sandbox directory must contain: Dockerfile : Defines the container image README.md : Describes the sandbox and how to use it Optional files: policy.yaml : Default policy applied when the sandbox launches skills/ : Agent skill definitions bundled with the sandbox Startup scripts: Any scripts the Dockerfile or entrypoint invokes To contribute, fork the repository, add your sandbox directory, and open a pull\nrequest. Refer to the repository’s\nCONTRIBUTING.md\nfor submission guidelines. The community catalog is designed to grow. If you have built a sandbox that\nsupports a particular workflow (data processing, simulation, code review\nor anything else), consider contributing it back so others can use it. Next Steps Explore related topics: Need to supply API keys or tokens? Set up providers for credential management. Want to customize the sandbox policy? Write custom rules in policies","format":"text","summary":"Use pre-built sandboxes from the OpenShell Community catalog, or contribute your own.","headings":[{"text":"Community Sandboxes","level":1},{"text":"What Are Community Sandboxes","level":2},{"text":"Current Catalog","level":2},{"text":"Use a Community Sandbox","level":2},{"text":"Other Sources","level":3},{"text":"Contribute a Community Sandbox","level":2},{"text":"Next Steps","level":2}]}
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="current nav bd-sidenav">
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="current nav bd-sidenav">
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -822,7 +822,7 @@ window.addEventListener("load", load);</script>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="current nav bd-sidenav">
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="current nav bd-sidenav">
+1 -1
View File
@@ -1 +1 @@
{"id":"sandboxes/providers","title":"Providers","url":"sandboxes/providers.html","last_modified":"2026-03-12T09:12:26.656605+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Create and manage credential providers that inject API keys and tokens into OpenShell sandboxes.","tags":["Providers","Credentials","API Keys","Sandbox","Security"],"topics":["Generative AI","Cybersecurity"],"content_type":"how_to","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"Providers AI agents typically need credentials to access external services: an API key for the AI model provider, a token for GitHub or GitLab, and so on. OpenShell manages these credentials as first-class entities called providers . Create and manage providers that supply credentials to sandboxes. Create a Provider Providers can be created from local environment variables or with explicit credential values. From Local Credentials The fastest way to create a provider is to let the CLI discover credentials from\nyour shell environment: $ openshell provider create --name my-claude --type claude --from-existing\nThis reads ANTHROPIC_API_KEY or CLAUDE_API_KEY from your current environment\nand stores them in the provider. With Explicit Credentials Supply a credential value directly: $ openshell provider create --name my-api --type generic --credential API_KEY=sk-abc123\nBare Key Form Pass a key name without a value to read the value from the environment variable\nof that name: $ openshell provider create --name my-api --type generic --credential API_KEY\nThis looks up the current value of $API_KEY in your shell and stores it. Manage Providers List, inspect, update, and delete providers from the active cluster. List all providers: $ openshell provider list\nInspect a provider: $ openshell provider get my-claude\nUpdate a provider’s credentials: $ openshell provider update my-claude --type claude --from-existing\nDelete a provider: $ openshell provider delete my-claude\nAttach Providers to Sandboxes Pass one or more --provider flags when creating a sandbox: $ openshell sandbox create --provider my-claude --provider my-github -- claude\nEach --provider flag attaches one provider. The sandbox receives all\ncredentials from every attached provider at runtime. Providers cannot be added to a running sandbox. If you need to attach an\nadditional provider, delete the sandbox and recreate it with all required\nproviders specified. Auto-Discovery Shortcut When the trailing command in openshell sandbox create is a recognized tool name ( claude , codex , or opencode ), the CLI auto-creates the required\nprovider from your local credentials if one does not already exist. You do not\nneed to create the provider separately: $ openshell sandbox create -- claude\nThis detects claude as a known tool, finds your ANTHROPIC_API_KEY , creates\na provider, attaches it to the sandbox, and launches Claude Code. Supported Provider Types The following provider types are supported. Type Environment Variables Injected Typical Use claude ANTHROPIC_API_KEY , CLAUDE_API_KEY Claude Code, Anthropic API codex OPENAI_API_KEY OpenAI Codex opencode OPENCODE_API_KEY , OPENROUTER_API_KEY , OPENAI_API_KEY opencode tool github GITHUB_TOKEN , GH_TOKEN GitHub API, gh CLI — refer to /tutorials/github-sandbox gitlab GITLAB_TOKEN , GLAB_TOKEN , CI_JOB_TOKEN GitLab API, glab CLI nvidia NVIDIA_API_KEY NVIDIA API Catalog generic User-defined Any service with custom credentials outlook (none: no auto-discovery) Microsoft Outlook integration Use the generic type for any service not listed above. You define the\nenvironment variable names and values yourself with --credential . Next Steps Explore related topics: To control what the agent can access, refer to policies . To use a pre-built environment, refer to the community-sandboxes catalog. To view the complete field reference for the policy YAML, refer to the Policy Schema Reference","format":"text","summary":"AI agents typically need credentials to access external services: an API key for the AI model provider, a token for GitHub or GitLab, and so on. OpenShell manages these credentials as first-class entities called providers.","headings":[{"text":"Providers","level":1},{"text":"Create a Provider","level":2},{"text":"From Local Credentials","level":3},{"text":"With Explicit Credentials","level":3},{"text":"Bare Key Form","level":3},{"text":"Manage Providers","level":2},{"text":"Attach Providers to Sandboxes","level":2},{"text":"Auto-Discovery Shortcut","level":3},{"text":"Supported Provider Types","level":2},{"text":"Next Steps","level":2}]}
{"id":"sandboxes/providers","title":"Providers","url":"sandboxes/providers.html","last_modified":"2026-03-12T23:38:42.422131+00:00","book":{"title":"NVIDIA OpenShell Developer Guide","version":"0.1.0"},"product":{"name":"OpenShell","version":"0.1.0"},"description":"Create and manage credential providers that inject API keys and tokens into OpenShell sandboxes.","tags":["Providers","Credentials","API Keys","Sandbox","Security"],"topics":["Generative AI","Cybersecurity"],"content_type":"how_to","learning_level":"technical_beginner","audience":["engineer","data_scientist"],"content":"Providers AI agents typically need credentials to access external services: an API key for the AI model provider, a token for GitHub or GitLab, and so on. OpenShell manages these credentials as first-class entities called providers . Create and manage providers that supply credentials to sandboxes. Create a Provider Providers can be created from local environment variables or with explicit credential values. From Local Credentials The fastest way to create a provider is to let the CLI discover credentials from\nyour shell environment: $ openshell provider create --name my-claude --type claude --from-existing\nThis reads ANTHROPIC_API_KEY or CLAUDE_API_KEY from your current environment\nand stores them in the provider. With Explicit Credentials Supply a credential value directly: $ openshell provider create --name my-api --type generic --credential API_KEY=sk-abc123\nBare Key Form Pass a key name without a value to read the value from the environment variable\nof that name: $ openshell provider create --name my-api --type generic --credential API_KEY\nThis looks up the current value of $API_KEY in your shell and stores it. Manage Providers List, inspect, update, and delete providers from the active cluster. List all providers: $ openshell provider list\nInspect a provider: $ openshell provider get my-claude\nUpdate a provider’s credentials: $ openshell provider update my-claude --type claude --from-existing\nDelete a provider: $ openshell provider delete my-claude\nAttach Providers to Sandboxes Pass one or more --provider flags when creating a sandbox: $ openshell sandbox create --provider my-claude --provider my-github -- claude\nEach --provider flag attaches one provider. The sandbox receives all\ncredentials from every attached provider at runtime. Providers cannot be added to a running sandbox. If you need to attach an\nadditional provider, delete the sandbox and recreate it with all required\nproviders specified. Auto-Discovery Shortcut When the trailing command in openshell sandbox create is a recognized tool name ( claude , codex , or opencode ), the CLI auto-creates the required\nprovider from your local credentials if one does not already exist. You do not\nneed to create the provider separately: $ openshell sandbox create -- claude\nThis detects claude as a known tool, finds your ANTHROPIC_API_KEY , creates\na provider, attaches it to the sandbox, and launches Claude Code. Supported Provider Types The following provider types are supported. Type Environment Variables Injected Typical Use claude ANTHROPIC_API_KEY , CLAUDE_API_KEY Claude Code, Anthropic API codex OPENAI_API_KEY OpenAI Codex opencode OPENCODE_API_KEY , OPENROUTER_API_KEY , OPENAI_API_KEY opencode tool github GITHUB_TOKEN , GH_TOKEN GitHub API, gh CLI — refer to /tutorials/github-sandbox gitlab GITLAB_TOKEN , GLAB_TOKEN , CI_JOB_TOKEN GitLab API, glab CLI nvidia NVIDIA_API_KEY NVIDIA API Catalog generic User-defined Any service with custom credentials outlook (none: no auto-discovery) Microsoft Outlook integration Use the generic type for any service not listed above. You define the\nenvironment variable names and values yourself with --credential . Next Steps Explore related topics: To control what the agent can access, refer to policies . To use a pre-built environment, refer to the community-sandboxes catalog. To view the complete field reference for the policy YAML, refer to the Policy Schema Reference","format":"text","summary":"AI agents typically need credentials to access external services: an API key for the AI model provider, a token for GitHub or GitLab, and so on. OpenShell manages these credentials as first-class entities called providers.","headings":[{"text":"Providers","level":1},{"text":"Create a Provider","level":2},{"text":"From Local Credentials","level":3},{"text":"With Explicit Credentials","level":3},{"text":"Bare Key Form","level":3},{"text":"Manage Providers","level":2},{"text":"Attach Providers to Sandboxes","level":2},{"text":"Auto-Discovery Shortcut","level":3},{"text":"Supported Provider Types","level":2},{"text":"Next Steps","level":2}]}
+1 -1
View File
@@ -815,7 +815,7 @@ window.addEventListener("load", load);</script>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="tutorials/github-sandbox.html">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="tutorials/github-sandbox.html">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
File diff suppressed because one or more lines are too long
+142 -105
View File
@@ -387,7 +387,7 @@
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul class="current nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../get-started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1 current active"><a class="current reference internal" href="#">Tutorial: GitHub Policy Iteration</a></li>
<li class="toctree-l1 current active"><a class="current reference internal" href="#">GitHub Policy Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
@@ -469,7 +469,8 @@
-->
<section class="tex2jax_ignore mathjax_ignore" id="set-up-a-sandbox-of-claude-code-with-a-custom-github-policy">
<h1>Set Up a Sandbox of Claude Code with a Custom GitHub Policy<a class="headerlink" href="#set-up-a-sandbox-of-claude-code-with-a-custom-github-policy" title="Link to this heading">#</a></h1>
<p>This tutorial walks through the iterative policy workflow. You launch a sandbox, ask Claude Code to push code to GitHub, get blocked by the default network policy, diagnose the denial from two angles — the OpenShell Terminal on your laptop and the sandbox logs from inside — and then apply a custom policy to fix it, all without recreating the sandbox.</p>
<p>This tutorial walks through an iterative sandbox policy workflow. You launch a sandbox, ask Claude Code to push code to GitHub, and observe the default network policy denying the request.
You then diagnose the denial from your machine and from inside the sandbox, apply a policy update, and verify that the policy update to the sandbox takes effect.</p>
<p>After completing this tutorial, you will have:</p>
<ul class="simple">
<li><p>A running sandbox with Claude Code that can push to a GitHub repository.</p></li>
@@ -478,68 +479,70 @@
</ul>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>This tutorial shows example prompts and responses from Claude Code. The exact wording you see may differ between sessions — use the examples as a guide for the type of interaction, not as expected output.</p>
<p>This tutorial shows example prompts and responses from Claude Code. The exact wording you see might vary between sessions. Use the examples as a guide for the type of interaction, not as expected output.</p>
</div>
<section id="prerequisites">
<h2>Prerequisites<a class="headerlink" href="#prerequisites" title="Link to this heading">#</a></h2>
<p>This tutorial requires the following:</p>
<ul class="simple">
<li><p>Completed the <a class="reference internal" href="../get-started/quickstart.html"><span class="doc">Quickstart</span></a> tutorial.</p></li>
<li><p>A GitHub personal access token (PAT) with <code class="docutils literal notranslate"><span class="pre">repo</span></code> scope. To create one, go to <a class="reference external" href="https://github.com/settings/tokens" rel="noreferer noopener" target="_blank">GitHub Settings &gt; Developer settings &gt; Personal access tokens</a>, select <strong>Generate new token (classic)</strong>, check the <code class="docutils literal notranslate"><span class="pre">repo</span></code> scope, and copy the token.</p></li>
<li><p>Your own <a class="reference external" href="https://console.anthropic.com/" rel="noreferer noopener" target="_blank">Anthropic account</a> for Claude Code. OpenShell provides the sandbox, not the agent — you need your own account to log in to Claude Code.</p></li>
<li><p>A public GitHub repository you own (used as the push target). A scratch or test repository works well — the tutorial pushes a small file to it. You can <a class="reference external" href="https://github.com/new" rel="noreferer noopener" target="_blank">create a new repository</a> with a README if you do not have one handy.</p></li>
<li><p>A working OpenShell installation. Complete the <a class="reference internal" href="../get-started/quickstart.html"><span class="doc">Quickstart</span></a> before proceeding.</p></li>
<li><p>A GitHub personal access token (PAT) with <code class="docutils literal notranslate"><span class="pre">repo</span></code> scope. Generate one from the <a class="reference external" href="https://github.com/settings/tokens" rel="noreferer noopener" target="_blank">GitHub personal access token settings page</a> by selecting <strong>Generate new token (classic)</strong> and enabling the <code class="docutils literal notranslate"><span class="pre">repo</span></code> scope.</p></li>
<li><p>An <a class="reference external" href="https://console.anthropic.com/" rel="noreferer noopener" target="_blank">Anthropic account</a> with access to Claude Code. OpenShell provides the sandbox runtime, not the agent. You must authenticate with your own account.</p></li>
<li><p>A GitHub repository you own to use as the push target. A scratch repository is sufficient. You can <a class="reference external" href="https://github.com/new" rel="noreferer noopener" target="_blank">create one</a> with a README if needed.</p></li>
</ul>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>This tutorial uses two terminals throughout:</p>
<p>This tutorial uses two terminals to demonstrate the iterative policy workflow:</p>
<ul class="simple">
<li><p><strong>Terminal 1 (sandbox)</strong> — The terminal where you launch the sandbox. Claude Code runs here. You interact with the agent in this terminal.</p></li>
<li><p><strong>Terminal 2 (laptop)</strong> — A separate terminal on your laptop. You use this for <code class="docutils literal notranslate"><span class="pre">openshell</span> <span class="pre">term</span></code>, <code class="docutils literal notranslate"><span class="pre">openshell</span> <span class="pre">policy</span> <span class="pre">set</span></code>, and other CLI commands that manage the sandbox from the outside.</p></li>
<li><p><strong>Terminal 1</strong>: The sandbox terminal. You create the sandbox in this terminal by running <code class="docutils literal notranslate"><span class="pre">openshell</span> <span class="pre">sandbox</span> <span class="pre">create</span></code> and interact with Claude Code inside it.</p></li>
<li><p><strong>Terminal 2</strong>: A terminal outside the sandbox on your machine. You use this terminal for viewing the sandbox logs with <code class="docutils literal notranslate"><span class="pre">openshell</span> <span class="pre">term</span></code> and applying an updated policy with <code class="docutils literal notranslate"><span class="pre">openshell</span> <span class="pre">policy</span> <span class="pre">set</span></code>.</p></li>
</ul>
<p>Each section below indicates which terminal to use.</p>
</div>
</section>
<section id="launch-the-sandbox">
<h2>Launch the Sandbox<a class="headerlink" href="#launch-the-sandbox" title="Link to this heading">#</a></h2>
<p><strong>Terminal 1 (sandbox)</strong> — Create a sandbox and start Claude Code. No custom policy is needed yet — the <a class="reference internal" href="../reference/default-policy.html"><span class="doc">default policy</span></a> is applied automatically.</p>
<section id="set-up-a-sandbox-with-your-github-token">
<h2>Set Up a Sandbox with Your GitHub Token<a class="headerlink" href="#set-up-a-sandbox-with-your-github-token" title="Link to this heading">#</a></h2>
<p>Depending on whether you start a new sandbox or use an existing sandbox, choose the appropriate tab and follow the instructions.</p>
<div class="sd-tab-set docutils">
<input checked="checked" id="sd-tab-item-0" name="sd-tab-set-0" type="radio">
<label class="sd-tab-label" for="sd-tab-item-0">
Starting a new sandbox</label><div class="sd-tab-content docutils">
<p>In terminal 2, create a new sandbox with Claude Code. The <a class="reference internal" href="../reference/default-policy.html"><span class="doc">default policy</span></a> is applied automatically, which allows read-only access to GitHub.</p>
<p>Create a <a class="reference internal" href="../sandboxes/providers.html"><span class="doc">credential provider</span></a> that injects your GitHub token into the sandbox automatically. The provider reads <code class="docutils literal notranslate"><span class="pre">GITHUB_TOKEN</span></code> from your host environment and sets it as an environment variable inside the sandbox:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span><span class="nv">GITHUB_TOKEN</span><span class="o">=</span>&lt;your-token&gt;
<span class="gp">$ </span>openshell<span class="w"> </span>provider<span class="w"> </span>create<span class="w"> </span>--name<span class="w"> </span>my-github<span class="w"> </span>--type<span class="w"> </span>github<span class="w"> </span>--from-existing
<span class="gp">$ </span>openshell<span class="w"> </span>sandbox<span class="w"> </span>create<span class="w"> </span>--provider<span class="w"> </span>my-github<span class="w"> </span>--keep<span class="w"> </span>--<span class="w"> </span>claude
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">--keep</span></code> flag keeps the sandbox running after Claude Code exits, so you can apply policy updates later without recreating the environment.</p>
<p>Claude Code starts inside the sandbox. It prints an authentication link. Open it in your browser, sign in to your Anthropic account, and return to the terminal. When prompted, trust the <code class="docutils literal notranslate"><span class="pre">/sandbox</span></code> workspace to allow Claude Code to read and write files.</p>
</div>
<input id="sd-tab-item-1" name="sd-tab-set-0" type="radio">
<label class="sd-tab-label" for="sd-tab-item-1">
Using an existing sandbox</label><div class="sd-tab-content docutils">
<p>Connect to a sandbox that is already running and set your GitHub token as an environment variable:</p>
<p>In terminal 1, connect to a sandbox that is already running and set your GitHub token as an environment variable:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>openshell<span class="w"> </span>sandbox<span class="w"> </span>connect<span class="w"> </span>&lt;sandbox-name&gt;
<span class="gp">$ </span><span class="nb">export</span><span class="w"> </span><span class="nv">GITHUB_TOKEN</span><span class="o">=</span>&lt;your-token&gt;
</pre></div>
</div>
<p>To find the name of running sandboxes, run <code class="docutils literal notranslate"><span class="pre">openshell</span> <span class="pre">sandbox</span> <span class="pre">list</span></code> in terminal 2.</p>
</div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">--keep</span></code> flag keeps the sandbox running after Claude Code exits, so you can apply policy updates later without recreating the environment.</p>
<p>Claude Code starts inside the sandbox. Log in through your preferred authentication method and trust the <code class="docutils literal notranslate"><span class="pre">/sandbox</span></code> workspace when prompted.</p>
</section>
<section id="push-code-to-github">
<h2>Push Code to GitHub<a class="headerlink" href="#push-code-to-github" title="Link to this heading">#</a></h2>
<p><strong>Terminal 1 (sandbox)</strong> — Ask Claude Code to write a simple script and push it to your repository:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Write a hello_world.py script and push it to https://github.com/&lt;org&gt;/&lt;repo&gt;.
</pre></div>
<p>In terminal 1, ask Claude Code to write a simple script and push it to your repository. Replace <code class="docutils literal notranslate"><span class="pre">&lt;org&gt;</span></code> with your GitHub organization or username and <code class="docutils literal notranslate"><span class="pre">&lt;repo&gt;</span></code> with your repository name.</p>
<details class="sd-sphinx-override sd-dropdown sd-card sd-mb-3" open="open">
<summary class="sd-summary-title sd-card-header">
<span class="sd-summary-icon"><svg version="1.1" width="1.0em" height="1.0em" class="sd-octicon sd-octicon-terminal" viewBox="0 0 16 16" aria-hidden="true"><path d="M0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0 1 14.25 15H1.75A1.75 1.75 0 0 1 0 13.25Zm1.75-.25a.25.25 0 0 0-.25.25v10.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V2.75a.25.25 0 0 0-.25-.25ZM7.25 8a.749.749 0 0 1-.22.53l-2.25 2.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L5.44 8 3.72 6.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.25 2.25c.141.14.22.331.22.53Zm1.5 1.5h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5Z"></path></svg></span><span class="sd-summary-text">Prompt</span><span class="sd-summary-state-marker sd-summary-chevron-right"><svg version="1.1" width="1.5em" height="1.5em" class="sd-octicon sd-octicon-chevron-right" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.72 18.78a.75.75 0 0 1 0-1.06L14.44 12 8.72 6.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l6.25 6.25a.75.75 0 0 1 0 1.06l-6.25 6.25a.75.75 0 0 1-1.06 0Z"></path></svg></span></summary><div class="sd-summary-content sd-card-body docutils">
<p class="sd-card-text">Write a <code class="docutils literal notranslate"><span class="pre">hello_world.py</span></code> script and push it to <code class="docutils literal notranslate"><span class="pre">https://github.com/&lt;org&gt;/&lt;repo&gt;</span></code>.</p>
</div>
<p>Claude recognizes that it needs GitHub credentials. It asks how you want to authenticate. Provide your GitHub personal access token by pasting it into the conversation. Claude configures authentication and attempts the push.</p>
<p>The push fails. Claude reports an error — but the failure is not an authentication problem. The default sandbox policy does not permit outbound requests to GitHub, so the proxy blocks the connection before the request reaches GitHub’s servers.</p>
</details><p>Claude recognizes that it needs GitHub credentials. It asks how you want to authenticate. Provide your GitHub personal access token by pasting it into the conversation. Claude configures authentication and attempts the push.</p>
<p>The push fails. Claude reports an error, but the failure is not an authentication problem. The default sandbox policy permits read-only access to GitHub and blocks write operations, so the proxy denies the push before the request reaches the GitHub server.</p>
</section>
<section id="diagnose-the-denial">
<h2>Diagnose the Denial<a class="headerlink" href="#diagnose-the-denial" title="Link to this heading">#</a></h2>
<section id="view-the-logs-from-your-laptop">
<h3>View the logs from your laptop<a class="headerlink" href="#view-the-logs-from-your-laptop" title="Link to this heading">#</a></h3>
<p><strong>Terminal 2 (laptop)</strong> — Open a separate terminal on your laptop and launch the OpenShell Terminal:</p>
<p>In this section, you diagnose the denial from your machine and from inside the sandbox.</p>
<section id="view-the-logs-from-your-machine">
<h3>View the Logs from Your Machine<a class="headerlink" href="#view-the-logs-from-your-machine" title="Link to this heading">#</a></h3>
<p>In terminal 2, launch the OpenShell terminal:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>openshell<span class="w"> </span>term
</pre></div>
</div>
@@ -556,36 +559,52 @@ l7_deny_reason: PUT /repos/&lt;org&gt;/&lt;repo&gt;/contents/hello_world.py not
</div>
<p>The log shows that the sandbox proxy intercepted an outbound <code class="docutils literal notranslate"><span class="pre">PUT</span></code> request to <code class="docutils literal notranslate"><span class="pre">api.github.com</span></code> and denied it. The <code class="docutils literal notranslate"><span class="pre">github_rest_api</span></code> policy allows read operations (GET) but blocks write operations (PUT, POST, DELETE) to the GitHub API. A similar denial appears for <code class="docutils literal notranslate"><span class="pre">github.com</span></code> if Claude attempted a git push over HTTPS.</p>
</section>
<section id="ask-claude-to-check-the-sandbox-logs">
<h3>Ask Claude to check the sandbox logs<a class="headerlink" href="#ask-claude-to-check-the-sandbox-logs" title="Link to this heading">#</a></h3>
<p><strong>Terminal 1 (sandbox)</strong> — Switch back to Claude Code. Ask it to check the sandbox logs for denied requests:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Check the sandbox logs for any denied network requests. What is blocking the push?
</pre></div>
<section id="ask-claude-code-to-check-the-sandbox-logs">
<h3>Ask Claude Code to Check the Sandbox Logs<a class="headerlink" href="#ask-claude-code-to-check-the-sandbox-logs" title="Link to this heading">#</a></h3>
<p>In terminal 1, ask Claude Code to check the sandbox logs for denied requests:</p>
<details class="sd-sphinx-override sd-dropdown sd-card sd-mb-3" open="open">
<summary class="sd-summary-title sd-card-header">
<span class="sd-summary-icon"><svg version="1.1" width="1.0em" height="1.0em" class="sd-octicon sd-octicon-terminal" viewBox="0 0 16 16" aria-hidden="true"><path d="M0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0 1 14.25 15H1.75A1.75 1.75 0 0 1 0 13.25Zm1.75-.25a.25.25 0 0 0-.25.25v10.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V2.75a.25.25 0 0 0-.25-.25ZM7.25 8a.749.749 0 0 1-.22.53l-2.25 2.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L5.44 8 3.72 6.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.25 2.25c.141.14.22.331.22.53Zm1.5 1.5h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5Z"></path></svg></span><span class="sd-summary-text">Prompt</span><span class="sd-summary-state-marker sd-summary-chevron-right"><svg version="1.1" width="1.5em" height="1.5em" class="sd-octicon sd-octicon-chevron-right" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.72 18.78a.75.75 0 0 1 0-1.06L14.44 12 8.72 6.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l6.25 6.25a.75.75 0 0 1 0 1.06l-6.25 6.25a.75.75 0 0 1-1.06 0Z"></path></svg></span></summary><div class="sd-summary-content sd-card-body docutils">
<p class="sd-card-text">Check the sandbox logs for any denied network requests. What is blocking the push?</p>
</div>
<p>Claude reads the deny entries and identifies the root cause. It explains that the failure is a sandbox network policy restriction, not a token permissions issue:</p>
<blockquote>
<div><p>The sandbox runs a proxy that enforces policies on outbound traffic. The
<code class="docutils literal notranslate"><span class="pre">github_rest_api</span></code> policy allows GET requests (used to read the file) but blocks
PUT/write requests to GitHub. This is a sandbox-level restriction, not a token
issue — no matter what token you provide, pushes via the API will be blocked
until the policy is updated.</p>
</div></blockquote>
<p>Both perspectives confirm the same thing: the proxy is doing its job. The default policy is designed to be restrictive. To allow GitHub pushes, you need to update the network policy.</p>
<p>Copy the deny reason from Claude’s response — you will paste it into your laptop agent in the next step.</p>
</details><p>Claude reads the deny entries and identifies the root cause. It explains that the failure is a sandbox network policy restriction, not a token permissions issue. For example, the following is a possible response:</p>
<details class="sd-sphinx-override sd-dropdown sd-card sd-mb-3" open="open">
<summary class="sd-summary-title sd-card-header">
<span class="sd-summary-icon"><svg version="1.1" width="1.0em" height="1.0em" class="sd-octicon sd-octicon-comment" viewBox="0 0 16 16" aria-hidden="true"><path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></span><span class="sd-summary-text">Response</span><span class="sd-summary-state-marker sd-summary-chevron-right"><svg version="1.1" width="1.5em" height="1.5em" class="sd-octicon sd-octicon-chevron-right" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.72 18.78a.75.75 0 0 1 0-1.06L14.44 12 8.72 6.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l6.25 6.25a.75.75 0 0 1 0 1.06l-6.25 6.25a.75.75 0 0 1-1.06 0Z"></path></svg></span></summary><div class="sd-summary-content sd-card-body docutils">
<p class="sd-card-text">The sandbox runs a proxy that enforces policies on outbound traffic.
The <code class="docutils literal notranslate"><span class="pre">github_rest_api</span></code> policy allows GET requests (used to read the file)
but blocks PUT/write requests to GitHub. This is a sandbox-level restriction,
not a token issue. No matter what token you provide, pushes through the API
will be blocked until the policy is updated.</p>
</div>
</details><p>Both perspectives confirm the same thing: the proxy is doing its job. The default policy is designed to be restrictive. To allow GitHub pushes, you need to update the network policy.</p>
<p>Copy the deny reason from Claude’s response. You paste it into an agent running on your machine in the next step.</p>
</section>
</section>
<section id="update-the-policy-from-your-laptop">
<h2>Update the Policy from Your Laptop<a class="headerlink" href="#update-the-policy-from-your-laptop" title="Link to this heading">#</a></h2>
<p><strong>Terminal 2 (laptop)</strong> — Paste the deny reason from the previous step into your coding agent (for example, Claude Code or Cursor running on your laptop) and ask it to update the sandbox policy. The deny reason gives the agent the context it needs to generate the correct policy rules.</p>
<p>The agent inspects the deny reasons, writes an updated policy that adds <code class="docutils literal notranslate"><span class="pre">github_git</span></code> and <code class="docutils literal notranslate"><span class="pre">github_api</span></code> blocks for your repository, and runs <code class="docutils literal notranslate"><span class="pre">openshell</span> <span class="pre">policy</span> <span class="pre">set</span></code> to apply it:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>openshell<span class="w"> </span>policy<span class="w"> </span><span class="nb">set</span><span class="w"> </span>&lt;sandbox-name&gt;<span class="w"> </span>--policy<span class="w"> </span>/tmp/sandbox-policy-update.yaml<span class="w"> </span>--wait
</pre></div>
<section id="update-the-policy-from-your-machine">
<h2>Update the Policy from Your Machine<a class="headerlink" href="#update-the-policy-from-your-machine" title="Link to this heading">#</a></h2>
<p>In terminal 2, paste the deny reason from the previous step into your coding agent on your machine, such as Claude Code or Cursor, and ask it to recommend a policy update. The deny reason gives the agent the context it needs to generate the correct policy rules. After pasting the following prompt sample, properly provide the GitHub organization and repository names of the repository you are pushing to.</p>
<details class="sd-sphinx-override sd-dropdown sd-card sd-mb-3" open="open">
<summary class="sd-summary-title sd-card-header">
<span class="sd-summary-icon"><svg version="1.1" width="1.0em" height="1.0em" class="sd-octicon sd-octicon-terminal" viewBox="0 0 16 16" aria-hidden="true"><path d="M0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0 1 14.25 15H1.75A1.75 1.75 0 0 1 0 13.25Zm1.75-.25a.25.25 0 0 0-.25.25v10.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V2.75a.25.25 0 0 0-.25-.25ZM7.25 8a.749.749 0 0 1-.22.53l-2.25 2.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L5.44 8 3.72 6.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.25 2.25c.141.14.22.331.22.53Zm1.5 1.5h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5Z"></path></svg></span><span class="sd-summary-text">Prompt</span><span class="sd-summary-state-marker sd-summary-chevron-right"><svg version="1.1" width="1.5em" height="1.5em" class="sd-octicon sd-octicon-chevron-right" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.72 18.78a.75.75 0 0 1 0-1.06L14.44 12 8.72 6.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l6.25 6.25a.75.75 0 0 1 0 1.06l-6.25 6.25a.75.75 0 0 1-1.06 0Z"></path></svg></span></summary><div class="sd-summary-content sd-card-body docutils">
<p class="sd-card-text">Based on the following deny reasons, recommend a sandbox policy update that allows GitHub pushes to <code class="docutils literal notranslate"><span class="pre">https://github.com/&lt;org&gt;/&lt;repo&gt;</span></code>, and save to <code class="docutils literal notranslate"><span class="pre">/tmp/sandbox-policy-update.yaml</span></code>:</p>
<p class="sd-card-text">The <code class="docutils literal notranslate"><span class="pre">filesystem_policy</span></code>, <code class="docutils literal notranslate"><span class="pre">landlock</span></code>, and <code class="docutils literal notranslate"><span class="pre">process</span></code> sections are static. They are read once at sandbox creation and cannot be changed by a hot-reload. They are included here for completeness so the file is self-contained, but only the <code class="docutils literal notranslate"><span class="pre">network_policies</span></code> section takes effect when you apply this to a running sandbox.</p>
</div>
<p>Your coding agent generates both the policy file and this command. Network policies are hot-reloadable — the <code class="docutils literal notranslate"><span class="pre">--wait</span></code> flag blocks until the policy engine confirms the new revision loaded, and the update takes effect immediately without restarting the sandbox or reconnecting Claude Code.</p>
</details><p>The following steps outline the expected process done by the agent:</p>
<ol class="arabic simple">
<li><p>Inspects the deny reasons.</p></li>
<li><p>Writes an updated policy that adds <code class="docutils literal notranslate"><span class="pre">github_git</span></code> and <code class="docutils literal notranslate"><span class="pre">github_api</span></code> blocks that grant write access to your repository.</p></li>
<li><p>Saves the policy to <code class="docutils literal notranslate"><span class="pre">/tmp/sandbox-policy-update.yaml</span></code>.</p></li>
</ol>
</section>
<section id="review-the-generated-policy">
<h2>Review the Generated Policy<a class="headerlink" href="#review-the-generated-policy" title="Link to this heading">#</a></h2>
<p>Refer to the following policy example to compare with the generated policy before applying it. Confirm that the policy grants only the access you expect. In this case, <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code> operations and GitHub REST API access scoped to a single repository.</p>
<details class="sd-sphinx-override sd-dropdown sd-card sd-mb-3">
<summary class="sd-summary-title sd-card-header">
<span class="sd-summary-text">Full reference policy</span><span class="sd-summary-state-marker sd-summary-chevron-right"><svg version="1.1" width="1.5em" height="1.5em" class="sd-octicon sd-octicon-chevron-right" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.72 18.78a.75.75 0 0 1 0-1.06L14.44 12 8.72 6.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l6.25 6.25a.75.75 0 0 1 0 1.06l-6.25 6.25a.75.75 0 0 1-1.06 0Z"></path></svg></span></summary><div class="sd-summary-content sd-card-body docutils">
<p class="sd-card-text">The following YAML shows a complete policy that extends the <a class="reference internal" href="../reference/default-policy.html"><span class="doc">default policy</span></a> with GitHub access for a single repository. This is representative of what a coding agent generates when asked to unblock GitHub pushes. Replace <code class="docutils literal notranslate"><span class="pre">&lt;org&gt;</span></code> with your GitHub organization or username and <code class="docutils literal notranslate"><span class="pre">&lt;repo&gt;</span></code> with your repository name.</p>
<span class="sd-summary-icon"><svg version="1.1" width="1.0em" height="1.0em" class="sd-octicon sd-octicon-code" viewBox="0 0 16 16" aria-hidden="true"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg></span><span class="sd-summary-text">Full reference policy</span><span class="sd-summary-state-marker sd-summary-chevron-right"><svg version="1.1" width="1.5em" height="1.5em" class="sd-octicon sd-octicon-chevron-right" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.72 18.78a.75.75 0 0 1 0-1.06L14.44 12 8.72 6.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l6.25 6.25a.75.75 0 0 1 0 1.06l-6.25 6.25a.75.75 0 0 1-1.06 0Z"></path></svg></span></summary><div class="sd-summary-content sd-card-body docutils">
<p class="sd-card-text">The following YAML shows a complete policy that extends the <a class="reference internal" href="../reference/default-policy.html"><span class="doc">default policy</span></a> with GitHub access for a single repository. Replace <code class="docutils literal notranslate"><span class="pre">&lt;org&gt;</span></code> with your GitHub organization or username and <code class="docutils literal notranslate"><span class="pre">&lt;repo&gt;</span></code> with your repository name.</p>
<p class="sd-card-text">The <code class="docutils literal notranslate"><span class="pre">filesystem_policy</span></code>, <code class="docutils literal notranslate"><span class="pre">landlock</span></code>, and <code class="docutils literal notranslate"><span class="pre">process</span></code> sections are static. They are read once at sandbox creation and cannot be changed by a hot-reload. They are included here for completeness so the file is self-contained, but only the <code class="docutils literal notranslate"><span class="pre">network_policies</span></code> section takes effect when you apply this to a running sandbox.</p>
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">1</span>
<span class="c1"># ── Static (locked at sandbox creation) ──────────────────────────</span>
@@ -639,54 +658,54 @@ until the policy is updated.</p>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/bin/bash</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/local/bin/opencode</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="w"> </span><span class="c1"># ── GitHub: git operations (clone, fetch, push) ──────────────</span>
<span class="w"> </span><span class="nt">github_git</span><span class="p">:</span>
<span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">github-git</span>
<span class="w"> </span><span class="nt">endpoints</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">github.com</span>
<span class="w"> </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">443</span>
<span class="w"> </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">rest</span>
<span class="w"> </span><span class="nt">tls</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">terminate</span>
<span class="w"> </span><span class="nt">enforcement</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">enforce</span>
<span class="w"> </span><span class="nt">rules</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
<span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">GET</span>
<span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/&lt;org&gt;/&lt;repo&gt;.git/info/refs*&quot;</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
<span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">POST</span>
<span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/&lt;org&gt;/&lt;repo&gt;.git/git-upload-pack&quot;</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
<span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">POST</span>
<span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/&lt;org&gt;/&lt;repo&gt;.git/git-receive-pack&quot;</span>
<span class="w"> </span><span class="nt">binaries</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/bin/git</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="w"> </span><span class="c1"># ── GitHub: REST API ─────────────────────────────────────────</span>
<span class="w"> </span><span class="nt">github_api</span><span class="p">:</span>
<span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">github-api</span>
<span class="w"> </span><span class="nt">endpoints</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">api.github.com</span>
<span class="w"> </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">443</span>
<span class="w"> </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">rest</span>
<span class="w"> </span><span class="nt">tls</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">terminate</span>
<span class="w"> </span><span class="nt">enforcement</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">enforce</span>
<span class="w"> </span><span class="nt">rules</span><span class="p">:</span>
<span class="w"> </span><span class="c1"># GraphQL API (used by gh CLI)</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
<span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">POST</span>
<span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/graphql&quot;</span>
<span class="w"> </span><span class="c1"># Full read-write access to the repository</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
<span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;*&quot;</span>
<span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/repos/&lt;org&gt;/&lt;repo&gt;/**&quot;</span>
<span class="w"> </span><span class="nt">binaries</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/local/bin/claude</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/local/bin/opencode</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/bin/gh</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/bin/curl</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="hll"><span class="w"> </span><span class="c1"># ── GitHub: git operations (clone, fetch, push) ──────────────</span>
</span><span class="hll">
</span><span class="hll"><span class="w"> </span><span class="nt">github_git</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">github-git</span>
</span><span class="hll"><span class="w"> </span><span class="nt">endpoints</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">github.com</span>
</span><span class="hll"><span class="w"> </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">443</span>
</span><span class="hll"><span class="w"> </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">rest</span>
</span><span class="hll"><span class="w"> </span><span class="nt">tls</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">terminate</span>
</span><span class="hll"><span class="w"> </span><span class="nt">enforcement</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">enforce</span>
</span><span class="hll"><span class="w"> </span><span class="nt">rules</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">GET</span>
</span><span class="hll"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/&lt;org&gt;/&lt;repo&gt;.git/info/refs*&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">POST</span>
</span><span class="hll"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/&lt;org&gt;/&lt;repo&gt;.git/git-upload-pack&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">POST</span>
</span><span class="hll"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/&lt;org&gt;/&lt;repo&gt;.git/git-receive-pack&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="nt">binaries</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/bin/git</span><span class="w"> </span><span class="p p-Indicator">}</span>
</span><span class="hll">
</span><span class="hll"><span class="w"> </span><span class="c1"># ── GitHub: REST API ─────────────────────────────────────────</span>
</span><span class="hll">
</span><span class="hll"><span class="w"> </span><span class="nt">github_api</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">github-api</span>
</span><span class="hll"><span class="w"> </span><span class="nt">endpoints</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">api.github.com</span>
</span><span class="hll"><span class="w"> </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">443</span>
</span><span class="hll"><span class="w"> </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">rest</span>
</span><span class="hll"><span class="w"> </span><span class="nt">tls</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">terminate</span>
</span><span class="hll"><span class="w"> </span><span class="nt">enforcement</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">enforce</span>
</span><span class="hll"><span class="w"> </span><span class="nt">rules</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="c1"># GraphQL API (used by gh CLI)</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">POST</span>
</span><span class="hll"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/graphql&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="c1"># Full read-write access to the repository</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">allow</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="nt">method</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;*&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;/repos/&lt;org&gt;/&lt;repo&gt;/**&quot;</span>
</span><span class="hll"><span class="w"> </span><span class="nt">binaries</span><span class="p">:</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/local/bin/claude</span><span class="w"> </span><span class="p p-Indicator">}</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/local/bin/opencode</span><span class="w"> </span><span class="p p-Indicator">}</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/bin/gh</span><span class="w"> </span><span class="p p-Indicator">}</span>
</span><span class="hll"><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="p p-Indicator">{</span><span class="nt"> path</span><span class="p">:</span><span class="w"> </span><span class="nv">/usr/bin/curl</span><span class="w"> </span><span class="p p-Indicator">}</span>
</span>
<span class="w"> </span><span class="c1"># ── Package managers ─────────────────────────────────────────</span>
<span class="w"> </span><span class="nt">pypi</span><span class="p">:</span>
@@ -745,18 +764,33 @@ until the policy is updated.</p>
</tbody>
</table>
</div>
<p class="sd-card-text">The remaining blocks (<code class="docutils literal notranslate"><span class="pre">claude_code</span></code>, <code class="docutils literal notranslate"><span class="pre">nvidia_inference</span></code>, <code class="docutils literal notranslate"><span class="pre">pypi</span></code>, <code class="docutils literal notranslate"><span class="pre">vscode</span></code>) are identical to the <a class="reference internal" href="../reference/default-policy.html"><span class="doc">default policy</span></a>. Sandbox behavior outside of GitHub operations is unchanged.</p>
<p class="sd-card-text">The remaining blocks (<code class="docutils literal notranslate"><span class="pre">claude_code</span></code>, <code class="docutils literal notranslate"><span class="pre">nvidia_inference</span></code>, <code class="docutils literal notranslate"><span class="pre">pypi</span></code>, <code class="docutils literal notranslate"><span class="pre">vscode</span></code>) are identical to the <a class="reference internal" href="../reference/default-policy.html"><span class="doc">default policy</span></a>. The default policy’s <code class="docutils literal notranslate"><span class="pre">github_ssh_over_https</span></code> and <code class="docutils literal notranslate"><span class="pre">github_rest_api</span></code> blocks are replaced by the <code class="docutils literal notranslate"><span class="pre">github_git</span></code> and <code class="docutils literal notranslate"><span class="pre">github_api</span></code> blocks above, which grant write access to the specified repository. Sandbox behavior outside of GitHub operations is unchanged.</p>
<p class="sd-card-text">For details on policy block structure, refer to <a class="reference internal" href="../sandboxes/index.html#network-access-rules"><span class="std std-ref">Network Access Rules</span></a>.</p>
</div>
</details></section>
<section id="apply-the-policy">
<h2>Apply the Policy<a class="headerlink" href="#apply-the-policy" title="Link to this heading">#</a></h2>
<p>After you have reviewed the generated policy, apply it to the running sandbox:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>openshell<span class="w"> </span>policy<span class="w"> </span><span class="nb">set</span><span class="w"> </span>&lt;sandbox-name&gt;<span class="w"> </span>--policy<span class="w"> </span>/tmp/sandbox-policy-update.yaml<span class="w"> </span>--wait
</pre></div>
</div>
<p>Network policies are hot-reloadable. The <code class="docutils literal notranslate"><span class="pre">--wait</span></code> flag blocks until the policy engine confirms the new revision loaded, and the update takes effect immediately without restarting the sandbox or reconnecting Claude Code.</p>
</section>
<section id="retry-the-push">
<h2>Retry the Push<a class="headerlink" href="#retry-the-push" title="Link to this heading">#</a></h2>
<p><strong>Terminal 1 (sandbox)</strong> — Switch back to Claude Code and ask it to retry the push:</p>
<p>In terminal 1, ask Claude Code to retry the push:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>The sandbox policy has been updated. Try pushing to the repository again.
</pre></div>
</div>
<p>The push completes successfully. The <code class="docutils literal notranslate"><span class="pre">openshell</span> <span class="pre">term</span></code> dashboard now shows <code class="docutils literal notranslate"><span class="pre">l7_decision=allow</span></code> entries for <code class="docutils literal notranslate"><span class="pre">api.github.com</span></code> and <code class="docutils literal notranslate"><span class="pre">github.com</span></code> where it previously showed denials.</p>
</section>
<section id="clean-up">
<h2>Clean Up<a class="headerlink" href="#clean-up" title="Link to this heading">#</a></h2>
<p>When you are finished, delete the sandbox to free cluster resources:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>openshell<span class="w"> </span>sandbox<span class="w"> </span>delete<span class="w"> </span>&lt;sandbox-name&gt;
</pre></div>
</div>
</section>
<section id="next-steps">
<h2>Next Steps<a class="headerlink" href="#next-steps" title="Link to this heading">#</a></h2>
<p>The following resources cover related topics in greater depth:</p>
@@ -818,15 +852,18 @@ until the policy is updated.</p>
<nav class="bd-toc-nav page-toc" aria-labelledby="pst-page-navigation-heading-2">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#prerequisites">Prerequisites</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#launch-the-sandbox">Launch the Sandbox</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#set-up-a-sandbox-with-your-github-token">Set Up a Sandbox with Your GitHub Token</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#push-code-to-github">Push Code to GitHub</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#diagnose-the-denial">Diagnose the Denial</a><ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#view-the-logs-from-your-laptop">View the logs from your laptop</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#ask-claude-to-check-the-sandbox-logs">Ask Claude to check the sandbox logs</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#view-the-logs-from-your-machine">View the Logs from Your Machine</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#ask-claude-code-to-check-the-sandbox-logs">Ask Claude Code to Check the Sandbox Logs</a></li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#update-the-policy-from-your-laptop">Update the Policy from Your Laptop</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#update-the-policy-from-your-machine">Update the Policy from Your Machine</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#review-the-generated-policy">Review the Generated Policy</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#apply-the-policy">Apply the Policy</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#retry-the-push">Retry the Push</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#clean-up">Clean Up</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#next-steps">Next Steps</a></li>
</ul>
</nav></div>
File diff suppressed because one or more lines are too long