Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .agents/skills/test-release-canary/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The Release Canary (`.github/workflows/release-canary.yml`) smoke-tests the arti
| `macos` | `macos-latest-xlarge` | Installs the dev Homebrew artifacts, reaches the VM gateway, and creates, executes in, and deletes a sandbox. |
| `ubuntu-deb` | `ubuntu-latest` | Installs the dev Debian package, reaches the Docker gateway, and creates, executes in, and deletes a sandbox. |
| `fedora` | `fedora:latest` container | Installs the dev RPM packages, reaches the Podman gateway, and creates, executes in, and deletes a sandbox. |
| `ubuntu-snap-system-docker` | `ubuntu-latest` | Uses `install.sh` to install the snap from `latest/edge`, reuses system Docker, reaches the Docker gateway, and creates, executes in, and deletes a sandbox, and verifies that the Docker snap is not installed. |
| `ubuntu-snap-system-docker` | `ubuntu-latest` | Uses `install.sh` to install the snap from `latest/edge`, reuses system Docker, verifies the packaged prover version and a local policy boundary check, reaches the Docker gateway, creates, executes in, and deletes a sandbox, and verifies that the Docker snap is not installed. |
| `ubuntu-snap-docker-preflight` | `ubuntu-latest` | Verifies that `install.sh` rejects the OpenShell Snap path when Docker is absent or supplied by the Docker snap, without installing OpenShell. |
| `kubernetes` | `ubuntu-latest` + kind | Installs the dev Helm chart, reaches the in-cluster gateway, and creates, executes in, and deletes a sandbox using the published runtime images. |

Expand Down Expand Up @@ -144,6 +144,7 @@ Loopback registration auto-derives the gateway name to `openshell` if `--name` i
| Sandbox create or exec fails | Published sandbox and supervisor artifacts are missing, incompatible, or cannot establish the protected runtime channel. | Gateway logs plus Docker, Podman, VM, Snap, or Kubernetes runtime diagnostics for the job. |
| `macos`/`ubuntu-deb`/`fedora` job fails on `openshell status` | Local gateway service did not start (systemd/brew/podman). Often a driver issue. | Service logs in the job log; `OPENSHELL_COMPUTE_DRIVER` env in the "Ensure …" step. |
| `ubuntu-snap-system-docker` fails during `install.sh` | System Docker was unavailable, the edge revision or automatic interfaces were unavailable, or the gateway did not become reachable. | Failure diagnostics dump system Docker, snap service/connection/change state, gateway and snapd journals, snap logs, and port 17670 listeners. |
| `ubuntu-snap-system-docker` fails during the prover checks | The prover artifact is missing or packaged for the wrong architecture, `openshell.prover` is not exposed or confined to read the test policies, or its solver linkage is not runnable. | The `Verify Snap installation` and `Check a policy boundary with the Snap prover` steps, plus `snap info openshell` and `snap connections openshell`. |
| `ubuntu-snap-docker-preflight` unexpectedly succeeds | The installer no longer fails before installing the OpenShell snap when Docker is absent or supplied by the Docker snap. | Inspect `install.log`, `docker-snap.log`, `snap list`, and snapd changes. |
| `kubernetes` job fails on `helm install --wait` | Chart did not deploy in 5 min — usually image pull failure or readiness probe failing. | "Diagnostics on failure" step dumps `helm status`, manifest, pod describe, pod logs. |
| `kubernetes` job fails on `kubectl wait` | Gateway pod stuck `CrashLoopBackOff` or `ImagePullBackOff`. | Diagnostics dump; check `:dev` image existence at `ghcr.io/nvidia/openshell/gateway`. |
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/release-canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,35 @@ jobs:
docker info
sudo snap connections openshell | grep -E '^docker +openshell:docker +:docker +'
openshell --version
openshell.prover --version
sudo snap services openshell
sudo journalctl -b -u snap.openshell.gateway.service --no-pager |
grep -F "mTLS user authentication enabled"
openshell gateway list | grep -F "https://127.0.0.1:17670"
openshell status

