Repository navigation
[infra] - Select the bwrap AppArmor CI proof from Ubuntu VERSION_ID - #1644
Merged
Merged
Conversation
Ubuntu 26.04 already enforces profile bwrap on /usr/bin/bwrap. Loading cyclaw-bwrap beside it denies net_admin and the confinement command fails. 24.04 keeps the noble pin, the stock refusal, and the profile load. Co-authored-by: Chris Grady <cgfixit@users.noreply.github.com>
Owner
Author
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
cgfixit
marked this pull request as ready for review
October 13, 2026 10:56
…version-aware-1517 # Conflicts: # .github/workflows/ci.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Branch naming (required for agent-opened PRs)
Head branch:
agent/bwrap-apparmor-version-aware-1517.The driver for this session is a Cursor cloud agent. The tracked hooks allow
agent/and refusecursor/. The task asked for anagent/branch cut frommain, not #1641's branchagent/ubuntu-26-04-bwrap-apparmor-b991.Title
[infra] - Select the bwrap AppArmor CI proof from Ubuntu VERSION_IDProposed changes
Makes the Linux bubblewrap AppArmor proof in
.github/workflows/ci.ymlfollowVERSION_IDfrom/etc/os-release, and runs that same script on a non-required Ubuntu 26.04 job. Linked issue: #1626. Measured on #1641, run https://github.com/cgfixit/CyClaw/actions/runs/38352458013, jobubuntu-26-04-bwrap-diagnose.scripts/ci/bwrap-apparmor-check.shis the only copy of the proof. The requiredtestmatrix Linux legs and the new job both runbash scripts/ci/bwrap-apparmor-check.sh.bubblewrap=0.6.1-1ubuntu0.3and the stock confinement command. It does not loadcyclaw-bwrap.bubblewrap=0.9.0-1ubuntu0.3,kernel.apparmor_restrict_unprivileged_usernsmust read1, stockbwrapmust be refused with a userns/permission denial, thendeploy/apparmor/cyclaw-bwrapis loaded, then the confinement command must pass.cyclaw-bwrapand do not install0.9.0-1ubuntu0.3. The script installs the candidate listed inapt-cache policy bubblewrap's version table (apt-cache showof the noble pin exited 0 on 26.04 even though that version was not in the table). It then requires the sysctl to read1, Ubuntu'sbwrapprofile to be loaded in enforce mode, a copy ofbwrapoutside/usr/binto fail withbwrap: loopback: Failed RTM_NEWADDR: Operation not permitted, and the same confinement command to pass for/usr/bin/bwrap. The child label must bebwrap//&unpriv_bwrap (enforce).VERSION_IDfails the job.The new job is
ubuntu-26.04 bwrap(runs-on: ubuntu-26.04,continue-on-error: true,timeout-minutes: 15). That name is notubuntu-latest,windows-latest,macos-latest,invariant-guard, ordotenv-guard. Thetestmatrix entries are unchanged, so those required check names stay the same. When GitHub movesubuntu-latestto 26.04, that required job followsVERSION_IDinstead of loadingcyclaw-bwrapon a host that already has Ubuntu's profile..github/actionlint.yamlallowlists the labelubuntu-26.04for actionlint 1.7.12, which does not know that label. The label is a GitHub-hosted runner. The file does not provision a machine.Operator docs that said "24.04 and newer: load
cyclaw-bwrap" now say not to load it on 26.04, because that is the measured failure. The profile rules indeploy/apparmor/cyclaw-bwrapare unchanged.Invariant / Governance Impact
gate.py,gate_ops.py,gate_auth.py,gate_memory.py,graph.py,mcp_hybrid_server.py, soul handling, the sanitizer, auth, or retrieval.Types of changes
Optional free-text scope note (recommended):
Infrastructure / CI only. Operator docs for the bubblewrap profile were corrected so Ubuntu 26.04 is not told to load
cyclaw-bwrap.Benefits / why
/usr/bin/bwrapalready runs underbwrap (enforce)and the confinement command exits 0. Loadingdeploy/apparmor/cyclaw-bwrapbeside that profile makes the same command fail withbwrap: loopback: Failed RTM_NEWADDR: Operation not permitted. The requiredubuntu-lateststeps used to load that profile whenever the runner label wasubuntu-latest. After GitHub's move to Ubuntu 26, those steps would fail the confinement proof. This change keeps the 24.04 proof and switches 26.04+ to the stock profile instead of weakening the 24.04 refusal.1.apt-cache policy's version table is what decides the 26.04 package. The noble pin is refused if it is the candidate.Risks to monitor
main.continue-on-error: truemeans a later failure of that job does not fail the workflow. The signal is the job log. The requiredubuntu-latestleg is still blocking, and it will take the 26.04 branch once that image is whatubuntu-latestis.0.9.0-1ubuntu0.3is still refused.bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted. A different refusal string fails the job. That is not a loosened check..github/actionlint.yamlallowlistsubuntu-26.04for actionlint only..github/workflows/ci.yml. Trial-merging this branch after [infra] - Prove bwrap AppArmor policy on Ubuntu 26.04 without weakening the checks #1641 conflicts in that file. Do not merge both.setup-guide.mdgives stock 24.04 users.kernel.apparmor_restrict_unprivileged_userns=1, a loaded linebwrap (enforce), the copy'sRTM_NEWADDRline, and/usr/bin/bwrapexit 0 with child labelbwrap//&unpriv_bwrap (enforce). On 24.04, the stock refusal line and a passing confinement command afterapparmor_parser -r.Checklist
docs/THREAT_MODEL.md,INVARIANTS.mdandSECURITY.md(and any relevant Phase docs)GROK_API_KEY=dummy pytest tests/ -q --tb=short, andbash .claude/skills/CyClaw-Sandbox/verify.shfor core RAG/agentic paths) and passes with no regressionsFurther comments
Human review note: the diff touches
.github/workflows/ci.ymland adds.github/actionlint.yaml. The checkout action pin is the existing SHAactions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1(v7.0.1) withpersist-credentials: false. No new third-party action. This PR is a draft. Do not merge it and do not enable auto-merge.What #1641 measured, and what this PR does with it:
/etc/apparmor.d/bwrap-userns-restrict(profile bwrap /usr/bin/bwrap flags=(attach_disconnected,mediate_deleted)). Loaded profiles includebwrap (enforce). The confinement command exits 0. The child label wasbwrap//&unpriv_bwrap (enforce).bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted.cyclaw-bwrapmakes that same command exit 1 with the same line. Removingcyclaw-bwrapmakes it exit 0 again.0.11.1-1ubuntu0.3(bwrap --versionprintedbubblewrap 0.11.1).apt-cache show 'bubblewrap=0.9.0-1ubuntu0.3'printednoble_pin=presentwhile the version table listed only0.11.1-1ubuntu0.3and0.11.1-1.Local checks, not a full suite:
bash -non the script; a fixture of that version table (the noble string in a pin URL is not treated as a version row;0.9.0-1ubuntu0.3as a real candidate is recognized so the script can refuse it);is_2604_or_newerfor 22.04, 24.04, 24.10, 25.10, 26.03, 26.04, 26.10, 28.04, and08.04(decimal, not octal); ShellCheck 0.9.0; actionlint 1.7.12; zizmor 1.28.0--min-severity=highboth offline and with a GitHub token; the five functions intests/security/test_bwrap_apparmor_profile_scope.py; ruff F/B/S on that file.pytest tests/was not run. Hosted proof is run https://github.com/cgfixit/CyClaw/actions/runs/38355973489, which completed with success on head70610083:ubuntu-26.04 bwrappassed (job 115158837026) and requiredubuntu-lateston Ubuntu 24.04.5 passed (job 115158836925), with all checks green.Suggested merge order of open PRs
Trial merges verified (
git merge --no-commit --no-ff+ abort) against main @ 663a8bb on 2026-10-13. This branch after a local merge of #1641 conflicts in.github/workflows/ci.yml.#1637 · Safe ✅
Impact: Telemetry egress notes for the Keychain CLI and uv. Trial merge clean. No file overlap with this PR.
Action: Merge when the in-progress checks finish green. No current failing check; an older template check was cancelled.
#1638 · Safe ✅
Impact: Ponytail audit notes. Trial merge clean. No dependency on this PR.
Action: Merge when the in-progress checks finish green. No current failing check; an older template check was cancelled.
#1640 · Safe ✅
Impact: Dependency currency notes. Trial merge clean. No dependency on this PR.
Action: Merge when the still-running checks finish green. No failing check at this trial merge.
#1641 · Blocked ⛔
Impact: Non-required Ubuntu 26.04 diagnosis. Trial merge against main is clean. Merging it before this PR conflicts in
.github/workflows/ci.yml.Action: Do not merge and do not auto-merge. This PR is the fix. Close #1641 if this one lands.
#1642 · Blocked ⛔
Impact: Skill-doc alignment. Trial merge clean.
Check PR body against templateis failing.Action: Do not merge while that check is red and the PR is still a draft.
#1643 · Blocked ⛔
Impact: Checker-skill resync. Trial merge clean. Still a draft; checks were still queued.
Action: Do not merge until it is ready and its checks are green.
#1644 · Blocked ⛔
Impact: Version-aware bwrap proof. Draft. Replaces #1641's diagnosis job. Trial merge against main is clean.
Action: Do not merge and do not auto-merge. Required check names are unchanged. CI run 38355973489 passed on head
70610083. Still a draft; needs the Advisor's pass and the owner's go.ELI5
The required Ubuntu test used to assume stock AppArmor blocks bubblewrap until CyClaw loads
deploy/apparmor/cyclaw-bwrap. On Ubuntu 26.04 that assumption is backwards. Jobubuntu-26-04-bwrap-diagnosein run 38352458013 showed stock/usr/bin/bwrapalready works, because Ubuntu's ownbwrapprofile is loaded in enforce mode, and the confinement command exits 0. A copy that is not at/usr/bin/bwrapis refused withbwrap: loopback: Failed RTM_NEWADDR: Operation not permitted. Loading CyClaw's profile next to Ubuntu's profile makes/usr/bin/bwrapfail the same way.scripts/ci/bwrap-apparmor-check.shreadsVERSION_IDfrom/etc/os-release. Ubuntu 24.04 still does the old proof: refuse, loadcyclaw-bwrap, then confine, and it still installs the noble package pin. Ubuntu 26.04 and newer do not load CyClaw's profile and do not install that pin. They check that the kernel switch still reads 1, that Ubuntu'sbwrapprofile is in enforce mode, that a copy outside/usr/binis refused, and that/usr/bin/bwrappasses the same confinement command. Any other version fails on purpose. The script never turns the kernel switch off.The required check is still named
ubuntu-latest. A separate practice job namedubuntu-26.04 bwrapruns the same script onubuntu-26.04and iscontinue-on-error, so it is not a required check.pytest tests/was not run here. Do not merge this draft, and do not turn on auto-merge.Last updated: 2026-10-13 03:15 ET