Skip to content
This repository was archived by the owner on Oct 7, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
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
32 changes: 32 additions & 0 deletions sandboxes/dsh/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# syntax=docker/dockerfile:1.4

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# DeepSeek Harness (dsh) sandbox image for OpenShell
#
# Builds on the community base sandbox and adds DeepSeek Harness's headless
# profile: a one-shot CLI runner (no GUI, no server, no open port), the
# shape this repo's other sandboxes use for a CLI-driven coding agent.
# Build: docker build -t openshell-dsh --build-arg BASE_IMAGE=openshell-base .
# Run: openshell sandbox create --from dsh

ARG BASE_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest
FROM ${BASE_IMAGE}

USER root

# Install DeepSeek Harness CLI (pinned for reproducibility). Developer
# preview: expect breaking changes between releases.
RUN npm install -g @deepseek-ai/dsh@0.2.0-rc.2

# Copy sandbox policy
COPY policy.yaml /etc/openshell/policy.yaml

# Harness home (DSH_HOME, default ~/.dsh): profiles, credentials, session log.
RUN mkdir -p /sandbox/.dsh && \
chown -R sandbox:sandbox /sandbox/.dsh

USER sandbox

ENTRYPOINT ["/bin/bash"]
51 changes: 51 additions & 0 deletions sandboxes/dsh/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# DeepSeek Harness Sandbox

