Files
OpenShell/docs/get-started/tutorials/github-sandbox.mdx
Drew Newberry a649aa42fc docs: add 0.1.0 upgrade guide outline (#3540)
* docs: add 0.1.0 upgrade guide outline

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: add upgrade change provenance

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: update 0.1.0 upgrade guidance

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: move upgrade navigation below security

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: remove release notes page

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: announce OpenShell 0.1.0

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: reorganize guides and require user-owned images

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: reorganize navigation around core concepts

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: simplify navigation and tutorial catalog

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: refine 0.1.0 release highlights

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: align navigation and 0.1.0 guidance

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

---------

Signed-off-by: Drew Newberry <anewberry@nvidia.com>
2026-09-23 20:26:25 +00:00

224 lines
6.9 KiB
Plaintext

---
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
title: "Grant GitHub Push Access to a Sandboxed Agent"
sidebar-title: "GitHub Push Access"
slug: "get-started/tutorials/github-sandbox"
description: "Launch an agent with a GitHub provider, diagnose a denied push, and grant repository-scoped write access."
keywords: "Generative AI, Cybersecurity, Tutorial, GitHub, Sandbox, Policy, Claude Code"
---
This tutorial shows how provider access and sandbox policy work together. You
attach a GitHub provider that contributes read-only GitHub access, observe a
denied push, and add a user policy that permits writes to one repository.
The built-in [default policy](/reference/default-policy) does not grant network
access. Imported provider profiles contribute the endpoints and executable
paths needed by their providers.
## Prerequisites
You need:
- A working OpenShell installation and active gateway.
- An OCI image you built with Claude Code, `git`, and the GitHub CLI installed.
- An Anthropic API key.
- A GitHub fine-grained personal access token with read and write access to the
target repository's contents.
- A scratch GitHub repository that you can push to.
Use two host terminals. Terminal 1 runs the agent. Terminal 2 inspects denials
and updates policy.
<Steps toc={true}>
## Import the Provider Profiles
Download and review the Claude Code and GitHub profiles. Confirm that their
`binaries` paths match the executables in your image, then import them:
```shell
curl -LsSfO https://raw.githubusercontent.com/NVIDIA/OpenShell/main/providers/claude-code.yaml
curl -LsSfO https://raw.githubusercontent.com/NVIDIA/OpenShell/main/providers/github.yaml
openshell profile import -f claude-code.yaml --global
openshell profile import -f github.yaml --global
```
The gateway contains no built-in profiles. Import each profile once per gateway
at the scope where users need it.
## Create the Providers
Create provider instances from credentials in your host environment. Passing a
credential on the same command line exports it only to that command:
```shell
ANTHROPIC_API_KEY=<your-anthropic-key> \
openshell provider create --name my-claude --type claude-code --from-existing
GITHUB_TOKEN=<your-github-token> \
openshell provider create --name my-github --type github --from-existing
```
OpenShell stores the credentials through the configured credential driver. The
agent receives opaque placeholders; the sandbox proxy resolves them only for
endpoints allowed by the corresponding profile.
## Start the Agent
In terminal 1, start Claude Code from your image and attach both providers:
```shell
openshell sandbox create \
--name github-demo \
--from registry.example.com/your-org/claude-agent:latest \
--provider my-claude \
--provider my-github \
-- claude
```
To use an existing sandbox, attach the providers from a host terminal, then
start a new agent process so it receives the provider environment variables:
```shell
openshell sandbox provider attach <sandbox-name> my-claude
openshell sandbox provider attach <sandbox-name> my-github
openshell sandbox connect <sandbox-name>
```
## Attempt a Push
Ask the agent to create a file and push it to your scratch repository. Replace
`<org>` and `<repo>` with the repository owner and name:
```md title="Prompt" wordWrap showLineNumbers={false}
Create `hello_world.py`, commit it, and push it to
`https://github.com/<org>/<repo>.git`. Use the GitHub credentials already
available in the environment. Do not ask me to paste a token.
```
The push fails. The GitHub profile permits clone and fetch operations but does
not permit `git-receive-pack`, the Git Smart HTTP operation used for a push.
The credential remains attached and endpoint-scoped; changing the token would
not grant the missing network authority.
## Inspect the Denial
In terminal 2, inspect recent sandbox logs:
```shell
openshell logs github-demo --level warn --since 5m
```
You should see a denial for a request resembling this one:
```text
action=deny dst_host=github.com dst_port=443 binary=/usr/bin/git l7_action=POST l7_target=/<org>/<repo>.git/git-receive-pack
```
You can also run `openshell term` to inspect policy decisions in the terminal
dashboard.
## Create a Repository-Scoped Policy
Create `github-push.yaml`. Replace `<org>` and `<repo>`, and adjust `binaries`
to match your image:
```yaml
version: 1
filesystem_policy:
include_workdir: true
read_only: [/usr, /lib, /proc, /dev/urandom, /etc, /var/log]
read_write: [/tmp, /dev/null]
landlock:
compatibility: best_effort
network_policies:
github_repository_push:
name: github-repository-push
endpoints:
- host: github.com
port: 443
protocol: rest
enforcement: enforce
rules:
- allow:
method: GET
path: "/<org>/<repo>.git/info/refs*"
- allow:
method: POST
path: "/<org>/<repo>.git/git-upload-pack"
- allow:
method: POST
path: "/<org>/<repo>.git/git-receive-pack"
binaries:
- path: /usr/bin/git
- path: /usr/local/bin/git
github_repository_api:
name: github-repository-api
endpoints:
- host: api.github.com
port: 443
protocol: rest
enforcement: enforce
rules:
- allow:
method: "*"
path: "/repos/<org>/<repo>/**"
binaries:
- path: /usr/bin/gh
- path: /usr/local/bin/gh
```
The first entry grants Git Smart HTTP operations only for the selected
repository. The second lets `gh` use REST operations scoped to the same
repository. The attached GitHub provider continues to supply credential
placement and its broader read-only rules.
The filesystem and Landlock sections preserve the fallback policy's static
settings because `policy set` replaces the complete user-authored base policy.
Process identity remains omitted so the compute driver can select it.
## Apply the Policy
Apply the policy and wait for the new revision to load:
```shell
openshell policy set github-demo --policy github-push.yaml --wait
```
Network policy changes hot-reload without recreating the sandbox. Provider
rules are composed with this user-authored base policy.
## Retry and Verify
Ask the agent to retry the push. Then confirm that the proxy allowed the scoped
request:
```shell
openshell logs github-demo --since 5m
openshell policy get github-demo --full
```
The push succeeds for the selected repository. Requests to push to another
repository remain denied.
## Clean Up
Delete the sandbox when you are finished:
```shell
openshell sandbox delete github-demo
```
</Steps>
## Next Steps
- Review [Profiles](/providers/profiles) for endpoint-scoped credential placement.
- Review [Policies](/sandboxes/policies) for incremental policy updates and policy history.
- Review the [Policy Schema](/reference/policy-schema) for REST, GraphQL, and other protocol rules.