Skip to content
This repository was archived by the owner on Oct 7, 2026. It is now read-only.

Commit 36c558e

Browse files
feat(sandbox): add Factory Droid sandbox image (#59)
* feat(sandbox): add Factory Droid sandbox image Signed-off-by: Octavian Sima <octavian@factory.ai> * add read-only network policy * more network policy allows * fix * more comment * more general readme --------- Signed-off-by: Octavian Sima <octavian@factory.ai>
1 parent 8f7d0da commit 36c558e

3 files changed

Lines changed: 198 additions & 0 deletions

File tree

‎sandboxes/droid/Dockerfile‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# syntax=docker/dockerfile:1.4
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
# Factory Droid sandbox image for OpenShell
7+
#
8+
# Builds on the community base sandbox and adds Factory's Droid CLI.
9+
# Build: docker build -t openshell-droid --build-arg BASE_IMAGE=openshell-base .
10+
# Run: openshell sandbox create --from droid
11+
12+
ARG BASE_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest
13+
FROM ${BASE_IMAGE}
14+
15+
USER root
16+
17+
# Install Droid CLI (pinned for reproducibility)
18+
RUN npm install -g droid@0.90.0
19+
20+
# Copy sandbox policy
21+
COPY policy.yaml /etc/openshell/policy.yaml
22+
23+
# Create Droid config directory
24+
RUN mkdir -p /sandbox/.factory && \
25+
chown sandbox:sandbox /sandbox/.factory
26+
27+
USER sandbox
28+
29+
ENTRYPOINT ["/bin/bash"]

‎sandboxes/droid/README.md‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Factory Droid Sandbox
2+
3+
OpenShell sandbox image pre-configured with [Factory Droid CLI](https://docs.factory.ai/) for AI-powered software engineering.
4+
5+
## What's Included
6+
7+
- **Droid CLI** (`droid@0.90.0`) — Factory's AI coding agent
8+
- Everything from the [base sandbox](../base/README.md)
9+
10+
## Build
11+
12+
```bash
13+
docker build -t openshell-droid .
14+
```
15+
16+
To build against a specific base image:
17+
18+
```bash
19+
docker build -t openshell-droid --build-arg BASE_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest .
20+
```
21+
22+
## Usage
23+
24+
### Create a sandbox
25+
26+
```bash
27+
openshell sandbox create --from droid
28+
```

‎sandboxes/droid/policy.yaml‎

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
version: 1
5+
6+
# --- Sandbox setup configuration (queried once at startup) ---
7+
8+
filesystem_policy:
9+
include_workdir: true
10+
read_only:
11+
- /usr
12+
- /lib
13+
- /proc
14+
- /dev/urandom
15+
- /app
16+
- /etc
17+
- /var/log
18+
read_write:
19+
- /sandbox
20+
- /tmp
21+
- /dev/null
22+
23+
landlock:
24+
compatibility: best_effort
25+
26+
process:
27+
run_as_user: sandbox
28+
run_as_group: sandbox
29+
30+
# --- Network policies (queried per-CONNECT request) ---
31+
#
32+
# Each named policy maps a set of allowed (binary, endpoint) pairs.
33+
# Binary identity is resolved via /proc/net/tcp inode lookup + /proc/{pid}/exe.
34+
# Ancestors (/proc/{pid}/status PPid walk) and cmdline paths are also matched.
35+
# SHA256 integrity is enforced in Rust via trust-on-first-use, not here.
36+
37+
network_policies:
38+
39+
# --- Factory Droid core infrastructure ---
40+
droid:
41+
name: droid
42+
endpoints:
43+
# Main API / LLM proxy
44+
- { host: api.factory.ai, port: 443 }
45+
# Auth, OAuth callbacks, CLI updates
46+
- { host: app.factory.ai, port: 443 }
47+
# WorkOS authentication (device code / OAuth login flow)
48+
- { host: api.workos.com, port: 443 }
49+
# Droid Computers relay (HTTPS + WSS)
50+
- { host: relay.factory.ai, port: 443 }
51+
# CLI auto-update CDN
52+
- { host: downloads.factory.ai, port: 443 }
53+
# Documentation / changelog
54+
- { host: docs.factory.ai, port: 443 }
55+
# Customer OTEL telemetry
56+
- { host: "*.run.app", port: 443 }
57+
# Error tracking
58+
- { host: "*.ingest.us.sentry.io", port: 443 }
59+
- { host: "*.ingest.sentry.io", port: 443 }
60+
binaries:
61+
- { path: "/usr/lib/node_modules/droid/**" }
62+
- { path: /usr/bin/droid }
63+
- { path: /usr/bin/node }
64+
65+
# --- BYOK: direct model provider access ---
66+
droid_byok:
67+
name: droid-byok
68+
endpoints:
69+
- { host: api.anthropic.com, port: 443 }
70+
- { host: api.openai.com, port: 443 }
71+
- { host: generativelanguage.googleapis.com, port: 443 }
72+
- { host: "*.googleapis.com", port: 443 }
73+
- { host: api.groq.com, port: 443 }
74+
- { host: api.fireworks.ai, port: 443 }
75+
- { host: api.deepinfra.com, port: 443 }
76+
- { host: openrouter.ai, port: 443 }
77+
- { host: api-inference.huggingface.co, port: 443 }
78+
binaries:
79+
- { path: "/usr/lib/node_modules/droid/**" }
80+
- { path: /usr/bin/droid }
81+
- { path: /usr/bin/node }
82+
83+
# --- GitHub (full read + write access) ---
84+
github:
85+
name: github
86+
endpoints:
87+
- host: github.com
88+
port: 443
89+
protocol: rest
90+
tls: terminate
91+
enforcement: enforce
92+
rules:
93+
- allow:
94+
method: GET
95+
path: "/**/info/refs*"
96+
- allow:
97+
method: POST
98+
path: "/**/git-upload-pack"
99+
- allow:
100+
method: POST
101+
path: "/**/git-receive-pack"
102+
- host: api.github.com
103+
port: 443
104+
protocol: rest
105+
tls: terminate
106+
enforcement: enforce
107+
access: read-only
108+
binaries:
109+
- { path: /usr/bin/git }
110+
- { path: /usr/bin/gh }
111+
- { path: "/usr/lib/node_modules/droid/**" }
112+
- { path: /usr/bin/node }
113+
114+
# --- npm registry (MCP server installs) ---
115+
npm:
116+
name: npm
117+
endpoints:
118+
- { host: registry.npmjs.org, port: 443 }
119+
binaries:
120+
- { path: /usr/bin/node }
121+
- { path: /usr/local/bin/npm }
122+
123+
# --- PyPI (Python package installs) ---
124+
pypi:
125+
name: pypi
126+
endpoints:
127+
- { host: pypi.org, port: 443 }
128+
- { host: files.pythonhosted.org, port: 443 }
129+
- { host: github.com, port: 443 }
130+
- { host: objects.githubusercontent.com, port: 443 }
131+
- { host: api.github.com, port: 443 }
132+
- { host: downloads.python.org, port: 443 }
133+
binaries:
134+
- { path: /sandbox/.venv/bin/python }
135+
- { path: /sandbox/.venv/bin/python3 }
136+
- { path: /sandbox/.venv/bin/pip }
137+
- { path: /app/.venv/bin/python }
138+
- { path: /app/.venv/bin/python3 }
139+
- { path: /app/.venv/bin/pip }
140+
- { path: /usr/local/bin/uv }
141+
- { path: "/sandbox/.uv/python/**" }

0 commit comments

Comments
 (0)