Skip to content

Commit eb5197c

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

10 files changed

Lines changed: 104 additions & 9 deletions

File tree

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,32 @@ jobs:
231231
docker info
232232
sudo snap connections openshell | grep -E '^docker +openshell:docker +:docker +'
233233
openshell --version
234+
openshell.prover --version
234235
sudo snap services openshell
235236
openshell status
236237
238+
- name: Check a policy boundary with the Snap prover
239+
run: |
240+
set -euo pipefail
241+
prover_dir=$(mktemp -d "$HOME/openshell-prover-canary.XXXXXX")
242+
trap 'rm -rf "$prover_dir"' EXIT
243+
cat >"$prover_dir/boundary.yaml" <<'EOF'
244+
version: 1
245+
filesystem_policy:
246+
read_only:
247+
- /usr
248+
- /etc
249+
EOF
250+
cat >"$prover_dir/candidate.yaml" <<'EOF'
251+
version: 1
252+
filesystem_policy:
253+
read_only:
254+
- /usr
255+
EOF
256+
result=$(openshell.prover check "$prover_dir/candidate.yaml" \
257+
--boundary "$prover_dir/boundary.yaml")
258+
grep -q '^result: within_boundary$' <<<"$result"
259+
237260
- name: Create and exercise a sandbox
238261
run: |
239262
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
@@ -423,7 +423,7 @@ These workflows run after merge to publish dev/tagged artifacts and verify them.
423423
|---|---|
424424
| `.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. |
425425
| `.github/workflows/release-tag.yml` | Publishes tagged stable releases and manually dispatched pre-releases. Its automatic tag trigger excludes `-pre.*`. 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. |
426-
| `.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. |
426+
| `.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 positive Snap lane also runs a local policy containment check with the packaged prover. 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. |
427427

428428
## Required status contexts
429429

‎architecture/build.md‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ not reintroduce bundled Mozilla roots. Release builds that need bundled Z3
7777
continue to opt in with `bundled-z3`.
7878

7979
Release workflows build the standalone `openshell-prover` executable for Linux
80-
musl x86_64 and aarch64 and macOS Apple Silicon. The standard Debian, RPM, and
81-
Homebrew installations include it. Releases also publish one standalone archive
82-
per target plus a dedicated SHA-256 manifest. Before publication, target-native
83-
jobs extract each archive, reject host Z3 or Nix store linkage, and run a real
84-
local containment check. The standalone artifact therefore requires neither an
85-
OpenShell installation nor a separately installed Z3 runtime.
80+
musl x86_64 and aarch64 and macOS Apple Silicon. The standard Snap, Debian,
81+
RPM, and Homebrew installations include it. Releases also publish one
82+
standalone archive per target plus a dedicated SHA-256 manifest. Before
83+
publication, target-native jobs extract each archive, reject host Z3 or Nix
84+
store linkage, and run a real local containment check. The standalone artifact
85+
therefore requires neither an OpenShell installation nor a separately installed
86+
Z3 runtime.
8687

8788
## Linux Runtime Environments
8889

‎docs/about/installation.mdx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ The snap requires Docker Engine installed from your distribution or Docker's pac
7373
sudo snap install openshell
7474
```
7575

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

7883
The gateway runs as a system service at `http://127.0.0.1:17670` and reads `/var/snap/openshell/common/gateway.toml`.

‎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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh |
2525
openshell-prover --version
2626
```
2727

28+
For Snap installations, replace `openshell-prover` in these examples with
29+
`openshell.prover`. The `openshell-prover` Snap alias requires Store approval
30+
and may not be available.
31+
2832
The prover remains independent of the gateway at runtime. If you only need the
2933
standalone binary, use the artifacts listed in the
3034
[Support Matrix](/about/support-matrix#standalone-policy-prover). These

‎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_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,6 +80,7 @@ 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"
@@ -88,6 +89,7 @@ snap_install_hook="${ROOT}/snap/hooks/install"
8889
package_deb="${ROOT}/tasks/scripts/package-deb.sh"
8990
assert_file_exists "$snap_wrapper"
9091
assert_file_exists "$snapcraft"
92+
assert_file_exists "$snap_workflow"
9193
assert_file_exists "$snap_install_docs"
9294
assert_file_exists "$snap_canary"
9395
assert_file_exists "$snap_repro"
@@ -125,14 +127,33 @@ if [[ ! -x "$snap_install_hook" ]]; then
125127
fi
126128
assert_contains "$snap_install_hook" 'allow_unauthenticated_users = true'
127129
bash "$ROOT/tasks/scripts/test-snap-install-hook.sh" "$snap_install_hook"
130+
assert_contains "$snap_workflow" 'name: openshell-prover-${{ matrix.rust_arch }}-unknown-linux-musl'
131+
assert_contains "$snap_workflow" 'chmod +x prebuilt/prover/openshell-prover'
132+
assert_contains "$snap_workflow" 'cp prebuilt/prover/openshell-prover snap/prebuilt/openshell-prover'
133+
assert_contains "$snapcraft" 'for bin in openshell openshell-prover openshell-gateway openshell-sandbox openshell-gateway-wrapper; do'
134+
assert_contains "$snapcraft" '"$CRAFT_PART_INSTALL/bin/openshell-prover"'
135+
if ! awk '
136+
/^ prover:$/ { in_prover = 1; next }
137+
in_prover && /^ [[:alnum:]_-]+:$/ { finished = 1; exit }
138+
in_prover && /command: bin\/openshell-prover/ { command = 1 }
139+
in_prover && /- openshell-prover/ { alias = 1 }
140+
in_prover && /- home/ { home = 1 }
141+
in_prover && /- (docker|log-observe|network|network-bind|system-observe)/ { broad_plug = 1 }
142+
END { exit !(in_prover && finished && command && alias && home && !broad_plug) }
143+
' "$snapcraft"; then
144+
echo "FAIL: Snap prover app must expose the openshell-prover alias with only home access" >&2
145+
exit 1
146+
fi
128147
assert_not_contains "$snap_install_docs" "snap connect openshell:home"
129148
assert_not_contains "$snap_install_docs" "snap connect openshell:network"
130149
assert_not_contains "$snap_install_docs" "snap connect openshell:network-bind"
131150
assert_contains "$snap_install_docs" "snap connect openshell:docker :docker"
132151
assert_contains "$snap_canary" "install.sh | sh"
133152
assert_contains "$snap_canary" "ubuntu-snap-system-docker:"
134153
assert_contains "$snap_canary" "ubuntu-snap-docker-preflight:"
154+
assert_contains "$snap_canary" "openshell.prover check"
135155
assert_contains "$snap_repro" 'OPENSHELL_VERSION=dev sh "${install_script}"'
156+
assert_contains "$snap_repro" "/snap/bin/openshell.prover check"
136157
assert_contains "$snap_repro" "system-docker"
137158
assert_contains "$snap_repro" "missing-docker"
138159
assert_contains "$snap_repro" "docker-snap"

0 commit comments

Comments
 (0)