OpenShell sandbox image pre-configured with [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`), an open-source, plugin-architected agent harness from DeepSeek AI.

> [!NOTE]
> DeepSeek Harness is in developer preview. Expect compatibility-breaking changes between releases.

## What's Included

- **DeepSeek Harness CLI** (`@deepseek-ai/dsh@0.2.0-rc.2`) — `dsh`, run via its `headless` profile
- Everything from the [base sandbox](../base/README.md)

## Build

```bash
docker build -t openshell-dsh .
```

To build against a specific base image:

```bash
docker build -t openshell-dsh --build-arg BASE_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest .
```

## Usage

### Create a sandbox

```bash
openshell sandbox create --from dsh
```

### Run a one-shot task

`dsh`'s `headless` profile runs a single task from the command line, prints the final answer, and exits — no GUI, no server, no open port. This is the profile to drive from an eval harness or a script:

```bash
dsh --profile headless "run the tests"
```

Pipe a task in instead of passing it as an argument:

```bash
{ echo "Summarize these changes:"; git diff --stat; } | dsh --profile headless
```

Pass `--json` for a newline-delimited JSON event stream (`session`, `status`, `text`, `thinking`, `tool_call`, `tool_result`, `final`) instead of plain text on stdout, and `--session-id <id>` to continue a previous conversation. Exit code 0 means the task completed; 1 means it aborted or errored.

## Configuration

DeepSeek Harness stores profiles, credentials, and the session log under its Harness home, `~/.dsh` by default (override with `$DSH_HOME`). See the [DeepSeek Harness docs](https://deepseek-harness.github.io/deepseek-harness/) for provider and plugin configuration.
210 changes: 210 additions & 0 deletions sandboxes/dsh/policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

version: 1

# --- Sandbox setup configuration (queried once at startup) ---

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 (queried per-CONNECT request) ---
#
# Each named policy maps a set of allowed (binary, endpoint) pairs.
# Binary identity is resolved via /proc/net/tcp inode lookup + /proc/{pid}/exe.
# Ancestors (/proc/{pid}/status PPid walk) and cmdline paths are also matched.
# SHA256 integrity is enforced in Rust via trust-on-first-use, not here.

network_policies:
claude_code:
name: claude-code
endpoints:
- { host: api.anthropic.com, port: 443, protocol: rest, enforcement: enforce, access: full, tls: terminate }
- { host: statsig.anthropic.com, port: 443 }
- { host: sentry.io, port: 443 }
- { host: raw.githubusercontent.com, port: 443 }
- { host: platform.claude.com, port: 443 }
binaries:
- { path: /usr/local/bin/claude }
- { path: /usr/bin/node }

github_ssh_over_https:
name: github-ssh-over-https
endpoints:
- host: github.com
port: 443
protocol: rest
tls: terminate
enforcement: enforce
rules:
# Git Smart HTTP read-only: allow clone, fetch, pull
# Discovery (query string is included in path matching)
- allow:
method: GET
path: "/**/info/refs*"
# Data transfer for reads (all repos)
- allow:
method: POST
path: "/**/git-upload-pack"
# Data transfer for writes
# - allow:
# method: POST
# path: "/**/git-receive-pack"
binaries:
- { path: /usr/bin/git }

nvidia_inference:
name: nvidia-inference
endpoints:
- { host: integrate.api.nvidia.com, port: 443 }
binaries:
- { path: /usr/bin/curl }
- { path: /bin/bash }
- { path: /usr/local/bin/opencode }

# --- GitHub REST API (read-only) ---
github_rest_api:
name: github-rest-api
endpoints:
- host: api.github.com
port: 443
protocol: rest
tls: terminate
enforcement: enforce
access: read-only
binaries:
- { path: /usr/local/bin/claude }
- { path: /usr/bin/gh }

# --- GitHub Copilot API ---
# Endpoints from https://docs.github.com/en/copilot/reference/copilot-allowlist-reference
copilot:
name: copilot
endpoints:
# Auth and user management
- { host: github.com, port: 443 }
- { host: api.github.com, port: 443 }
# Copilot API (subscription-tier routing)
- { host: api.githubcopilot.com, port: 443, protocol: rest, enforcement: enforce, access: read-write }
- { host: api.individual.githubcopilot.com, port: 443, protocol: rest, enforcement: enforce, access: read-write }
- { host: api.business.githubcopilot.com, port: 443, protocol: rest, enforcement: enforce, access: read-write }
- { host: api.enterprise.githubcopilot.com, port: 443, protocol: rest, enforcement: enforce, access: read-write }
# Model proxy
- { host: copilot-proxy.githubusercontent.com, port: 443, protocol: rest, enforcement: enforce, access: read-write }
# Telemetry, feature flags, updates
- { host: origin-tracker.githubusercontent.com, port: 443 }
- { host: telemetry.enterprise.githubcopilot.com, port: 443 }
- { host: default.exp-tas.com, port: 443 }
- { host: release-assets.githubusercontent.com, port: 443 }
binaries:
- { path: /usr/bin/copilot }
- { path: "/usr/lib/node_modules/@github/copilot/node_modules/@github/**/copilot" }

pypi:
name: pypi
endpoints:
- { host: pypi.org, port: 443 }
- { host: files.pythonhosted.org, port: 443 }
# uv python install downloads from python-build-standalone on GitHub
- { host: github.com, port: 443 }
- { host: objects.githubusercontent.com, port: 443 }
# uv resolves python-build-standalone release metadata via the GitHub API
- { host: api.github.com, port: 443 }
- { host: downloads.python.org, port: 443 }
binaries:
- { path: /sandbox/.venv/bin/python }
- { path: /sandbox/.venv/bin/python3 }
- { path: /sandbox/.venv/bin/pip }
- { path: /app/.venv/bin/python }
- { path: /app/.venv/bin/python3 }
- { path: /app/.venv/bin/pip }
- { path: /usr/local/bin/uv }
# Managed Python installations from uv python install
- { path: "/sandbox/.uv/python/**" }

vscode:
name: vscode
endpoints:
- { host: update.code.visualstudio.com, port: 443 }
# NOTE: OPA host matching uses exact equality, not glob — list hosts explicitly.
- { host: az764295.vo.msecnd.net, port: 443 }
- { host: vscode.download.prss.microsoft.com, port: 443 }
- { host: marketplace.visualstudio.com, port: 443 }
- { host: gallerycdn.vsassets.io, port: 443 }
binaries:
- { path: /usr/bin/curl }
- { path: /usr/bin/wget }
- { path: "/sandbox/.vscode-server/**" }
- { path: "/sandbox/.vscode-remote-containers/**" }

cursor:
name: cursor
endpoints:
- { host: cursor.blob.core.windows.net, port: 443 }
# NOTE: OPA host matching uses exact equality, not glob — list hosts explicitly.
- { host: api2.cursor.sh, port: 443 }
- { host: repo.cursor.sh, port: 443 }
- { host: download.cursor.sh, port: 443 }
- { host: cursor.download.prss.microsoft.com, port: 443 }
binaries:
- { path: /usr/bin/curl }
- { path: /usr/bin/wget }
- { path: "/sandbox/.cursor-server/**" }

opencode:
name: opencode
endpoints:
- host: registry.npmjs.org
port: 443
- host: opencode.ai
port: 443
- host: integrate.api.nvidia.com
port: 443
binaries:
- path: /usr/lib/node_modules/opencode-ai/bin/.opencode
- path: /usr/bin/node
- path: /usr/local/bin/opencode

codex:
name: codex
endpoints:
- { host: api.openai.com, port: 443 }
- { host: auth.openai.com, port: 443 }
- { host: chatgpt.com, port: 443 }
binaries:
- { path: /usr/bin/codex }
- { path: /usr/bin/node }
- { path: "/usr/lib/node_modules/@openai/**" }

deepseek_harness:
name: deepseek-harness
endpoints:
# Default model provider (dsh defaults to deepseek-v4-flash). Add
# entries here for any other provider a profile is configured to use.
- { host: api.deepseek.com, port: 443, protocol: rest, enforcement: enforce, access: full, tls: terminate }
# npm registry: `dsh plugin install` fetches plugins at runtime, not
# only at image build time.
- { host: registry.npmjs.org, port: 443 }
binaries:
- { path: /usr/bin/dsh }
- { path: "/usr/lib/node_modules/@deepseek-ai/dsh/**" }
- { path: /usr/bin/node }
Loading