docs(security): running application isolation under Docker (CAP_SYS_ADMIN + seccomp) - #20
Conversation
✅ Deploy Preview
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3ca1fbf65b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
There was a problem hiding this comment.
Code Review
This pull request adds documentation to explain how to configure Docker containers to support the isolation feature, including necessary syscalls and capability requirements. The review comment suggests improving the readability of the configuration options by restructuring them into a nested list and provides a technical correction regarding which syscalls require explicit allowance in a custom seccomp profile.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Address Codex + Gemini review on #20, verified against moby's default seccomp profile (profiles/seccomp/default.json) and Unit's nxt_isolation_change_root(): - Docker's default profile allows unshare/mount/umount2 once the container holds CAP_SYS_ADMIN (they are gated on it via includes.caps), and allows chroot (default CAP_SYS_CHROOT) and openat2 unconditionally. Only pivot_root is absent from the profile and denied even with CAP_SYS_ADMIN. The old "doesn't allow mount/umount2/pivot_root regardless of capabilities" was wrong for mount/umount2. - Stop recommending --security-opt seccomp=unconfined as the simple default: it disables the bundled AF_ALG deny (CVE-2026-31431). A chroot-based rootfs needs only --cap-add SYS_ADMIN with the default profile; a pivot_root-based rootfs should extend seccomp-no-af-alg.json with a pivot_root allow rule instead of turning seccomp off. - Restructure as a nested list split by chroot- vs pivot_root-based rootfs (Gemini readability suggestion). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017r3PHLb7YSsDTGmuJNpfPm
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9f172791d5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e267401773
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
Address Codex review on #20, verified against moby's AppArmor template (profiles/apparmor/template.go): docker-default grants network/capability/ file/umount and "deny mount", but has no pivot_root rule. Because the profile mediates the mount class, pivot_root (unlisted) is denied by default too. So a custom AppArmor profile for a pivot_root-based rootfs must allow both mount and pivot_root, not just override the mount deny. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017r3PHLb7YSsDTGmuJNpfPm
|
@codex review /gemini review |
There was a problem hiding this comment.
Code Review
This pull request adds documentation on running Unit's application isolation feature inside Docker containers, detailing the necessary capabilities, seccomp profiles, and AppArmor configurations. The review feedback suggests clarifying that older Docker versions (< 20.10.10) require a custom seccomp profile for chroot-based rootfs due to openat2 usage, and recommends fixing split-line inline markups to prevent potential reStructuredText rendering issues.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a2d142314
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
Address the second Codex + Gemini review on #20, verified against moby's default seccomp/AppArmor profiles and Unit's nxt_isolation source: - Codex P2 (pivot_root profile): seccomp-no-af-alg.json is defaultAction: SCMP_ACT_ALLOW, so it already permits pivot_root — adding a pivot_root allow rule to it is a no-op. Recommend running that bundled profile (keeps the AF_ALG mitigation AND allows every isolation syscall); only a Docker-default-derived profile needs an explicit pivot_root allow. Also drop the self-contradictory "keep the default profile and the AF_ALG mitigation" claim — the default profile does not deny AF_ALG. - Codex P2 (chroot recipe): nxt_isolation_prepare_rootfs() runs whenever a rootfs has mounts (default automounts on), independent of the namespace flag, so a chroot-only rootfs also calls mount()/openat2() in the host namespace. It therefore also hits docker-default AppArmor's "deny mount"; the chroot path is no longer described as "capability only". - Gemini (openat2): openat2 is used for both rootfs mechanisms, so pre- 20.10.10 Docker needs it allowed for the chroot path too. - Gemini (rST): keep the :ref: role and inline markup on single lines. Restructured the block around the three independent Docker layers (capability, seccomp, AppArmor) with a combined recipe. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017r3PHLb7YSsDTGmuJNpfPm
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f62f59b65
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
…OW one Address Codex review on #20 (commit 7f62f59). seccomp-no-af-alg.json is defaultAction: SCMP_ACT_ALLOW, so recommending it as the simple path for a pivoting rootfs silently discards the rest of Docker's default seccomp denylist. Present two options for unblocking pivot_root, with the hardened one preferred: - Preferred: copy Docker's default profile and add a pivot_root allow rule (keeps the full denylist); add the AF_ALG/TIPC socket denies to also carry the CVE-2026-31431 mitigation. - Simplest: run the bundled seccomp-no-af-alg.json, noting it forfeits the rest of Docker's default denylist. The combined example is relabeled the "simplest" recipe with a pointer to the hardened variant. Note on Codex's factual premise: verified moby default.json across v24.0.9..v28.3.0 — none block AF_ALG (value 38 never appears; the socket rule only filters AF_VSOCK/40), so Docker's released default profile does not carry the AF_ALG mitigation. The clarified text says as much. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017r3PHLb7YSsDTGmuJNpfPm
46a2023 to
8556378
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8556378254
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d594f40349
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
|
/gemini review |
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cd399d11c4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
|
@codex review |
|
/gemini review |
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
|
Codex Review: Didn't find any major issues. 🚀 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". |
0d6c0ae to
2122477
Compare
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0d6c0ae736
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Add a "Running Isolation in a Container (Docker)" section to the security how-to covering the three gates an isolated app must clear under Docker -- the SYS_ADMIN capability, the seccomp profile, and AppArmor/SELinux -- with the syscalls Unit's isolation uses (unshare, mount, umount2, pivot_root, chroot, openat2) mapped to each gate and a diagnostic recipe for telling a capability, seccomp, or LSM denial apart. Document blocking AF_ALG (CVE-2026-31431) with the bundled seccomp-no-af-alg.json: how to pass or extract it, the intentional SCMP_ACT_ALLOW default, the host-level algif_aead module blacklist, and a verify step. Scope the profile honestly -- it denies AF_ALG only (not TIPC), and it filters the direct socket(2) call only, so a warning and the cross-LSM note flag that the socketcall(2) multiplexer still reaches AF_ALG on i386/s390x and via the x86-64 int 0x80 entry, closed by an AppArmor (deny network alg) / SELinux (alg_socket) rule or the module blacklist. Cross-reference the new section from the configuration index's isolation note. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017r3PHLb7YSsDTGmuJNpfPm
abad8d5 to
0bc4861
Compare
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review once |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The call-docs-build-push job dropped its job-level permissions block, so the reusable workflow's deploy job (which needs pages: write + id-token: write) exceeded the caller grant (contents: read) and the run failed at startup — the site stopped deploying. Restore the block that was present when #20 last deployed successfully. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DYcuURscruaF1yNVHJHW3C
Summary
Documents how to run FreeUnit's application isolation feature inside a container (Docker), which fails with
EPERMunder default container settings.Why
FreeUnit's
isolation(user/pid/net/uts/mnt/cgroup namespaces,mount,rootfs,pivot_root) needs privileged syscalls —unshare(CLONE_NEW*),mount,umount2,pivot_root,chroot,openat2. Under Docker's defaults these fail for two independent reasons: default containers dropCAP_SYS_ADMIN, and the default seccomp profile doesn't allowmount/umount2/pivot_root. The result today is a silent worker respawn loop with no guidance for the operator.What
source/howto/security.rst— new subsection "Running Isolation in a Container (Docker)" (anchorsecurity-isolation-docker), placed after the existing Docker AF_ALG seccomp section. Names the required syscalls, explains the two EPERM causes, and shows that both--cap-add SYS_ADMINand a permitting seccomp policy are needed — withseccomp=unconfined/ a custom profile /--privilegedas the three options, plus a concretedocker runexample. Notes that bare-metal Debian Trixie (unprivileged user namespaces enabled by default) needs no special flags.source/configuration/index.rst— a.. note::in Process isolation cross-referencing the howto.Deliberately does not claim a shipped
seccomp-isolation.jsonexists (none does yet) — it lists the syscalls so users can build a profile or useunconfined.Verification
Sphinx build (repo venv, 6.2.1): zero new warnings/errors vs
main(only pre-existing ones remain).🤖 Generated with Claude Code
https://claude.ai/code/session_017r3PHLb7YSsDTGmuJNpfPm