Files
OpenShell/pr-preview/pr-240/tutorials/github-sandbox.html
T
2026-03-11 22:30:42 +00:00

939 lines
66 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en" data-content_root="../" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Set Up a Sandbox of Claude Code with a Custom GitHub Policy &#8212; NVIDIA OpenShell Developer Guide</title>
<script data-cfasync="false">
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
document.documentElement.dataset.theme = localStorage.getItem("theme") || "";
</script>
<!--
this give us a css class that will be invisible only if js is disabled
-->
<noscript>
<style>
.pst-js-only { display: none !important; }
</style>
</noscript>
<!-- Loaded before other Sphinx assets -->
<link href="../_static/styles/theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" />
<link href="../_static/styles/pydata-sphinx-theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=8f2a1f02" />
<link rel="stylesheet" type="text/css" href="../_static/styles/nvidia-sphinx-theme.css?v=933278ad" />
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css?v=76b2166b" />
<link rel="stylesheet" type="text/css" href="../_static/enhanced-search.css?v=2e2db37d" />
<link rel="stylesheet" type="text/css" href="../_static/sphinx-design.min.css?v=95c83b7e" />
<!-- So that users can add custom icons -->
<script src="../_static/scripts/fontawesome.js?digest=8878045cc6db502f8baf"></script>
<!-- Pre-loaded scripts that we'll load fully later -->
<link rel="preload" as="script" href="../_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf" />
<link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf" />
<script src="../_static/documentation_options.js?v=2caa9db7"></script>
<script src="../_static/doctools.js?v=9a2dae69"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/clipboard.min.js?v=a7894cd8"></script>
<script src="../_static/copybutton.js?v=6dbb43f8"></script>
<script src="../_static/search-assets.bundle.js?v=00e3e057"></script>
<script src="../_static/design-tabs.js?v=f930bc37"></script>
<script>DOCUMENTATION_OPTIONS.pagename = 'tutorials/github-sandbox';</script>
<script>
DOCUMENTATION_OPTIONS.theme_version = '0.16.1';
DOCUMENTATION_OPTIONS.theme_switcher_json_url = '../versions1.json';
DOCUMENTATION_OPTIONS.theme_switcher_version_match = '0.1.0';
DOCUMENTATION_OPTIONS.show_version_warning_banner =
false;
</script>
<link rel="canonical" href="https://docs.nvidia.com/openshell/latest/tutorials/github-sandbox.html" />
<link rel="icon" href="../_static/favicon.png"/>
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="About Sandboxes" href="../sandboxes/index.html" />
<link rel="prev" title="Quickstart" href="../get-started/quickstart.html" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="docsearch:language" content="en"/>
<meta name="docsearch:version" content="" />
</head>
<body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode="">
<div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Skip to main content</a></div>
<div id="pst-scroll-pixel-helper"></div>
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
<i class="fa-solid fa-arrow-up"></i>Back to top</button>
<dialog id="pst-search-dialog">
<form class="bd-search d-flex align-items-center"
action="../search.html"
method="get">
<i class="fa-solid fa-magnifying-glass"></i>
<input type="search"
class="form-control"
name="q"
placeholder="Search the docs ..."
aria-label="Search the docs ..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"/>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
</form>
</dialog>
<div class="pst-async-banner-revealer d-none">
<aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Version warning"></aside>
</div>
<header class="bd-header navbar navbar-expand-lg bd-navbar d-print-none">
<div class="bd-header__inner bd-page-width">
<button class="pst-navbar-icon sidebar-toggle primary-toggle" aria-label="Site navigation">
<span class="fa-solid fa-bars"></span>
</button>
<div class="col-lg-3 navbar-header-items__start">
<div class="navbar-item">
<a class="navbar-brand logo" href="../index.html">
<img src="../_static/nvidia-logo-horiz-rgb-blk-for-screen.svg" class="logo__image only-light" alt="NVIDIA OpenShell Developer Guide - Home"/>
<img src="../_static/nvidia-logo-horiz-rgb-wht-for-screen.svg" class="logo__image only-dark pst-js-only" alt="NVIDIA OpenShell Developer Guide - Home"/>
<p class="title logo__title">NVIDIA OpenShell Developer Guide</p>
</a></div>
</div>
<div class="col-lg-9 navbar-header-items">
<div class="me-auto navbar-header-items__center">
<div class="navbar-item">
<div class="version-switcher__container dropdown pst-js-only">
<button id="pst-version-switcher-button-2"
type="button"
class="version-switcher__button btn btn-sm dropdown-toggle"
data-bs-toggle="dropdown"
aria-haspopup="listbox"
aria-controls="pst-version-switcher-list-2"
aria-label="Version switcher list"
>
Choose version <!-- this text may get changed later by javascript -->
<span class="caret"></span>
</button>
<div id="pst-version-switcher-list-2"
class="version-switcher__menu dropdown-menu list-group-flush py-0"
role="listbox" aria-labelledby="pst-version-switcher-button-2">
<!-- dropdown will be populated by javascript on page load -->
</div>
</div></div>
</div>
<div class="navbar-header-items__end">
<div class="navbar-item navbar-persistent--container">
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
</div>
<div class="navbar-item">
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
</button></div>
<div class="navbar-item"><ul class="navbar-icon-links"
aria-label="Icon Links">
<li class="nav-item">
<a href="https://github.com/NVIDIA/OpenShell" title="GitHub" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-github fa-lg" aria-hidden="true"></i>
<span class="sr-only">GitHub</span></a>
</li>
<li class="nav-item">
<a href="https://pypi.org/project/openshell/" title="PyPI" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-python fa-lg" aria-hidden="true"></i>
<span class="sr-only">PyPI</span></a>
</li>
</ul></div>
</div>
</div>
<div class="navbar-persistent--mobile">
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
</div>
<button class="pst-navbar-icon sidebar-toggle secondary-toggle" aria-label="On this page">
<span class="fa-solid fa-outdent"></span>
</button>
</div>
</header>
<div class="bd-container">
<div class="bd-container__inner bd-page-width">
<dialog id="pst-primary-sidebar-modal"></dialog>
<div id="pst-primary-sidebar" class="bd-sidebar-primary bd-sidebar">
<a class="navbar-brand logo" href="../index.html">
<img src="../_static/nvidia-logo-horiz-rgb-blk-for-screen.svg" class="logo__image only-light" alt="NVIDIA OpenShell Developer Guide - Home"/>
<img src="../_static/nvidia-logo-horiz-rgb-wht-for-screen.svg" class="logo__image only-dark pst-js-only" alt="NVIDIA OpenShell Developer Guide - Home"/>
<p class="title logo__title">NVIDIA OpenShell Developer Guide</p>
</a>
<div class="sidebar-header-items sidebar-primary__section">
<div class="sidebar-header-items__center">
<div class="navbar-item">
<div class="version-switcher__container dropdown pst-js-only">
<button id="pst-version-switcher-button-3"
type="button"
class="version-switcher__button btn btn-sm dropdown-toggle"
data-bs-toggle="dropdown"
aria-haspopup="listbox"
aria-controls="pst-version-switcher-list-3"
aria-label="Version switcher list"
>
Choose version <!-- this text may get changed later by javascript -->
<span class="caret"></span>
</button>
<div id="pst-version-switcher-list-3"
class="version-switcher__menu dropdown-menu list-group-flush py-0"
role="listbox" aria-labelledby="pst-version-switcher-button-3">
<!-- dropdown will be populated by javascript on page load -->
</div>
</div></div>
</div>
<div class="sidebar-header-items__end">
<div class="navbar-item">
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
</button></div>
<div class="navbar-item"><ul class="navbar-icon-links"
aria-label="Icon Links">
<li class="nav-item">
<a href="https://github.com/NVIDIA/OpenShell" title="GitHub" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-github fa-lg" aria-hidden="true"></i>
<span class="sr-only">GitHub</span></a>
</li>
<li class="nav-item">
<a href="https://pypi.org/project/openshell/" title="PyPI" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-python fa-lg" aria-hidden="true"></i>
<span class="sr-only">PyPI</span></a>
</li>
</ul></div>
</div>
</div>
<div class="sidebar-primary-items__start sidebar-primary__section">
<div class="sidebar-primary-item">
<nav class="bd-docs-nav bd-links"
aria-label="Table of Contents">
<p class="bd-links__title" role="heading" aria-level="1">Table of Contents</p>
<div class="bd-toc-item navbar-nav"><ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../index.html">Home</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">About NVIDIA OpenShell</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../about/overview.html">Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../about/architecture.html">How It Works</a></li>
<li class="toctree-l1"><a class="reference internal" href="../about/release-notes.html">Release Notes</a></li>
</ul>
<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="#">GitHub Policy Iteration Tutorial</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Sandboxes</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../sandboxes/index.html">About Sandboxes</a></li>
<li class="toctree-l1"><a class="reference internal" href="../sandboxes/create-and-manage.html">Create and Manage Sandboxes</a></li>
<li class="toctree-l1"><a class="reference internal" href="../sandboxes/providers.html">Providers</a></li>
<li class="toctree-l1"><a class="reference internal" href="../sandboxes/policies.html">Customize Sandbox Policies</a></li>
<li class="toctree-l1"><a class="reference internal" href="../sandboxes/community-sandboxes.html">Community Sandboxes</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Inference Routing</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../inference/index.html">About Inference Routing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../inference/configure.html">Configure Inference Routing</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Reference</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../reference/cli.html">CLI Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/default-policy.html">Default Policy Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/policy-schema.html">Policy Schema Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/support-matrix.html">Support Matrix</a></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Resources</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../resources/eula.html">License</a></li>
</ul>
</div>
</nav></div>
</div>
<div class="sidebar-primary-items__end sidebar-primary__section">
</div>
</div>
<main id="main-content" class="bd-main" role="main">
<div class="bd-content">
<div class="bd-article-container">
<div class="bd-header-article d-print-none">
<div class="header-article-items header-article__inner">
<div class="header-article-items__start">
<div class="header-article-item">
<nav aria-label="Breadcrumb" class="d-print-none">
<ul class="bd-breadcrumbs">
<li class="breadcrumb-item breadcrumb-home">
<a href="../index.html" class="nav-link" aria-label="Home">
<i class="fa-solid fa-home"></i>
</a>
</li>
<li class="breadcrumb-item active" aria-current="page"><span class="ellipsis">Set Up a Sandbox of Claude Code with a Custom GitHub Policy</span></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div id="searchbox"></div>
<article class="bd-article">
<!--
SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->
<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 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 custom policy, and verify that the policy update 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>
<li><p>A custom network policy that grants GitHub access for a specific repository.</p></li>
<li><p>Experience with the policy iteration workflow: fail, diagnose, update, verify.</p></li>
</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 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>
<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>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>To avoid pasting the token manually during the tutorial, you can configure a <a class="reference internal" href="../sandboxes/providers.html"><span class="doc">credential provider</span></a> to inject it automatically at sandbox startup:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><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 provider reads <code class="docutils literal notranslate"><span class="pre">GITHUB_TOKEN</span></code> from your host environment and exposes it as an environment variable inside the sandbox. Claude Code can then use it directly.</p>
</div>
</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>
<p>This tutorial uses two terminals to demonstrate the iterative policy workflow:</p>
<ul class="simple">
<li><p><strong>Terminal 1</strong>: The sandbox terminal. You create the sandbox here with <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 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>
</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>In terminal 1, create a sandbox and start Claude Code. No custom policy is needed. The <a class="reference internal" href="../reference/default-policy.html"><span class="doc">default policy</span></a> is applied automatically:</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>create<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>
</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>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>
<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>
</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 should fail. 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>
<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>
<p>The dashboard shows sandbox status and a live stream of policy decisions. Look for entries with <code class="docutils literal notranslate"><span class="pre">l7_decision=deny</span></code>. Select a deny entry to see the full detail:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>l7_action: PUT
l7_target: /repos/&lt;org&gt;/&lt;repo&gt;/contents/hello_world.py
l7_decision: deny
dst_host: api.github.com
dst_port: 443
l7_protocol: rest
policy: github_rest_api
l7_deny_reason: PUT /repos/&lt;org&gt;/&lt;repo&gt;/contents/hello_world.py not permitted by policy
</pre></div>
</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>In terminal 1, ask Claude Code 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>
</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 through 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>
</section>
</section>
<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, create a policy file that extends the <a class="reference internal" href="../reference/default-policy.html"><span class="doc">default policy</span></a> with GitHub write access for your repository. You can ask a coding agent on your machine, such as Claude Code or Cursor, to generate it from the deny reasons.
The updated policy should have <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>
<p>The following steps outline the expected process done by the agent:</p>
<ol class="arabic">
<li><p>Reads the default policy.</p></li>
<li><p>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.
Refer to the following policy example to compare with the policy the agent generated.</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-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>
<span class="nt">filesystem_policy</span><span class="p">:</span>
<span class="w"> </span><span class="nt">include_workdir</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="w"> </span><span class="nt">read_only</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/usr</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/lib</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/proc</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/dev/urandom</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/app</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/etc</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/var/log</span>
<span class="w"> </span><span class="nt">read_write</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/sandbox</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/tmp</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/dev/null</span>
<span class="nt">landlock</span><span class="p">:</span>
<span class="w"> </span><span class="nt">compatibility</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">best_effort</span>
<span class="nt">process</span><span class="p">:</span>
<span class="w"> </span><span class="nt">run_as_user</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">sandbox</span>
<span class="w"> </span><span class="nt">run_as_group</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">sandbox</span>
<span class="c1"># ── Dynamic (hot-reloadable) ─────────────────────────────────────</span>
<span class="nt">network_policies</span><span class="p">:</span>
<span class="w"> </span><span class="c1"># Claude Code ↔ Anthropic API</span>
<span class="w"> </span><span class="nt">claude_code</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">claude-code</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="p p-Indicator">{</span><span class="nt"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">api.anthropic.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</span><span class="p p-Indicator">,</span><span class="nt"> protocol</span><span class="p">:</span><span class="w"> </span><span class="nv">rest</span><span class="p p-Indicator">,</span><span class="nt"> enforcement</span><span class="p">:</span><span class="w"> </span><span class="nv">enforce</span><span class="p p-Indicator">,</span><span class="nt"> access</span><span class="p">:</span><span class="w"> </span><span class="nv">full</span><span class="p p-Indicator">,</span><span class="nt"> tls</span><span class="p">:</span><span class="w"> </span><span class="nv">terminate</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">statsig.anthropic.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">sentry.io</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">raw.githubusercontent.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">platform.claude.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</span><span class="w"> </span><span class="p p-Indicator">}</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/bin/node</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="w"> </span><span class="c1"># NVIDIA inference endpoint</span>
<span class="w"> </span><span class="nt">nvidia_inference</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">nvidia-inference</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="p p-Indicator">{</span><span class="nt"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">integrate.api.nvidia.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</span><span class="w"> </span><span class="p p-Indicator">}</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/curl</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">/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="w"> </span><span class="c1"># ── Package managers ─────────────────────────────────────────</span>
<span class="w"> </span><span class="nt">pypi</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">pypi</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="p p-Indicator">{</span><span class="nt"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">pypi.org</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">files.pythonhosted.org</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">github.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">objects.githubusercontent.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">api.github.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">downloads.python.org</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</span><span class="w"> </span><span class="p p-Indicator">}</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">/sandbox/.venv/bin/python</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">/sandbox/.venv/bin/python3</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">/sandbox/.venv/bin/pip</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">/app/.venv/bin/python</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">/app/.venv/bin/python3</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">/app/.venv/bin/pip</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/uv</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="s">&quot;/sandbox/.uv/python/**&quot;</span><span class="w"> </span><span class="p p-Indicator">}</span>
<span class="w"> </span><span class="c1"># ── VS Code Remote ──────────────────────────────────────────</span>
<span class="w"> </span><span class="nt">vscode</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">vscode</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="p p-Indicator">{</span><span class="nt"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">update.code.visualstudio.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;*.vo.msecnd.net&quot;</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">vscode.download.prss.microsoft.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="nv">marketplace.visualstudio.com</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</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"> host</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;*.gallerycdn.vsassets.io&quot;</span><span class="p p-Indicator">,</span><span class="nt"> port</span><span class="p">:</span><span class="w"> </span><span class="nv">443</span><span class="w"> </span><span class="p p-Indicator">}</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/curl</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/wget</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="s">&quot;/sandbox/.vscode-server/**&quot;</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="s">&quot;/sandbox/.vscode-remote-containers/**&quot;</span><span class="w"> </span><span class="p p-Indicator">}</span>
</pre></div>
</div>
<p class="sd-card-text">The following table summarizes the two GitHub-specific blocks:</p>
<div class="pst-scrollable-table-container"><table class="table">
<thead>
<tr class="row-odd"><th class="head"><p class="sd-card-text">Block</p></th>
<th class="head"><p class="sd-card-text">Endpoint</p></th>
<th class="head"><p class="sd-card-text">Behavior</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p class="sd-card-text"><code class="docutils literal notranslate"><span class="pre">github_git</span></code></p></td>
<td><p class="sd-card-text"><code class="docutils literal notranslate"><span class="pre">github.com:443</span></code></p></td>
<td><p class="sd-card-text">Git Smart HTTP protocol with TLS termination. Permits <code class="docutils literal notranslate"><span class="pre">info/refs</span></code> (clone/fetch), <code class="docutils literal notranslate"><span class="pre">git-upload-pack</span></code> (fetch data), and <code class="docutils literal notranslate"><span class="pre">git-receive-pack</span></code> (push) for the specified repository. Denies all operations on unlisted repositories.</p></td>
</tr>
<tr class="row-odd"><td><p class="sd-card-text"><code class="docutils literal notranslate"><span class="pre">github_api</span></code></p></td>
<td><p class="sd-card-text"><code class="docutils literal notranslate"><span class="pre">api.github.com:443</span></code></p></td>
<td><p class="sd-card-text">REST API with TLS termination. Permits all HTTP methods for the specified repository and GraphQL queries. Denies API access to unlisted repositories.</p></td>
</tr>
</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>. 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></li>
<li><p>Saves the policy to a file, such as <code class="docutils literal notranslate"><span class="pre">/tmp/sandbox-policy-update.yaml</span></code>.</p></li>
<li><p>Applies the policy to the running sandbox by running the following command:</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>
<div class="admonition note">
<p class="admonition-title">Note</p>
<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>
</div>
</li>
</ol>
</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>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>
<ul class="simple">
<li><p>To add per-repository access levels (read-write vs read-only) or restrict to specific API methods, refer to the <a class="reference internal" href="../reference/policy-schema.html"><span class="std std-doc">Policy Schema Reference</span></a>.</p></li>
<li><p>To learn the full policy iteration workflow (pull, edit, push, verify), refer to <a class="reference internal" href="../sandboxes/policies.html"><span class="doc">Customize Sandbox Policies</span></a>.</p></li>
<li><p>To inject credentials automatically instead of pasting tokens, refer to <a class="reference internal" href="../sandboxes/providers.html"><span class="doc">Providers</span></a>.</p></li>
</ul>
</section>
</section>
</article>
<footer class="prev-next-footer d-print-none">
<div class="prev-next-area">
<a class="left-prev"
href="../get-started/quickstart.html"
title="previous page">
<i class="fa-solid fa-angle-left"></i>
<div class="prev-next-info">
<p class="prev-next-subtitle">previous</p>
<p class="prev-next-title">Quickstart</p>
</div>
</a>
<a class="right-next"
href="../sandboxes/index.html"
title="next page">
<div class="prev-next-info">
<p class="prev-next-subtitle">next</p>
<p class="prev-next-title">About Sandboxes</p>
</div>
<i class="fa-solid fa-angle-right"></i>
</a>
</div>
</footer>
</div>
<dialog id="pst-secondary-sidebar-modal"></dialog>
<div id="pst-secondary-sidebar" class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
<div class="sidebar-secondary-item">
<div
id="pst-page-navigation-heading-2"
class="page-toc tocsection onthispage">
<i class="fa-solid fa-list"></i> On this page
</div>
<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="#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-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-to-check-the-sandbox-logs">Ask Claude 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-machine">Update the Policy from Your Machine</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>
</div></div>
</div>
<footer class="bd-footer-content">
</footer>
</main>
</div>
</div>
<!-- Scripts loaded after <body> so the DOM is not blocked -->
<script defer src="../_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf"></script>
<script defer src="../_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf"></script>
<footer class="bd-footer">
<div class="bd-footer__inner bd-page-width">
<div class="footer-items__start">
<div class="footer-item">
<a class="footer-brand logo" href="https://www.nvidia.com">
<img src="../_static/nvidia-logo-horiz-rgb-1c-blk-for-screen.svg" class="logo__image only-light" alt="NVIDIA"/>
<img src="../_static/nvidia-logo-horiz-rgb-1c-wht-for-screen.svg" class="logo__image only-dark" alt="NVIDIA"/>
</a></div>
<div class="footer-item">
<div class="footer-links">
<a class="external" href="https://www.nvidia.com/en-us/about-nvidia/privacy-policy/">Privacy Policy</a>
|
<a class="external" href="https://www.nvidia.com/en-us/about-nvidia/privacy-center/">Your Privacy Choices</a>
|
<a class="external" href="https://www.nvidia.com/en-us/about-nvidia/terms-of-service/">Terms of Service</a>
|
<a class="external" href="https://www.nvidia.com/en-us/about-nvidia/accessibility/">Accessibility</a>
|
<a class="external" href="https://www.nvidia.com/en-us/about-nvidia/company-policies/">Corporate Policies</a>
|
<a class="external" href="https://www.nvidia.com/en-us/product-security/">Product Security</a>
|
<a class="external" href="https://www.nvidia.com/en-us/contact/">Contact</a>
</div>
</div>
<div class="footer-item">
<p class="copyright">
Copyright © 2025-2026, NVIDIA Corporation.
<br/>
</p>
</div>
</div>
</div>
</footer>
</body>
</html>