- name: Check a policy boundary with the Snap prover
run: |
set -euo pipefail
prover_dir=$(mktemp -d "$HOME/openshell-prover-canary.XXXXXX")
trap 'rm -rf "$prover_dir"' EXIT
cat >"$prover_dir/boundary.yaml" <<'EOF'
version: 1
filesystem_policy:
read_only:
- /usr
- /etc
EOF
cat >"$prover_dir/candidate.yaml" <<'EOF'
version: 1
filesystem_policy:
read_only:
- /usr
EOF
result=$(openshell.prover check "$prover_dir/candidate.yaml" \
--boundary "$prover_dir/boundary.yaml")
grep -q '^result: within_boundary$' <<<"$result"

- name: Create and exercise a sandbox
run: |
set -euo pipefail
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/snap-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ jobs:
name: openshell-${{ matrix.rust_arch }}-unknown-linux-musl
path: prebuilt/cli

- name: Download prebuilt prover binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: openshell-prover-${{ matrix.rust_arch }}-unknown-linux-musl
path: prebuilt/prover

- name: Download prebuilt gateway binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand All @@ -105,6 +111,7 @@ jobs:
run: |
set -euo pipefail
chmod +x prebuilt/cli/openshell
chmod +x prebuilt/prover/openshell-prover
chmod +x prebuilt/gateway/openshell-gateway
chmod +x prebuilt/sandbox/openshell-sandbox
ls -laR prebuilt/
Expand All @@ -115,6 +122,7 @@ jobs:
mkdir -p snap/prebuilt

cp prebuilt/cli/openshell snap/prebuilt/openshell
cp prebuilt/prover/openshell-prover snap/prebuilt/openshell-prover
cp prebuilt/gateway/openshell-gateway snap/prebuilt/openshell-gateway
cp prebuilt/sandbox/openshell-sandbox snap/prebuilt/openshell-sandbox

Expand Down
2 changes: 1 addition & 1 deletion CI.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ These workflows run after merge to publish dev/tagged artifacts and verify them.
|---|---|
| `.github/workflows/release-dev.yml` | Publishes the rolling `dev` build on every push to `main`. Builds gateway, sandbox, and supervisor images and binaries, packages, wheels, and pushes the Helm chart as `oci://ghcr.io/nvidia/openshell/helm-chart:0.0.0-dev` (plus an immutable `0.0.0-dev.<sha>` pin). Also dispatchable manually. |
| `.github/workflows/release-tag.yml` | Publishes tagged stable releases and manually dispatched pre-releases. Its automatic tag trigger excludes `-pre.*`. Protobuf, security, and integration failures do not block pre-release artifact publication. Stable publication requires the currently implemented qualification profile to pass; the summary identifies the remaining RFC 0014 coverage. |
| `.github/workflows/release-canary.yml` | Smoke-tests published dev artifacts in the `macos`, `ubuntu-deb`, `ubuntu-snap-system-docker`, `fedora`, and `kubernetes` (kind + Helm) jobs. Each job reaches its gateway and creates, exercises, and deletes a sandbox. The Snap lanes verify a compatible system Docker lifecycle and `ubuntu-snap-docker-preflight` tests fail-fast behavior when Docker is absent or supplied by the Docker snap. It runs automatically after `Release Dev` succeeds and supports manual dispatch (`gh workflow run release-canary.yml --ref <branch>`). See the `test-release-canary` skill for the playbook and local kind reproduction. |
| `.github/workflows/release-canary.yml` | Smoke-tests published dev artifacts in the `macos`, `ubuntu-deb`, `ubuntu-snap-system-docker`, `fedora`, and `kubernetes` (kind + Helm) jobs. Each job reaches its gateway and creates, exercises, and deletes a sandbox. The Snap lanes verify a compatible system Docker lifecycle and `ubuntu-snap-docker-preflight` tests fail-fast behavior when Docker is absent or supplied by the Docker snap. The positive Snap lane also runs a local policy containment check with the packaged prover. It runs automatically after `Release Dev` succeeds and supports manual dispatch (`gh workflow run release-canary.yml --ref <branch>`). See the `test-release-canary` skill for the playbook and local kind reproduction. |

