@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 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
- > ⚠️ **Alpha. AI-built, not human-reviewed.** This software was written by an AI agent and has NOT been reviewed by a human security engineer. It is an experimental alpha. Do NOT deploy it to protect real secrets or production systems without independent human review. Treat the semantic-gate claims as unverified until a qualified reviewer confirms them. See [SECURITY](#security-posture).
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 (from source — not yet on npm)
30
+ ## Install
31
31
 
32
32
  ```bash
33
- git clone <repo-url>
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"]
@@ -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.0",
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"