@fractalcode/bridge 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/docker/Dockerfile +51 -0
- package/docker/README.md +102 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Fractal governs what an agent may *semantically* do (scoped channels, typed intents). OpenShell governs where bytes may *physically* travel (kernel filesystem/network/process containment). This bridge compiles between their domain models so an agent must pass both enforcement gates.
|
|
6
6
|
|
|
7
|
-
>
|
|
7
|
+
> **Alpha.** Open source, Apache-2.0. Issues and PRs welcome.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -27,13 +27,17 @@ The bridge maps only the channels that earn their keep — app-semantic scopes t
|
|
|
27
27
|
|
|
28
28
|
**Deliberately NOT mapped** (documented in emitted YAML comments): `postgres`/`sqlite` (read-only via SQL inspection is unsound — use DB roles), `stripe` (duplicates Stripe's restricted-key model), `aws-s3`/`sqs` (duplicates IAM), `docker`/`kubernetes`/`terraform`/`vault`/`github-actions` (native RBAC), `browser` (overlaps OpenShell network policy), test runners (local execution), and unaudited SaaS channels. See [docs/mapping-reference.md](docs/mapping-reference.md).
|
|
29
29
|
|
|
30
|
-
## Install
|
|
30
|
+
## Install
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
|
|
33
|
+
npm install -g @fractalcode/bridge
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or from source:
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/haltandcatchwater/fractal-openshell-bridge.git
|
|
34
39
|
cd fractal-openshell-bridge
|
|
35
|
-
npm install
|
|
36
|
-
npm run build
|
|
40
|
+
npm install && npm run build
|
|
37
41
|
```
|
|
38
42
|
|
|
39
43
|
## Usage
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# fractal-openshell-bridge — BYOC (Bring Your Own Container) sandbox image.
|
|
2
|
+
#
|
|
3
|
+
# An OpenShell-compatible image that runs the Fractal runner inside an OpenShell
|
|
4
|
+
# sandbox. Follows the OpenShell BYOC contract:
|
|
5
|
+
# - Linux base (not distroless/scratch)
|
|
6
|
+
# - iproute2 installed (network namespace management)
|
|
7
|
+
# - nftables installed (bypass detection)
|
|
8
|
+
# - sandbox user UID/GID 1000660000
|
|
9
|
+
# - workdir /sandbox, owned by sandbox:sandbox
|
|
10
|
+
# - CMD/ENTRYPOINT replaced by OpenShell supervisor
|
|
11
|
+
#
|
|
12
|
+
# This image contains NO OpenShell code. OpenShell's supervisor (installed
|
|
13
|
+
# separately) attaches and enforces policy.
|
|
14
|
+
#
|
|
15
|
+
# Now that @fractalcode/runner and @fractalcode/bridge are on npm, this
|
|
16
|
+
# Dockerfile installs them directly — no build args, no source copies.
|
|
17
|
+
|
|
18
|
+
FROM node:22-slim
|
|
19
|
+
|
|
20
|
+
# ── OpenShell BYOC requirements ───────────────────────────────────────
|
|
21
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
22
|
+
iproute2 nftables curl git ca-certificates \
|
|
23
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
24
|
+
|
|
25
|
+
# ── Sandbox user (OpenShell BYOC contract) ────────────────────────────
|
|
26
|
+
RUN groupadd -g 1000660000 sandbox && \
|
|
27
|
+
useradd -m -u 1000660000 -g sandbox sandbox
|
|
28
|
+
|
|
29
|
+
# ── Javy — compiles Fractal cell logic (TypeScript → Wasm) ────────────
|
|
30
|
+
# Latest stable release with fetch support.
|
|
31
|
+
ARG JAVY_VERSION=v3.0.1
|
|
32
|
+
RUN curl -fsSL "https://github.com/bytecodealliance/javy/releases/download/${JAVY_VERSION}/javy-x86_64-linux-${JAVY_VERSION}.gz" -o /tmp/javy.gz \
|
|
33
|
+
&& gunzip /tmp/javy.gz \
|
|
34
|
+
&& mv /tmp/javy /usr/local/bin/javy \
|
|
35
|
+
&& chmod +x /usr/local/bin/javy
|
|
36
|
+
|
|
37
|
+
# ── Fractal + Bridge (from npm) ───────────────────────────────────────
|
|
38
|
+
RUN npm install -g @fractalcode/runner @fractalcode/bridge
|
|
39
|
+
|
|
40
|
+
# ── Policy directory (root-owned, read-only bind-mount target) ────────
|
|
41
|
+
RUN install -d -o root -g root -m 0755 /etc/openshell
|
|
42
|
+
|
|
43
|
+
# ── Workdir ───────────────────────────────────────────────────────────
|
|
44
|
+
RUN install -d -o sandbox -g sandbox /sandbox
|
|
45
|
+
WORKDIR /sandbox
|
|
46
|
+
|
|
47
|
+
USER sandbox
|
|
48
|
+
|
|
49
|
+
# Replaced by OpenShell supervisor at sandbox creation:
|
|
50
|
+
# openshell sandbox create --from fractal-sandbox --policy policy.yaml -- fractal-runner serve
|
|
51
|
+
CMD ["fractal-runner", "serve"]
|
package/docker/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# BYOC Sandbox Image
|
|
2
|
+
|
|
3
|
+
An OpenShell-compatible Docker image that runs the Fractal runner inside an
|
|
4
|
+
OpenShell sandbox. The bridge compiles a finalized scaffold's sidecars into
|
|
5
|
+
`policy.yaml`; OpenShell enforces that policy at the kernel level around the
|
|
6
|
+
runner process running in this image.
|
|
7
|
+
|
|
8
|
+
## What's in the image (and what's NOT)
|
|
9
|
+
|
|
10
|
+
- **In:** node:22-slim, iproute2, nftables (OpenShell BYOC requirements), Javy
|
|
11
|
+
(Fractal's TS→Wasm compiler), the fractal-openshell-bridge (this repo), the
|
|
12
|
+
fractal-runner, an unprivileged `sandbox` user (UID/GID 1000660000), workdir
|
|
13
|
+
`/sandbox`.
|
|
14
|
+
- **NOT in:** OpenShell itself. OpenShell's supervisor is installed separately
|
|
15
|
+
by the user and attaches to this container. This image is a standard Linux
|
|
16
|
+
container that meets OpenShell's BYOC contract — no OpenShell code bundled.
|
|
17
|
+
|
|
18
|
+
## Build
|
|
19
|
+
|
|
20
|
+
The fractal-runner is not yet on npm (pending the owner's publish). Until then,
|
|
21
|
+
build it from the `fractal-code-void` source and provide it as a build context.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# From the parent directory containing both repos:
|
|
25
|
+
docker build \
|
|
26
|
+
-f fractal-openshell-bridge/docker/Dockerfile \
|
|
27
|
+
-t fractal-runner \
|
|
28
|
+
--build-arg FRACTAL_RUNNER_SRC=fractal-code-void \
|
|
29
|
+
fractal-openshell-bridge
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Once `@fractal-code/runner` is on npm, the Dockerfile can `npm install -g` it
|
|
33
|
+
directly and the `FRACTAL_RUNNER_SRC` build arg goes away.
|
|
34
|
+
|
|
35
|
+
## Run (inside an OpenShell sandbox)
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# 1. Compile your finalized scaffold's sidecars to a policy.
|
|
39
|
+
fractal-openshell-bridge compile ./my-pipeline/cells -o policy.yaml
|
|
40
|
+
|
|
41
|
+
# 2. (Optional) verify the policy with the prover before applying.
|
|
42
|
+
fractal-openshell-bridge verify ./my-pipeline/cells --credentials creds.yaml --openshell-prover
|
|
43
|
+
|
|
44
|
+
# 3. Create the sandbox, bind-mounting the policy read-only.
|
|
45
|
+
openshell sandbox create \
|
|
46
|
+
--from fractal-runner \
|
|
47
|
+
--mount type=bind,source=$(pwd)/policy.yaml,destination=/etc/openshell/policy.yaml,readonly \
|
|
48
|
+
-- fractal-runner serve
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Policy file protection — can the agent overwrite its own containment rules?
|
|
52
|
+
|
|
53
|
+
No. The protection is layered, strongest first:
|
|
54
|
+
|
|
55
|
+
1. **Read-only bind mount (primary, kernel-enforced).** `policy.yaml` is
|
|
56
|
+
generated on the host and bind-mounted into the container at
|
|
57
|
+
`/etc/openshell/policy.yaml` with `readonly`. The VFS layer rejects writes
|
|
58
|
+
from any unprivileged process. The sandbox (UID 1000660000, no CAP_SYS_ADMIN)
|
|
59
|
+
cannot remount.
|
|
60
|
+
|
|
61
|
+
2. **DAC: root-owned, mode 0644.** The `/etc/openshell/` directory is created
|
|
62
|
+
`root:root 0755` in the Dockerfile. The `sandbox` user can't write to it by
|
|
63
|
+
basic Unix permissions — a backstop if the mount flag is ever dropped.
|
|
64
|
+
|
|
65
|
+
3. **Fractal-side: policy path never in any FileChannel `allowedPaths`.** The
|
|
66
|
+
bridge's generated `filesystem_policy` lists `/etc/openshell/` under
|
|
67
|
+
`read_only`, never `read_write`. No FileChannel scope grants write there.
|
|
68
|
+
|
|
69
|
+
4. **Landlock (OpenShell's MAC).** OpenShell's filesystem policy — derived from
|
|
70
|
+
the bridge's output — marks the policy path read-only at the kernel level.
|
|
71
|
+
Best-effort (`compatibility: best_effort`), so defense-in-depth, not primary.
|
|
72
|
+
|
|
73
|
+
5. **Merkle tamper detection.** The policy hash is committed to Fractal's
|
|
74
|
+
Merkle root at finalize. Any tampering that survives layers 1-4 produces a
|
|
75
|
+
hash mismatch — detection, not prevention, but a backstop.
|
|
76
|
+
|
|
77
|
+
The red-team's AppArmor/SELinux suggestion is largely redundant here: OpenShell
|
|
78
|
+
already applies kernel-level filesystem MAC via Landlock, and the sandbox is
|
|
79
|
+
unprivileged. MAC-on-MAC adds marginal value. The read-only bind mount is the
|
|
80
|
+
control that makes overwrite structurally impossible rather than policy-forbidden.
|
|
81
|
+
|
|
82
|
+
## State-drift limitation
|
|
83
|
+
|
|
84
|
+
The bridge produces a **static** policy at finalize. If an agent needs a new
|
|
85
|
+
endpoint mid-task, OpenShell's sandbox is locked to the boot-time policy.
|
|
86
|
+
OpenShell *does* support hot-reloadable network policy (`openshell policy set`),
|
|
87
|
+
so a future bridge version can recompile + hot-reload on scope change. For now:
|
|
88
|
+
mid-task endpoint changes require recompile + reload. Document this for users
|
|
89
|
+
whose agents encounter unexpected endpoints at runtime.
|
|
90
|
+
|
|
91
|
+
## Verification
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Build succeeds:
|
|
95
|
+
docker build -f docker/Dockerfile -t fractal-runner .
|
|
96
|
+
|
|
97
|
+
# Sandbox boots and the policy is mounted read-only:
|
|
98
|
+
openshell sandbox create --from fractal-runner --policy policy.yaml -- fractal-runner serve
|
|
99
|
+
# Inside the sandbox:
|
|
100
|
+
sandbox$ echo x > /etc/openshell/policy.yaml
|
|
101
|
+
# → permission denied (read-only mount)
|
|
102
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fractalcode/bridge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Compiles Fractal Code channel sidecars into OpenShell sandbox policy YAML, and wires the OpenShell Z3 prover as a finalize-time gate. Standalone — zero NVIDIA code, zero Fractal-internal dependency.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/src/cli.js",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
+
"docker",
|
|
12
13
|
"README.md",
|
|
13
14
|
"LICENSE",
|
|
14
15
|
"NOTICE"
|