## Required status contexts

Expand Down
7 changes: 6 additions & 1 deletion docs/about/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,16 @@ sudo loginctl enable-linger $USER

The snap requires Docker Engine installed from your distribution or Docker's package repository. The Docker snap is not compatible.

The snap does not migrate existing Debian, RPM, or Homebrew installs. Remove any existing installation first, then either rerun the `install.sh` script with `OPENSHELL_INSTALL_METHOD=snap OPENSHELL_ACK_BREAKING_UPGRADE=1`, or install the snap directly:

```shell
sudo snap install openshell
```

The snap does not migrate existing Debian, RPM, or Homebrew installs. Remove any existing installation first, then rerun the script with `OPENSHELL_INSTALL_METHOD=snap OPENSHELL_ACK_BREAKING_UPGRADE=1`.
The snap installs the standalone policy prover as `openshell.prover`. The
`openshell-prover` alias requires Snap Store approval and may not be available.
The prover reads local policy files through the `home` interface and does not
connect to the gateway.

The gateway runs as a system service at `https://127.0.0.1:17670` and reads `/var/snap/openshell/common/gateway.toml`. It requires a client certificate. The install script copies that certificate to the installing user's Snap state and registers the gateway automatically. If you installed with `sudo snap install openshell`, give each trusted user the certificate and register the gateway from that user's account:

Expand Down
5 changes: 5 additions & 0 deletions docs/about/support-matrix.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ OpenShell publishes standalone `openshell-prover` release assets for manual down

These artifacts are attached to GitHub releases. The Linux binaries are static and do not require glibc. All prover archives include the required solver linkage.

The Debian, RPM, Homebrew, and Snap packages also include the prover. Debian,
RPM, and Homebrew installations expose it as `openshell-prover`; use
`openshell.prover` with the Snap. The `openshell-prover` Snap alias requires
Store approval and may not be available.

## Runtimes

The gateway can manage sandboxes through several runtimes.
Expand Down
20 changes: 14 additions & 6 deletions docs/how-it-works/policies/prover.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ contain access that the proposal risk check would flag.
This page covers the boundary check. To learn about the proposal risk check,
refer to [Policy Advisor](/how-it-works/policies/advisor).

For Snap installations, replace `openshell-prover` in these examples with
`openshell.prover`. The `openshell-prover` Snap alias requires Store approval
and may not be available.

The prover remains independent of the gateway at runtime. If you only need the
standalone binary, use the artifacts listed in the
[Support Matrix](/about/support-matrix#standalone-policy-prover). These
artifacts and `openshell-prover-checksums-sha256.txt` are attached to
[OpenShell releases](https://github.com/NVIDIA/OpenShell/releases).

## Run a Boundary Check

A boundary check compares the policy you are testing, called the candidate, with
Expand All @@ -50,12 +60,10 @@ or MCP rules, the prover reports that it cannot check the policy instead of
ignoring those rules. [What the Boundary Check
Covers](#what-the-boundary-check-covers) describes each part and its limits.

The Homebrew, Debian, and RPM packages install the `openshell-prover` CLI. The
snap package does not include it, so on a snap installation, download the
`openshell-prover` archive for your platform from the [OpenShell
releases](https://github.com/NVIDIA/OpenShell/releases). The CLI reads policy
files on your machine, does not need a gateway, and does not apply or approve
policies.
The Homebrew, Debian, RPM, and Snap packages install the prover. Homebrew,
Debian, and RPM expose it as `openshell-prover`; use `openshell.prover` with the
Snap. The CLI reads policy files on your machine, does not need a gateway, and
does not apply or approve policies.

Create `boundary.yaml`, a boundary that allows reading `/usr` and `/etc`:

Expand Down
19 changes: 19 additions & 0 deletions nix/test-guest/scripts/snap-gateway-repro.sh
Original file line number Diff line number Diff line change
Expand Up @@ -127,20 +127,39 @@ for attempt in $(seq 1 "${attempts}"); do
fi

sandbox="snap-${attempt}-$$"
prover_dir=$(mktemp -d "$HOME/openshell-prover-repro.XXXXXX")
cat >"${prover_dir}/boundary.yaml" <<'EOF'
version: 1
filesystem_policy:
read_only:
- /usr
- /etc
EOF
cat >"${prover_dir}/candidate.yaml" <<'EOF'
version: 1
filesystem_policy:
read_only:
- /usr
EOF
if ! OPENSHELL_INSTALL_METHOD=snap OPENSHELL_VERSION=dev sh "${install_script}" ||
! sudo snap list openshell >/dev/null ||
! snap info openshell | grep -Eq '^tracking: +latest/edge$' ||
! docker_is_ready ||
! sudo snap connections openshell | grep -Eq '^docker +openshell:docker +:docker +' ||
! /snap/bin/openshell status ||
! /snap/bin/openshell.prover --version ||
! /snap/bin/openshell.prover check "${prover_dir}/candidate.yaml" \
--boundary "${prover_dir}/boundary.yaml" | grep -q '^result: within_boundary$' ||
! /snap/bin/openshell sandbox create --name "${sandbox}" --detach ||
! /snap/bin/openshell sandbox exec --name "${sandbox}" --no-tty -- true ||
! /snap/bin/openshell sandbox delete "${sandbox}"; then
echo "install.sh Snap reproduction failed" >&2
diagnostics "${attempt}"
failures=$((failures + 1))
rm -rf "${prover_dir}"
continue
fi
rm -rf "${prover_dir}"

if sudo snap list docker >/dev/null 2>&1; then
echo "install.sh unexpectedly installed the Docker snap" >&2
Expand Down
13 changes: 11 additions & 2 deletions snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ description: |
profile-backed model-provider access.

The OpenShell snap ships a CLI (`openshell`), a terminal UI
(`openshell.term`), and a managed gateway daemon (`openshell.gateway`).
(`openshell.term`), a standalone policy prover (`openshell.prover`), and a
managed gateway daemon (`openshell.gateway`).

**Setup instructions**

Expand Down Expand Up @@ -85,6 +86,12 @@ apps:
- home
- network
- system-observe
prover:
command: bin/openshell-prover
aliases:
- openshell-prover
plugs:
- home
gateway:
command: bin/openshell-gateway-wrapper
daemon: simple
Expand Down Expand Up @@ -120,7 +127,7 @@ parts:
set -euo pipefail

MISSING=()
for bin in openshell openshell-gateway openshell-sandbox openshell-gateway-wrapper; do
for bin in openshell openshell-prover openshell-gateway openshell-sandbox openshell-gateway-wrapper; do
if [ ! -f "$CRAFT_PART_SRC/$bin" ]; then
MISSING+=("$bin")
fi
Expand All @@ -138,6 +145,8 @@ parts:

install -D -m 0755 "$CRAFT_PART_SRC/openshell" \
"$CRAFT_PART_INSTALL/bin/openshell"
install -D -m 0755 "$CRAFT_PART_SRC/openshell-prover" \
"$CRAFT_PART_INSTALL/bin/openshell-prover"
install -D -m 0755 "$CRAFT_PART_SRC/openshell-gateway" \
"$CRAFT_PART_INSTALL/bin/openshell-gateway"
install -D -m 0755 "$CRAFT_PART_SRC/openshell-sandbox" \
Expand Down
26 changes: 24 additions & 2 deletions tasks/scripts/test-packaging-assets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,15 @@ assert_not_contains "$spec" '%%S/openshell/tls'
# Schema-v2 package startup wiring.
snap_wrapper="${ROOT}/tasks/scripts/snap-gateway-wrapper.sh"
snapcraft="${ROOT}/snapcraft.yaml"
snap_workflow="${ROOT}/.github/workflows/snap-package.yml"
snap_install_docs="${ROOT}/docs/about/installation.mdx"
snap_canary="${ROOT}/.github/workflows/release-canary.yml"
snap_repro="${ROOT}/nix/test-guest/scripts/snap-gateway-repro.sh"
snap_post_refresh_hook="${ROOT}/snap/hooks/post-refresh"
package_deb="${ROOT}/tasks/scripts/package-deb.sh"
assert_file_exists "$snap_wrapper"
assert_file_exists "$snapcraft"
assert_file_exists "$snap_workflow"
assert_file_exists "$snap_install_docs"
assert_file_exists "$snap_canary"
assert_file_exists "$snap_repro"
Expand Down Expand Up @@ -131,18 +133,38 @@ if [[ ! -x "$snap_post_refresh_hook" ]]; then
fi
assert_not_contains "$ROOT/tasks/scripts/snap-gateway-wrapper.sh" 'OPENSHELL_DISABLE_TLS'
bash "$ROOT/tasks/scripts/test-snap-post-refresh-hook.sh" "$snap_post_refresh_hook"
assert_contains "$snap_workflow" 'name: openshell-prover-${{ matrix.rust_arch }}-unknown-linux-musl'
assert_contains "$snap_workflow" 'chmod +x prebuilt/prover/openshell-prover'
assert_contains "$snap_workflow" 'cp prebuilt/prover/openshell-prover snap/prebuilt/openshell-prover'
assert_contains "$snapcraft" 'for bin in openshell openshell-prover openshell-gateway openshell-sandbox openshell-gateway-wrapper; do'
assert_contains "$snapcraft" '"$CRAFT_PART_INSTALL/bin/openshell-prover"'
if ! awk '
/^ prover:$/ { in_prover = 1; next }
in_prover && /^ [[:alnum:]_-]+:$/ { finished = 1; exit }
in_prover && /command: bin\/openshell-prover/ { command = 1 }
in_prover && /- openshell-prover/ { alias = 1 }
in_prover && /^ plugs:$/ { in_plugs = 1; next }
in_prover && in_plugs && /^ - / {
plug_count++
if ($0 == " - home") home = 1
}
END { exit !(in_prover && finished && command && alias && home && plug_count == 1) }
' "$snapcraft"; then
echo "FAIL: Snap prover app must expose the openshell-prover alias with only home access" >&2
exit 1
fi
Comment thread
elezar marked this conversation as resolved.
assert_not_contains "$snap_install_docs" "snap connect openshell:home"
assert_not_contains "$snap_install_docs" "snap connect openshell:network"
assert_not_contains "$snap_install_docs" "snap connect openshell:network-bind"
assert_contains "$snap_install_docs" "snap connect openshell:docker :docker"
assert_contains "$snap_install_docs" "systemctl reset-failed snap.openshell.gateway.service"
assert_contains "$snap_install_docs" "snap restart openshell.gateway"
assert_contains "$snap_install_docs" "Snap refreshes keep the running gateway process active"
assert_contains "$snap_install_docs" "install script refreshes and restarts the gateway automatically"
assert_contains "$snap_canary" "install.sh | sh"
assert_contains "$snap_canary" "ubuntu-snap-system-docker:"
assert_contains "$snap_canary" "ubuntu-snap-docker-preflight:"
assert_contains "$snap_canary" "openshell.prover check"
assert_contains "$snap_repro" 'OPENSHELL_INSTALL_METHOD=snap OPENSHELL_VERSION=dev sh "${install_script}"'
assert_contains "$snap_repro" "/snap/bin/openshell.prover check"
assert_contains "$snap_repro" "system-docker"
assert_contains "$snap_repro" "missing-docker"
assert_contains "$snap_repro" "docker-snap"
Expand Down
Loading