Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Sandbox Policy Quickstart

See how OpenShell's network policy system works in under five minutes. You'll create a sandbox, watch a request get blocked by the default-deny policy, apply a fine-grained L7 rule, and verify that reads are allowed while writes are blocked — all without restarting anything.

Prerequisites

  • A running OpenShell gateway (openshell gateway start)
  • Docker daemon running

What's in this example

File Description
policy.yaml L7 read-only policy for the GitHub REST API, scoped to curl
demo.sh Automated script that runs the full walkthrough non-interactively

Walkthrough

1. Create a sandbox

openshell sandbox create --name demo --keep --no-auto-providers

--keep keeps the sandbox running after you exit so you can reconnect later. --no-auto-providers skips the provider setup prompt since this demo doesn't use an AI agent.

You'll land in an interactive shell inside the sandbox:

sandbox@demo:~$

2. Try to reach the GitHub API — blocked

curl -s https://api.github.com/zen

The request fails. By default, all outbound network traffic is denied. The sandbox proxy intercepted the HTTPS CONNECT request to api.github.com:443 and rejected it because no network policy authorizes curl to reach that host.

curl: (56) Received HTTP code 403 from proxy after CONNECT

Exit the sandbox (the sandbox stays alive thanks to --keep):

exit

3. Check the deny log

openshell logs demo --since 5m

You'll see a line like:

action=deny dst_host=api.github.com dst_port=443 binary=/usr/bin/curl deny_reason="no matching network policy"

Every denied connection is logged with the destination, the binary that attempted it, and the reason. Nothing gets out silently.

4. Apply the read-only GitHub API policy

Review the policy:

cat examples/sandbox-policy-quickstart/policy.yaml
version: 1

# Default sandbox filesystem and process settings.
# These static fields are required when using `openshell policy set`
# because it replaces the entire policy.
filesystem_policy:
  include_workdir: true
  read_only: [/usr, /lib, /proc, /dev/urandom, /app, /etc, /var/log]
  read_write: [/sandbox, /tmp, /dev/null]
landlock:
  compatibility: best_effort
process:
  run_as_user: sandbox
  run_as_group: sandbox

network_policies:
  github_api:
    name: github-api-readonly
    endpoints:
      - host: api.github.com
        port: 443
        protocol: rest
        tls: terminate
        enforcement: enforce
        access: read-only
    binaries:
      - { path: /usr/bin/curl }

The top section preserves the default sandbox filesystem and process settings (required because policy set replaces the entire policy). The network_policies section is the interesting part: curl may make GET, HEAD, and OPTIONS requests to api.github.com over HTTPS. Everything else is denied. The proxy terminates TLS (tls: terminate) to inspect each HTTP request and enforce the read-only access preset at the method level.

Apply it:

openshell policy set demo \
  --policy examples/sandbox-policy-quickstart/policy.yaml \
  --wait

--wait blocks until the sandbox confirms the new policy is loaded. No restart required — policies are hot-reloaded.

5. Connect and verify: GET works

openshell sandbox connect demo
curl -s https://api.github.com/zen
Anything added dilutes everything else.

It works. Try a more visual endpoint:

curl -s https://api.github.com/octocat
               MMM.           .MMM
               MMMMMMMMMMMMMMMMMMM
               MMMMMMMMMMMMMMMMMMM      ____________________________
              MMMMMMMMMMMMMMMMMMMMM    |                            |
             MMMMMMMMMMMMMMMMMMMMMMM   | Speak like a human.       |
            MMMMMMMMMMMMMMMMMMMMMMMM   |_   ________________________|
            MMMM::- -:::::::- -::MMMM    |/
             MM~:~ 00~:::::~ 00~:~MM
        .. MMMMM::.00:::+:::.00teleMMM ..
              .MM::::: ._. :::::MM.
                 MMMM;:::::;MMMM
          -MM        MMMMMMM
          ^  M+     MMMMMMMMM
              MMMMMMM MM MM MM
                   MM MM MM MM
                   MM MM MM MM
                .~~MM~MM~MM~MM~~.
             ~~~~MM:~MM~~~MM~:MM~~~~
            ~~~~~~==googler======~~~~~~
             ~~~~~~==googler======
                 :MMMMMMMMMMM:
                 '=googler=='

6. Try a write — blocked by L7

curl -s -X POST https://api.github.com/repos/octocat/hello-world/issues \
  -H "Content-Type: application/json" \
  -d '{"title":"oops"}'
{"error":"policy_denied","policy":"github-api-readonly","detail":"POST /repos/octocat/hello-world/issues not permitted by policy"}

The CONNECT request succeeded (api.github.com is allowed), but the L7 proxy inspected the HTTP method and returned 403. POST is not in the read-only preset. Your agent can read code from GitHub but cannot create issues, push commits, or modify anything.

Exit the sandbox:

exit

7. Check the L7 deny log

openshell logs demo --level warn --since 5m
l7_decision=deny dst_host=api.github.com l7_action=POST l7_target=/repos/octocat/hello-world/issues l7_deny_reason="POST /repos/octocat/hello-world/issues not permitted by policy"

The log captures the exact HTTP method, path, and deny reason. In production, pipe these logs to your SIEM for a complete audit trail of every request your agent makes.

8. Clean up

openshell sandbox delete demo

What you just saw

State What happens
Default deny All outbound traffic blocked — nothing gets out
L7 read-only GET to api.github.com allowed, POST blocked
Audit trail Every request logged with method, path, decision

The policy hot-reloads in seconds and gives you verifiable, fine-grained control over what your agent can access — without --dangerously-skip-permissions.

Next steps

  • Customize the policy: Change access: read-only to read-write or add explicit rules for specific paths. See the security policy reference.
  • Scope to an agent: Replace the binaries section with your agent's binary (e.g., /usr/local/bin/claude) instead of curl.
  • Add more endpoints: Stack multiple policies in the same file to allow PyPI, npm, or your internal APIs.
  • Try audit mode: Set enforcement: audit to log violations without blocking, useful for building a policy iteratively.