mirror of
https://github.com/openai/codex.git
synced 2026-05-02 04:11:39 +03:00
feat(devcontainer): add separate secure customer profile (#10431)
## Description Keeps the existing Codex contributor devcontainer in place and adds a separate secure profile for customer use. ## What changed - leaves `.devcontainer/devcontainer.json` and the contributor `Dockerfile` aligned with `main` - adds `.devcontainer/devcontainer.secure.json` and `.devcontainer/Dockerfile.secure` - adds secure-profile bootstrap scripts: - `post_install.py` - `post-start.sh` - `init-firewall.sh` - updates `.devcontainer/README.md` to explain when to use each path ## Secure profile behavior The new secure profile is opt-in and is meant for running Codex in a stricter project container: - preinstalls the Codex CLI plus common build tools - uses persistent volumes for Codex state, Cargo, Rustup, and GitHub auth - applies an allowlist-driven outbound firewall at startup - blocks IPv6 by default so the allowlist cannot be bypassed via AAAA routes - keeps the stricter networking isolated from the default contributor workflow ## Resulting behavior - `devcontainer.json` remains the low-friction Codex contributor setup - `devcontainer.secure.json` is the customer-facing secure option - the repo supports both workflows without forcing the secure profile on Codex contributors
This commit is contained in:
113
.devcontainer/post_install.py
Normal file
113
.devcontainer/post_install.py
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Post-install configuration for the Codex devcontainer."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def ensure_history_files() -> None:
|
||||
command_history_dir = Path("/commandhistory")
|
||||
command_history_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for filename in (".bash_history", ".zsh_history"):
|
||||
(command_history_dir / filename).touch(exist_ok=True)
|
||||
|
||||
|
||||
def fix_directory_ownership() -> None:
|
||||
uid = os.getuid()
|
||||
gid = os.getgid()
|
||||
|
||||
paths = [
|
||||
Path.home() / ".codex",
|
||||
Path.home() / ".config" / "gh",
|
||||
Path.home() / ".cargo",
|
||||
Path.home() / ".rustup",
|
||||
Path("/commandhistory"),
|
||||
]
|
||||
|
||||
for path in paths:
|
||||
if not path.exists():
|
||||
continue
|
||||
|
||||
stat_info = path.stat()
|
||||
if stat_info.st_uid == uid and stat_info.st_gid == gid:
|
||||
continue
|
||||
|
||||
try:
|
||||
subprocess.run(
|
||||
["sudo", "chown", "-R", f"{uid}:{gid}", str(path)],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
print(f"[post_install] fixed ownership: {path}", file=sys.stderr)
|
||||
except subprocess.CalledProcessError as err:
|
||||
print(
|
||||
f"[post_install] warning: could not fix ownership of {path}: {err.stderr.strip()}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
|
||||
def setup_git_config() -> None:
|
||||
home = Path.home()
|
||||
host_gitconfig = home / ".gitconfig"
|
||||
local_gitconfig = home / ".gitconfig.local"
|
||||
gitignore_global = home / ".gitignore_global"
|
||||
|
||||
gitignore_global.write_text(
|
||||
"""# Codex
|
||||
.codex/
|
||||
|
||||
# Rust
|
||||
/target/
|
||||
|
||||
# Node
|
||||
node_modules/
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Editors
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
include_line = (
|
||||
f"[include]\n path = {host_gitconfig}\n\n" if host_gitconfig.exists() else ""
|
||||
)
|
||||
|
||||
local_gitconfig.write_text(
|
||||
f"""# Container-local git configuration
|
||||
{include_line}[core]
|
||||
excludesfile = {gitignore_global}
|
||||
|
||||
[merge]
|
||||
conflictstyle = diff3
|
||||
|
||||
[diff]
|
||||
colorMoved = default
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print("[post_install] configuring devcontainer...", file=sys.stderr)
|
||||
ensure_history_files()
|
||||
fix_directory_ownership()
|
||||
setup_git_config()
|
||||
print("[post_install] complete", file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user