mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-08 19:00:35 +08:00
* 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>
228 lines
7.6 KiB
Plaintext
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.
|