Outer hardening: AppArmor profile, pids limit, egress allowlist proxy
Inner codex sandbox stays danger-full-access by choice (bwrap path is a separate decision); this hardens everything around it: - DockerExecutor: --security-opt plumbing (repeatable, dedups no-new-privileges), --pids-limit (CLI default 512, fork-bomb guard), per-call extra_env (-e NAME=VALUE, non-secrets only, e.g. proxy URLs; the model key still goes by -e NAME only). - Worker: --egress-proxy-port (0 = off). When on, Docker task containers get HTTP(S)_PROXY pointing at the host filtering proxy via their network gateway IP (tenant network gateway or default bridge gateway). Gateway unresolvable => the attempt fails instead of running unproxied (fail closed, same rule as tenant network creation failure). - AppArmor profile deploy/apparmor/docker-codex: docker-default base + deny network raw/packet, deny ptrace, deny mount/ umount/pivot_root, deny dangerous capabilities, deny writes to /proc/sys, /sys, /proc/keys. Deliberately NO userns rule (that would enable the bwrap path, not this one). File rules mirror docker-default (broad + sensitive denies); a strict file allowlist would need profiling codex's file access set and is not claimed here. - Egress proxy deploy/egress/: Tinyproxy with FilterDefaultDeny + anchored domain allowlist (relay, github, pypi, npm). Anchoring matters: an unanchored 'github.com' regex would also match 'evilgithub.com'. - Seccomp honesty (README): Docker default seccomp already enforces on all task containers; no new stricter allowlist is claimed in this change (building one from memory risks silently breaking the toolchain; it needs syscall profiling first). Tests: 3 outer-hardening tests (security-opt dedup, pids limit, proxy env without leaking the key value, gateway parse/fail, proxy fail-closed). Full suites pass.
This commit is contained in:
1 parent
4f7c7eb13e
commit
1e4623c61c
8 files changed
+399
-18
No files matched your search
@@ -491,6 +491,22 @@ interrupted 且终态任务 cancel 返回 400、心跳后 sweep 不扫刚心跳
|
||||
密钥值),绝不复制 thread_history。注意:内层 codex 沙箱仍
|
||||
是 danger-full-access(主机内核禁 user namespace,bwrap 不可
|
||||
用),隔离边界是容器 + 挂载 + 网络三层,不是内层沙箱。
|
||||
- 外层加固(内层保持 danger-full-access 时的补偿层):
|
||||
`--docker-security-opt`(可重复,如 `apparmor=docker-codex`,
|
||||
见 `deploy/apparmor/docker-codex`:在 Docker 默认 profile
|
||||
基础上禁 raw 网络、ptrace、mount 与危险 capability;注意
|
||||
它不含 `userns`,即不启用 bwrap 内层沙箱路线);
|
||||
`--docker-pids-limit`(默认 512,防 fork 炸弹);
|
||||
`--egress-proxy-port`(0 = 不启用;生产配 8888):启用后
|
||||
Docker 任务容器的 HTTP(S) 出口全部走宿主上的 Tinyproxy
|
||||
(见 `deploy/egress/`:FilterDefaultDeny 白名单,只放行
|
||||
relay、github、pypi、npm 域名,其余 403;网关查不到时
|
||||
任务直接 failed,绝不无代理运行)。seccomp 现状诚实说明:
|
||||
Docker 默认 seccomp profile 已在所有任务容器上生效(这是
|
||||
不弱的基线),本轮没有新写一个更严的 seccomp allowlist——
|
||||
从记忆里拼一个 allowlist 极易漏掉 codex 工具链要的系统调用
|
||||
而静默破坏任务,正确的更严 profile 需要先对 codex 做系统
|
||||
调用画像,那是下一项工作,不是本轮假装做到的。
|
||||
- 网络白名单的诚实边界:docker run 默认 bridge 网络,本执行
|
||||
器不做 egress 白名单——真正的“只放行模型 API”需要宿主防火
|
||||
墙或代理规则,那是部署项,不是本轮代码假装做到的,不要宣称
|
||||
|
||||
Reference in new issue
Block a user