Skip to content

Let CI runners give Chromium a usable sandbox - #11

Merged
gersham merged 2 commits into
mainfrom
cursor/fix-chromium-sandbox-ci-699a
Sep 24, 2026
Merged

gersham merged 2 commits into
mainfrom
cursor/fix-chromium-sandbox-ci-699a

Conversation

@gersham

@gersham gersham commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Public plugin gates have been red on main since the dashboard skill landed. verify fails in test_real_browser_repeat_and_failed_render_preserves_latest:

BrowserType.launch: Target page, context or browser has been closed
Browser logs:
Chromium sandboxing failed!
[...] No usable sandbox! If you are running on Ubuntu 23.10+ or another Linux distro
that has disabled unprivileged user namespaces with AppArmor [...]

skills/screenrig-dashboard/scripts/dashboard_runtime/render.py deliberately launches with chromium_sandbox=True, and the dashboarding design says not to weaken that sandbox when launch fails. GitHub's ubuntu-latest image ships kernel.apparmor_restrict_unprivileged_userns=1, and Playwright's Chromium carries no SUID sandbox helper, so the only sandbox it can use is unavailable there. This is not a regression in the renderer: the browser gate is new with the dashboard skill and has never run green on a GitHub runner.

Fix

Take Chromium's own preferred option — make the environment support sandboxing — rather than disabling the sandbox:

  • .github/workflows/ci.yml: a new step before the dashboard gate clears /proc/sys/kernel/apparmor_restrict_unprivileged_userns when that knob exists, on a throwaway runner. This is the workaround Chromium documents and that projects such as pa11y use in Actions.
  • skills/screenrig-dashboard/references/runtime.md: records that rendering always keeps the sandbox on, and that Linux hosts confining unprivileged user namespaces must grant them to the browser instead of rendering unsandboxed.
  • plugins/screenrig/: regenerated. The CLI bundle and manifests are unchanged.

No product launch flag, no --no-sandbox, and no change to local developer defaults.

CLI provenance refresh

The first run on this branch failed before the dashboard step, in "Rebuild and verify the committed plugin bundle":

Committed CLI tarball provenance differs from current screenrig/cli main
packed   f5feb909b96467573819bfd6569630e74fdaf708cf22eb74f6de52e8883823e1
recorded e0e06065ee8c44edf094df6174c153b26be5c239677f5d06e78afe406a33ce9c

screenrig/cli main has not moved: it is still ce737dde6dd179fa5bcbfe2bb2a59ddb266bfa5c, the commit already in components.lock.json. That commit has since collected eight CalVer tags (v26.09.190 … v26.09.204), and scripts/calver.py cli-stamp picks the highest, so package-release.sh stamps a later version and the same source packs to different bytes. Packing that commit locally confirms it: stamp 26.09.200 reproduces e0e0606… (the old recorded digest) and stamp 26.09.204 reproduces f5feb90… byte-for-byte, the digest CI packed.

components.lock.json now records that current pack. The generated bundle is byte-identical because the build normalizes the bundled CLI version, so this commit is provenance only.

Verification

On a real ubuntu-latest runner, via a temporary probe workflow on a scratch branch (run 35940119744, branch since deleted), running exactly these steps against this tree:

userns blocked          # before the new step
userns allowed          # after the new step
Ran 13 tests in 4.626s
OK                      # scripts/test-dashboard.py --browser, sandbox still on

Full local gate set against the re-packed artifact:

  • build-plugin.py --check --cli-artifact — generated plugin is current
  • validate-plugin.py --cli-artifact --cli-source — validation passed
  • check-public-repo.py — passed
  • test-public-dependencies.py, test-skill-commands.py, test-launcher.py, test-plugin-freshness.py, test-docs-only.py — passed
  • screenrig version — clean JSON envelope
  • size budget — tree 330,632,142 B and archive 140,183,571 B, both under budget, no stray large files
  • test-dashboard.py --browser — 13 tests pass with chromium_sandbox=True

Marketplace installation, live API use, native hardware and production deployment were not exercised.

Open in Web Open in Cursor 

cursoragent and others added 2 commits September 24, 2026 00:44
GitHub's Ubuntu runners confine unprivileged user namespaces with
AppArmor, so the dashboard renderer's sandboxed Chromium launch failed
the real-browser gate. Allow user namespaces on the runner instead of
rendering without a sandbox, and document the same requirement for
Linux hosts that confine them.

Co-authored-by: Gersham Meharg <gersham@users.noreply.github.com>
screenrig/cli main is unchanged at ce737dd, but that commit has since
been tagged v26.09.204, so package-release.sh stamps a later CalVer and
the tarball no longer hashes to the recorded digest. Re-pack that commit
and record the artifact CI packs today; the generated bundle is
unchanged because the bundled CLI version is normalized.

Co-authored-by: Gersham Meharg <gersham@users.noreply.github.com>
@gersham
gersham marked this pull request as ready for review September 24, 2026 01:03
@gersham
gersham merged commit 329dcbc into main Sep 24, 2026
3 checks passed
@gersham
gersham deleted the cursor/fix-chromium-sandbox-ci-699a branch September 25, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants