Skip to content

Commit d190b98

Browse files
committed
feat(snap): ship the standalone prover binary in the snap
Signed-off-by: Oliver Calder <oliver.calder@canonical.com>
1 parent 8091f66 commit d190b98

9 files changed

Lines changed: 104 additions & 4 deletions

File tree

‎.github/workflows/release-canary.yml‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,35 @@ jobs:
233233
docker info
234234
sudo snap connections openshell | grep -E '^docker +openshell:docker +:docker +'
235235
openshell --version
236+
openshell.prover --version
236237
sudo snap services openshell
237238
sudo journalctl -b -u snap.openshell.gateway.service --no-pager |
238239
grep -F "mTLS user authentication enabled"
239240
openshell gateway list | grep -F "https://127.0.0.1:17670"
240241
openshell status
241242
243+
- name: Check a policy boundary with the Snap prover
244+
run: |
245+
set -euo pipefail
246+
prover_dir=$(mktemp -d "$HOME/openshell-prover-canary.XXXXXX")
247+
trap 'rm -rf "$prover_dir"' EXIT
248+
cat >"$prover_dir/boundary.yaml" <<'EOF'
249+
version: 1
250+
filesystem_policy:
251+
read_only:
252+
- /usr
253+
- /etc
254+
EOF
255+
cat >"$prover_dir/candidate.yaml" <<'EOF'
256+
version: 1
257+
filesystem_policy:
258+
read_only:
259+
- /usr
260+
EOF
261+
result=$(openshell.prover check "$prover_dir/candidate.yaml" \
262+
--boundary "$prover_dir/boundary.yaml")
263+
grep -q '^result: within_boundary$' <<<"$result"
264+
242265
- name: Create and exercise a sandbox
243266
run: |
244267
set -euo pipefail

‎.github/workflows/snap-package.yml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ jobs:
8989
name: openshell-${{ matrix.rust_arch }}-unknown-linux-musl
9090
path: prebuilt/cli
9191

92+
- name: Download prebuilt prover binary
93+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
94+
with:
95+
name: openshell-prover-${{ matrix.rust_arch }}-unknown-linux-musl
96+
path: prebuilt/prover
97+
9298
- name: Download prebuilt gateway binary
9399
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
94100
with:
@@ -105,6 +111,7 @@ jobs:
105111
run: |
106112
set -euo pipefail
107113
chmod +x prebuilt/cli/openshell
114+
chmod +x prebuilt/prover/openshell-prover
108115
chmod +x prebuilt/gateway/openshell-gateway
109116
chmod +x prebuilt/sandbox/openshell-sandbox
110117
ls -laR prebuilt/
@@ -115,6 +122,7 @@ jobs:
115122
mkdir -p snap/prebuilt
116123
117124
cp prebuilt/cli/openshell snap/prebuilt/openshell
125+
cp prebuilt/prover/openshell-prover snap/prebuilt/openshell-prover
118126
cp prebuilt/gateway/openshell-gateway snap/prebuilt/openshell-gateway
119127
cp prebuilt/sandbox/openshell-sandbox snap/prebuilt/openshell-sandbox
120128

‎CI.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ These workflows run after merge to publish dev/tagged artifacts and verify them.
491491
|---|---|
492492
| `.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. |
493493
| `.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. |
494-
| `.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. |
494+
| `.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. |
495495

496496
## Required status contexts
497497

‎docs/about/installation.mdx‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,16 @@ sudo loginctl enable-linger $USER
106106

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

109+
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:
110+
109111
```shell
110112
sudo snap install openshell
111113
```
112114

