mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
## Summary - leave the default contributor devcontainer on its lightweight platform-only Docker runtime - install bubblewrap in setuid mode only in the secure devcontainer image for running Codex inside Docker - add Docker run args to the secure profile for bubblewrap's required capabilities - use explicit `seccomp=unconfined` and `apparmor=unconfined` in the secure profile instead of shipping a custom seccomp profile - document that the relaxed Docker security options are scoped to the secure profile ## Why Docker's default seccomp profile blocks bubblewrap with `pivot_root: Operation not permitted`, even when the container has `CAP_SYS_ADMIN`. Docker's default AppArmor profile also blocks bubblewrap with `Failed to make / slave: Permission denied`. A custom seccomp profile works, but it is hard for customers to audit and understand. Using Docker's standard `seccomp=unconfined` option is clearer: the secure profile intentionally relaxes Docker's outer sandbox just enough for Codex to construct its own bubblewrap/seccomp sandbox inside the container. The default contributor profile does not get these expanded runtime settings. ## Validation - `sed '/\\/\\*/,/\\*\\//d' .devcontainer/devcontainer.json | jq empty` - `jq empty .devcontainer/devcontainer.secure.json` - `git diff --check` - `docker build --platform=linux/arm64 -t codex-devcontainer-bwrap-test-arm64 ./.devcontainer` - `docker build --platform=linux/arm64 -f .devcontainer/Dockerfile.secure -t codex-devcontainer-secure-bwrap-test-arm64 .` - interactive `docker run -it` smoke tests: - verified non-root users `ubuntu` and `vscode` - verified secure image `/usr/bin/bwrap` is setuid - verified user/pid namespace, user/network namespace, and preserved-fd `--ro-bind-data` bwrap commands - reran secure-image smoke test with simplified `seccomp=unconfined` setup: - `bwrap-basic-ok` - `bwrap-netns-ok` - `codex-ok` - ran Codex inside the secure image: - `codex --version` -> `codex-cli 0.120.0` - `codex sandbox linux --full-auto -- /bin/sh -lc '...'` -> exited 0 and printed `codex-inner-ok` Note: direct `bwrap --proc /proc` is still denied by this Docker runtime, and Codex's existing proc-mount preflight fallback handles that by retrying without `--proc`. --------- Co-authored-by: Codex <noreply@openai.com>
75 lines
2.2 KiB
Docker
75 lines
2.2 KiB
Docker
FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
|
|
|
|
ARG TZ
|
|
ARG DEBIAN_FRONTEND=noninteractive
|
|
ARG NODE_MAJOR=22
|
|
ARG RUST_TOOLCHAIN=1.92.0
|
|
ARG CODEX_NPM_VERSION=latest
|
|
|
|
ENV TZ="$TZ"
|
|
|
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|
|
|
# Devcontainers run as a non-root user, so enable bubblewrap's setuid mode.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
curl \
|
|
git \
|
|
ca-certificates \
|
|
pkg-config \
|
|
clang \
|
|
musl-tools \
|
|
libssl-dev \
|
|
libsqlite3-dev \
|
|
just \
|
|
python3 \
|
|
python3-pip \
|
|
jq \
|
|
less \
|
|
man-db \
|
|
unzip \
|
|
ripgrep \
|
|
fzf \
|
|
fd-find \
|
|
zsh \
|
|
dnsutils \
|
|
iproute2 \
|
|
ipset \
|
|
iptables \
|
|
aggregate \
|
|
bubblewrap \
|
|
&& chmod u+s /usr/bin/bwrap \
|
|
&& apt-get clean \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash - \
|
|
&& apt-get update \
|
|
&& apt-get install -y --no-install-recommends nodejs \
|
|
&& npm install -g corepack@latest "@openai/codex@${CODEX_NPM_VERSION}" \
|
|
&& corepack enable \
|
|
&& corepack prepare pnpm@10.28.2 --activate \
|
|
&& apt-get clean \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY .devcontainer/init-firewall.sh /usr/local/bin/init-firewall.sh
|
|
COPY .devcontainer/post_install.py /opt/post_install.py
|
|
COPY .devcontainer/post-start.sh /opt/post_start.sh
|
|
|
|
RUN chmod 500 /usr/local/bin/init-firewall.sh \
|
|
&& chmod 755 /opt/post_start.sh \
|
|
&& chmod 644 /opt/post_install.py \
|
|
&& chown vscode:vscode /opt/post_install.py
|
|
|
|
RUN install -d -m 0775 -o vscode -g vscode /commandhistory /workspace \
|
|
&& touch /commandhistory/.bash_history /commandhistory/.zsh_history \
|
|
&& chown vscode:vscode /commandhistory/.bash_history /commandhistory/.zsh_history
|
|
|
|
USER vscode
|
|
ENV PATH="/home/vscode/.cargo/bin:${PATH}"
|
|
WORKDIR /workspace
|
|
|
|
RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain "${RUST_TOOLCHAIN}" \
|
|
&& rustup component add clippy rustfmt rust-src \
|
|
&& rustup target add x86_64-unknown-linux-musl aarch64-unknown-linux-musl
|