Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 18 additions & 47 deletions docs/tutorials/github-sandbox.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title:
page: Set Up a Sandbox of Claude Code with a Custom GitHub Policy
nav: "Tutorial: GitHub Policy Iteration"
nav: GitHub Sandbox Tutorial
description: Learn the iterative policy workflow by launching a sandbox, diagnosing a GitHub access denial, and applying a custom policy to fix it.
topics:
- Generative AI
Expand Down Expand Up @@ -44,7 +44,19 @@ This tutorial requires the following:

- Completed the {doc}`Quickstart </get-started/quickstart>` tutorial.
- A GitHub personal access token (PAT) with `repo` scope. To create one, go to [GitHub Settings > Developer settings > Personal access tokens](https://github.com/settings/tokens), select **Generate new token (classic)**, check the `repo` scope, and copy the token.
- An agent API key configured in the environment. For example, `ANTHROPIC_API_KEY` for Claude Code.

:::{tip}
Instead of pasting the token into Claude during the tutorial, use a {doc}`credential provider </sandboxes/providers>` to inject it into the sandbox automatically at startup:

```console
$ openshell provider create --name my-github --type github --from-existing
$ openshell sandbox create --provider my-github --keep -- claude
```

The provider reads `GITHUB_TOKEN` from your host environment and sets it as an environment variable inside the sandbox so Claude can use it directly.
:::

- Your own [Anthropic account](https://console.anthropic.com/) for Claude Code. OpenShell provides the sandbox, not the agent — you need your own account to log in to Claude Code.
- 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 [create a new repository](https://github.com/new) with a README if you do not have one handy.

:::{important}
Expand All @@ -58,20 +70,7 @@ Each section below indicates which terminal to use.

## Launch the Sandbox

:::::{tab-set}

::::{tab-item} Starting a new sandbox

**Terminal 1 (sandbox)** — Create a sandbox and start Claude Code. No custom policy is needed yet — the {doc}`default policy </reference/default-policy>` is applied automatically.

The recommended approach is to create a {doc}`credential provider </sandboxes/providers>` that injects your GitHub token into the sandbox automatically. The provider reads `GITHUB_TOKEN` from your host environment and sets it as an environment variable inside the sandbox:

```console
$ openshell provider create --name my-github --type github --from-existing
$ openshell sandbox create --provider my-github --keep -- claude
```

If you prefer to handle authentication manually, you can skip the provider and create the sandbox without one:
**Terminal 1 (sandbox)** — Create a sandbox and start Claude Code. No custom policy is needed yet — the {doc}`default policy </reference/default-policy>` is applied automatically:

```console
$ openshell sandbox create --keep -- claude
Expand All @@ -81,34 +80,6 @@ The `--keep` flag keeps the sandbox running after Claude Code exits, so you can

Claude Code starts inside the sandbox. Log in through your preferred authentication method and trust the `/sandbox` workspace when prompted.

::::

::::{tab-item} Using an existing sandbox

If you already have a sandbox running from the Quickstart, you do not need to create a new one. Providers can only be attached at creation time, so you will set up GitHub authentication inside the sandbox instead.

**Terminal 1 (sandbox)** — Connect to your running sandbox:

```console
$ openshell sandbox connect <sandbox-name>
```

From inside the sandbox, set your GitHub token as an environment variable:

```console
$ export GITHUB_TOKEN=<your-token>
```

Or start Claude Code and paste the token when it asks for GitHub credentials in the next step:

```console
$ claude
```

::::

:::::

## Push Code to GitHub

**Terminal 1 (sandbox)** — Ask Claude Code to write a simple script and push it to your repository:
Expand All @@ -117,9 +88,9 @@ $ claude
Write a hello_world.py script and push it to https://github.com/<org>/<repo>.
```

If you used a provider or set `GITHUB_TOKEN` as an environment variable, Claude uses the token automatically. Otherwise, Claude recognizes that it needs GitHub credentials, asks how you want to authenticate, and you can paste your personal access token into the conversation.
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.

Either way, Claude configures authentication and attempts the push. The push fails — 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.
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.

## Diagnose the Denial

Expand Down Expand Up @@ -348,4 +319,4 @@ The following resources cover related topics in greater depth:

- To add per-repository access levels (read-write vs read-only) or restrict to specific API methods, refer to the [Policy Schema Reference](/reference/policy-schema.md).
- To learn the full policy iteration workflow (pull, edit, push, verify), refer to {doc}`/sandboxes/policies`.
- To inject credentials automatically instead of pasting tokens, refer to {doc}`/sandboxes/providers`.
- To inject credentials automatically instead of pasting tokens, refer to {doc}`/sandboxes/providers`.
Loading