Files
OpenShell/docs/tutorials/github-sandbox.mdx
Johnny Greco d7f921190b docs(policy): refresh policy documentation and references (#3563)
* docs(policy): correct schema and default policy guidance

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): add network recipes and update command reference

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): organize lifecycle guidance and troubleshooting

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): split policy overview into concepts and management tasks

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): reorganize network recipes as a cookbook

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): restructure schema reference by field group and protocol

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): align troubleshooting, advisor, and reference pages

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): fix first policy tutorial and security guidance

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): keep overview high level and move network rules to their own page

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): focus policy management on CLI workflows and remove command reference

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): clarify policy views and sandbox deletion in management guide

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): streamline network rule concepts and examples

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): correct request path wildcard semantics

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): rewrite policy advisor guide for clarity

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): clarify policy advisor scope, setup, and review

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): rewrite policy prover guide for clarity

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): explain the two uses of the policy prover

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): describe policy prover uses, boundaries, and coverage

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): place prover before advisor and troubleshooting last

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): remove unsupported CI guidance from prover page

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): tighten policy prover introduction

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): move policy change behavior into management guide

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): name prover check types and note expanding coverage

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): prefix prover and advisor sidebar labels

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): streamline policy schema reference

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): place default policy before schema reference

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): fold troubleshooting into policy management guide

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): correct tutorial log samples and GitHub push policy steps

The first policy tutorial said the 403 body begins with error, policy, and
rule, but the proxy serializes the body with sorted keys. Its log samples also
showed the wrong CONNECT deny reason for a sandbox without network rules, and
the L7 deny sample omitted the :443 authority, the `l7` engine, and the reason
tag that the shorthand formatter emits.

The GitHub tutorial filtered denials with `--level warn`, which hides the INFO
level OCSF policy events, and showed the retired key=value log format. Its
hand-written policy also omitted /bin from the restrictive default, so
`policy set` would reject the file for removing a filesystem path on a live
sandbox. Start from `policy get --base` and add only the network rules.

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): improve flow and terminology across policy pages

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): correct network rule matching and protocol details

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): align policy management steps with CLI behavior

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): correct policy advisor proposal and approval details

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): correct policy section, default, and schema details

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): correct prover installation and coverage limits

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): recommend tls skip for server-first protocols

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): fix stale baseline path and interpreter examples

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): move policy pages under how-it-works and fix links

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): align native TCP guidance in security best practices

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): restore policy.local and policy DNS details from main

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

* docs(policy): state exact glob matching rules

Signed-off-by: Johnny Greco <jogreco@nvidia.com>

---------

Signed-off-by: Johnny Greco <jogreco@nvidia.com>
2026-09-25 18:19:16 +00:00

228 lines
7.6 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: "tutorials/github-push-access"
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](/how-it-works/policies/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
Review the [Claude Code profile](https://github.com/NVIDIA/OpenShell/blob/main/providers/claude-code.yaml)
and [GitHub profile](https://github.com/NVIDIA/OpenShell/blob/main/providers/github.yaml).
Confirm that their `binaries` paths match the executables in your image, then
import them directly. If a path or endpoint grant needs to change, edit a local
copy and import it with `-f` instead.
```shell
openshell profile import --url https://raw.githubusercontent.com/NVIDIA/OpenShell/main/providers/claude-code.yaml --global
openshell profile import --url https://raw.githubusercontent.com/NVIDIA/OpenShell/main/providers/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 --since 5m --source sandbox
```
You should see a denial for a request resembling this one:
```text
[1775014140.412] [sandbox] [OCSF ] [ocsf] HTTP:POST [MED] DENIED POST http://github.com:443/<org>/<repo>.git/git-receive-pack [policy:_provider_my_github engine:l7] [reason:L7_REQUEST deny POST github.com:443/<org>/<repo>.git/git-receive-pack reason=POST /<org>/<repo>.git/git-receive-pack not permitted by policy]
```
`_provider_my_github` is the rule that OpenShell composes from the attached
`my-github` provider. Policy events are INFO-level log records, so do not filter
them out with `--level warn`.
You can also run `openshell term` to inspect policy decisions in the terminal
dashboard.
## Create a Repository-Scoped Policy
`policy set` replaces the complete base policy, so start from the sandbox's
current one. In terminal 2, print it:
```shell
openshell policy get github-demo --base
```
The command prints revision details followed by the policy. Save only the policy
YAML as `github-push.yaml`. Keep its filesystem, Landlock, and process settings
unchanged, because OpenShell rejects removed filesystem paths and changed
Landlock or process settings on a running sandbox.
Add these entries under `network_policies`, creating the section if it is
missing. Replace `<org>` and `<repo>`, and adjust `binaries` to match your
image:
```yaml
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.
## 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](/how-it-works/providers/profiles) for endpoint-scoped credential placement.
- Review [Manage Sandbox Policies](/how-it-works/policies/manage-policies) for incremental policy updates and policy history.
- Review the [Policy Schema](/how-it-works/policies/schema) for REST, GraphQL, and other protocol rules.