Skip to content

Commit e8e66e6

Browse files
feat(sandbox): add Factory Droid sandbox image
Signed-off-by: Octavian Sima <octavian@factory.ai>
1 parent 91d915d commit e8e66e6

3 files changed

Lines changed: 189 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: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
# Droid Computers relay (HTTPS + WSS)
48+
- { host: relay.factory.ai, port: 443 }
49+
# Error tracking
50+
- { host: "*.ingest.us.sentry.io", port: 443 }
51+
- { host: "*.ingest.sentry.io", port: 443 }
52+
binaries:
53+
- { path: "/usr/lib/node_modules/droid/**" }
54+
- { path: /usr/local/bin/droid }
55+
- { path: /usr/bin/node }
56+
57+
# --- BYOK: direct model provider access ---
58+
droid_byok:
59+
name: droid-byok
60+
endpoints:
61+
- { host: api.anthropic.com, port: 443 }
62+
- { host: api.openai.com, port: 443 }
63+
- { host: generativelanguage.googleapis.com, port: 443 }
64+
- { host: "*.googleapis.com", port: 443 }
65+
- { host: api.groq.com, port: 443 }
66+
- { host: api.fireworks.ai, port: 443 }
67+
- { host: api.deepinfra.com, port: 443 }
68+
- { host: openrouter.ai, port: 443 }
69+
- { host: api-inference.huggingface.co, port: 443 }
70+
binaries:
71+
- { path: "/usr/lib/node_modules/droid/**" }
72+
- { path: /usr/local/bin/droid }
73+
- { path: /usr/bin/node }
74+
75+
# --- GitHub (full read + write access) ---
76+
github:
77+
name: github
78+
endpoints:
79+
- host: github.com
80+
port: 443
81+
protocol: rest
82+
tls: terminate
83+
enforcement: enforce
84+
rules:
85+
- allow:
86+
method: GET
87+
path: "/**/info/refs*"
88+
- allow:
89+
method: POST
90+
path: "/**/git-upload-pack"
91+
- allow:
92+
method: POST
93+
path: "/**/git-receive-pack"
94+
- host: api.github.com
95+
port: 443
96+
protocol: rest
97+
tls: terminate
98+
enforcement: enforce
99+
binaries:
100+
- { path: /usr/bin/git }
101+
- { path: /usr/bin/gh }
102+
- { path: "/usr/lib/node_modules/droid/**" }
103+
- { path: /usr/bin/node }
104+
105+
# --- npm registry (MCP server installs) ---
106+
npm:
107+
name: npm
108+
endpoints:
109+
- { host: registry.npmjs.org, port: 443 }
110+
binaries:
111+
- { path: /usr/bin/node }
112+
- { path: /usr/local/bin/npm }
113+
114+
# --- PyPI (Python package installs) ---
115+
pypi:
116+
name: pypi
117+
endpoints:
118+
- { host: pypi.org, port: 443 }
119+
- { host: files.pythonhosted.org, port: 443 }
120+
- { host: github.com, port: 443 }
121+
- { host: objects.githubusercontent.com, port: 443 }
122+
- { host: api.github.com, port: 443 }
123+
- { host: downloads.python.org, port: 443 }
124+
binaries:
125+
- { path: /sandbox/.venv/bin/python }
126+
- { path: /sandbox/.venv/bin/python3 }
127+
- { path: /sandbox/.venv/bin/pip }
128+
- { path: /app/.venv/bin/python }
129+
- { path: /app/.venv/bin/python3 }
130+
- { path: /app/.venv/bin/pip }
131+
- { path: /usr/local/bin/uv }
132+
- { path: "/sandbox/.uv/python/**" }

0 commit comments

Comments
 (0)