113-
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`.
115+
The snap installs the standalone policy prover as `openshell.prover`. The
116+
`openshell-prover` alias requires Snap Store approval and may not be available.
117+
The prover reads local policy files through the `home` interface and does not
118+
connect to the gateway.
114119

115120
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:
116121

‎docs/about/support-matrix.mdx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ OpenShell publishes standalone `openshell-prover` release assets for manual down
106106

107107
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.
108108

109+
The Debian, RPM, Homebrew, and Snap packages also include the prover. Debian,
110+
RPM, and Homebrew installations expose it as `openshell-prover`; use
111+
`openshell.prover` with the Snap. The `openshell-prover` Snap alias requires
112+
Store approval and may not be available.
113+
109114
## Runtimes
110115

111116
The gateway can manage sandboxes through several runtimes.

‎docs/how-it-works/policies/prover.mdx‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ contain access that the proposal risk check would flag.
3636
This page covers the boundary check. To learn about the proposal risk check,
3737
refer to [Policy Advisor](/how-it-works/policies/advisor).
3838

39+
For Snap installations, replace `openshell-prover` in these examples with
40+
`openshell.prover`. The `openshell-prover` Snap alias requires Store approval
41+
and may not be available.
42+
43+
The prover remains independent of the gateway at runtime. If you only need the
44+
standalone binary, use the artifacts listed in the
45+
[Support Matrix](/about/support-matrix#standalone-policy-prover). These
46+
artifacts and `openshell-prover-checksums-sha256.txt` are attached to
47+
[OpenShell releases](https://github.com/NVIDIA/OpenShell/releases).
48+
3949
## Run a Boundary Check
4050

4151
A boundary check compares the policy you are testing, called the candidate, with

‎nix/test-guest/scripts/snap-gateway-repro.sh‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,39 @@ for attempt in $(seq 1 "${attempts}"); do
127127
fi
128128

129129
sandbox="snap-${attempt}-$$"
130+
prover_dir=$(mktemp -d "$HOME/openshell-prover-repro.XXXXXX")
131+
cat >"${prover_dir}/boundary.yaml" <<'EOF'
132+
version: 1
133+
filesystem_policy:
134+
read_only:
135+
- /usr
136+
- /etc
137+
EOF
138+
cat >"${prover_dir}/candidate.yaml" <<'EOF'
139+
version: 1
140+
filesystem_policy:
141+
read_only:
142+
- /usr
143+
EOF
130144
if ! OPENSHELL_INSTALL_METHOD=snap OPENSHELL_VERSION=dev sh "${install_script}" ||
131145
! sudo snap list openshell >/dev/null ||
132146
! snap info openshell | grep -Eq '^tracking: +latest/edge$' ||
133147
! docker_is_ready ||
134148
! sudo snap connections openshell | grep -Eq '^docker +openshell:docker +:docker +' ||
135149
! /snap/bin/openshell status ||
150+
! /snap/bin/openshell.prover --version ||
151+
! /snap/bin/openshell.prover check "${prover_dir}/candidate.yaml" \
152+
--boundary "${prover_dir}/boundary.yaml" | grep -q '^result: within_boundary$' ||
136153
! /snap/bin/openshell sandbox create --name "${sandbox}" --detach ||
137154
! /snap/bin/openshell sandbox exec --name "${sandbox}" --no-tty -- true ||
138155
! /snap/bin/openshell sandbox delete "${sandbox}"; then
139156
echo "install.sh Snap reproduction failed" >&2
140157
diagnostics "${attempt}"
141158
failures=$((failures + 1))
159+
rm -rf "${prover_dir}"
142160
continue
143161
fi
162+
rm -rf "${prover_dir}"
144163

145164
if sudo snap list docker >/dev/null 2>&1; then
146165
echo "install.sh unexpectedly installed the Docker snap" >&2

‎snapcraft.yaml‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ description: |
1212
profile-backed model-provider access.
1313
1414
The OpenShell snap ships a CLI (`openshell`), a terminal UI
15-
(`openshell.term`), and a managed gateway daemon (`openshell.gateway`).
15+
(`openshell.term`), a standalone policy prover (`openshell.prover`), and a
16+
managed gateway daemon (`openshell.gateway`).
1617
1718
**Setup instructions**
1819
@@ -85,6 +86,12 @@ apps:
8586
- home
8687
- network
8788
- system-observe
89+
prover:
90+
command: bin/openshell-prover
91+
aliases:
92+
- openshell-prover
93+
plugs:
94+
- home
8895
gateway:
8996
command: bin/openshell-gateway-wrapper
9097
daemon: simple
@@ -120,7 +127,7 @@ parts:
120127
set -euo pipefail
121128
122129
MISSING=()
123-
for bin in openshell openshell-gateway openshell-sandbox openshell-gateway-wrapper; do
130+
for bin in openshell openshell-prover openshell-gateway openshell-sandbox openshell-gateway-wrapper; do
124131
if [ ! -f "$CRAFT_PART_SRC/$bin" ]; then
125132
MISSING+=("$bin")
126133
fi
@@ -138,6 +145,8 @@ parts:
138145
139146
install -D -m 0755 "$CRAFT_PART_SRC/openshell" \
140147
"$CRAFT_PART_INSTALL/bin/openshell"
148+
install -D -m 0755 "$CRAFT_PART_SRC/openshell-prover" \
149+
"$CRAFT_PART_INSTALL/bin/openshell-prover"
141150
install -D -m 0755 "$CRAFT_PART_SRC/openshell-gateway" \
142151
"$CRAFT_PART_INSTALL/bin/openshell-gateway"
143152
install -D -m 0755 "$CRAFT_PART_SRC/openshell-sandbox" \

‎tasks/scripts/test-packaging-assets.sh‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,15 @@ assert_not_contains "$spec" '%%S/openshell/tls'
8080
# Schema-v2 package startup wiring.
8181
snap_wrapper="${ROOT}/tasks/scripts/snap-gateway-wrapper.sh"
8282
snapcraft="${ROOT}/snapcraft.yaml"
83+
snap_workflow="${ROOT}/.github/workflows/snap-package.yml"
8384
snap_install_docs="${ROOT}/docs/about/installation.mdx"
8485
snap_canary="${ROOT}/.github/workflows/release-canary.yml"
8586
snap_repro="${ROOT}/nix/test-guest/scripts/snap-gateway-repro.sh"
8687
snap_post_refresh_hook="${ROOT}/snap/hooks/post-refresh"
8788
package_deb="${ROOT}/tasks/scripts/package-deb.sh"
8889
assert_file_exists "$snap_wrapper"
8990
assert_file_exists "$snapcraft"
91+
assert_file_exists "$snap_workflow"
9092
assert_file_exists "$snap_install_docs"
9193
assert_file_exists "$snap_canary"
9294
assert_file_exists "$snap_repro"
@@ -131,6 +133,23 @@ if [[ ! -x "$snap_post_refresh_hook" ]]; then
131133
fi
132134
assert_not_contains "$ROOT/tasks/scripts/snap-gateway-wrapper.sh" 'OPENSHELL_DISABLE_TLS'
133135
bash "$ROOT/tasks/scripts/test-snap-post-refresh-hook.sh" "$snap_post_refresh_hook"
136+
assert_contains "$snap_workflow" 'name: openshell-prover-${{ matrix.rust_arch }}-unknown-linux-musl'
137+
assert_contains "$snap_workflow" 'chmod +x prebuilt/prover/openshell-prover'
138+
assert_contains "$snap_workflow" 'cp prebuilt/prover/openshell-prover snap/prebuilt/openshell-prover'
139+
assert_contains "$snapcraft" 'for bin in openshell openshell-prover openshell-gateway openshell-sandbox openshell-gateway-wrapper; do'
140+
assert_contains "$snapcraft" '"$CRAFT_PART_INSTALL/bin/openshell-prover"'
141+
if ! awk '
142+
/^ prover:$/ { in_prover = 1; next }
143+
in_prover && /^ [[:alnum:]_-]+:$/ { finished = 1; exit }
144+
in_prover && /command: bin\/openshell-prover/ { command = 1 }
145+
in_prover && /- openshell-prover/ { alias = 1 }
146+
in_prover && /- home/ { home = 1 }
147+
in_prover && /- (docker|log-observe|network|network-bind|system-observe)/ { broad_plug = 1 }
148+
END { exit !(in_prover && finished && command && alias && home && !broad_plug) }
149+
' "$snapcraft"; then
150+
echo "FAIL: Snap prover app must expose the openshell-prover alias with only home access" >&2
151+
exit 1
152+
fi
134153
assert_not_contains "$snap_install_docs" "snap connect openshell:home"
135154
assert_not_contains "$snap_install_docs" "snap connect openshell:network"
136155
assert_not_contains "$snap_install_docs" "snap connect openshell:network-bind"
@@ -142,7 +161,9 @@ assert_contains "$snap_install_docs" "install script refreshes and restarts the
142161
assert_contains "$snap_canary" "install.sh | sh"
143162
assert_contains "$snap_canary" "ubuntu-snap-system-docker:"
144163
assert_contains "$snap_canary" "ubuntu-snap-docker-preflight:"
164+
assert_contains "$snap_canary" "openshell.prover check"
145165
assert_contains "$snap_repro" 'OPENSHELL_INSTALL_METHOD=snap OPENSHELL_VERSION=dev sh "${install_script}"'
166+
assert_contains "$snap_repro" "/snap/bin/openshell.prover check"
146167
assert_contains "$snap_repro" "system-docker"
147168
assert_contains "$snap_repro" "missing-docker"
148169
assert_contains "$snap_repro" "docker-snap"

0 commit comments

Comments
 (0)