Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions scripts/codex_lab_package/supervisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
DEFAULT_LISTEN_HOST = APP_SERVER_LISTEN_HOST
DEFAULT_LISTEN_PORT = APP_SERVER_LISTEN_PORT
MANAGED_CLI_RELATIVE_PATH = Path("packages/standalone/current/codex")
ALLOW_JIT_ENTITLEMENT = "com.apple.security.cs.allow-jit"
ALLOW_JIT_ENTITLEMENT_PLUTIL_KEY_PATH = r"com\.apple\.security\.cs\.allow-jit"


@dataclass(frozen=True)
Expand Down Expand Up @@ -149,6 +151,14 @@ def inspect_engine(
team_identifier = _signature_field(signature_output, "TeamIdentifier")
if not signing_identifier or not team_identifier or team_identifier == "not set":
raise ValueError("managed Codex Lab engine lacks a stable signing identity")
code_signing_entitlements = _code_signing_entitlements(
managed_cli,
codesign_path=codesign_path,
)
if ALLOW_JIT_ENTITLEMENT not in code_signing_entitlements:
raise ValueError(
"managed Codex Lab engine lacks the required V8 JIT entitlement"
)
return EngineIdentity(
build_channel=provenance["build_channel"],
build_profile=provenance["build_profile"],
Expand Down Expand Up @@ -182,6 +192,7 @@ def build_supervisor_runner(
EXPECTED_VERSION={quote(identity.version)}
EXPECTED_SIGNING_IDENTIFIER={quote(identity.signing_identifier)}
EXPECTED_TEAM_IDENTIFIER={quote(identity.team_identifier)}
ALLOW_JIT_ENTITLEMENT_KEY_PATH={quote(ALLOW_JIT_ENTITLEMENT_PLUTIL_KEY_PATH)}
CODESIGN={quote(tools.codesign)}
PLUTIL={quote(tools.plutil)}
SHASUM={quote(tools.shasum)}
Expand All @@ -190,15 +201,21 @@ def build_supervisor_runner(
UPDATER_PID_FILE="$LAB_HOME/app-server-daemon/app-server-updater.pid"
DAEMON_PID_FILE="$LAB_HOME/app-server-daemon/app-server.pid"
PROVENANCE_FILE=
ENTITLEMENTS_FILE=
LAST_STATE=

cleanup() {{
[ -z "$PROVENANCE_FILE" ] || /bin/rm -f "$PROVENANCE_FILE"
[ -z "$ENTITLEMENTS_FILE" ] || /bin/rm -f "$ENTITLEMENTS_FILE"
}}
discard_provenance() {{
cleanup
PROVENANCE_FILE=
}}
discard_entitlements() {{
[ -z "$ENTITLEMENTS_FILE" ] || /bin/rm -f "$ENTITLEMENTS_FILE"
ENTITLEMENTS_FILE=
}}
log_state() {{
[ "$1" = "$LAST_STATE" ] && return
printf '%s %s\n' "$(/bin/date -u '+%Y-%m-%dT%H:%M:%SZ')" "$1" >&2
Expand Down Expand Up @@ -239,6 +256,14 @@ def build_supervisor_runner(
team_identifier=$(printf '%s\n' "$signature" | /usr/bin/awk -F= '$1 == "TeamIdentifier" {{ print substr($0, index($0, "=") + 1); exit }}')
[ "$signing_identifier" = "$EXPECTED_SIGNING_IDENTIFIER" ] || return 1
[ "$team_identifier" = "$EXPECTED_TEAM_IDENTIFIER" ] || return 1
ENTITLEMENTS_FILE=$(/usr/bin/mktemp "${{TMPDIR:-/tmp}}/codex-lab-entitlements.XXXXXX")
if ! "$CODESIGN" -d --entitlements :- "$MANAGED_CLI" >"$ENTITLEMENTS_FILE" 2>/dev/null; then
discard_entitlements
return 1
fi
allow_jit=$("$PLUTIL" -extract "$ALLOW_JIT_ENTITLEMENT_KEY_PATH" raw -o - "$ENTITLEMENTS_FILE" 2>/dev/null || true)
discard_entitlements
[ "$allow_jit" = true ] || return 1
PROVENANCE_FILE=$(/usr/bin/mktemp "${{TMPDIR:-/tmp}}/codex-lab-supervisor.XXXXXX")
if ! "$MANAGED_CLI" debug provenance --json >"$PROVENANCE_FILE"; then
discard_provenance
Expand Down Expand Up @@ -453,6 +478,28 @@ def _signature_field(output: str, name: str) -> str:
)


def _code_signing_entitlements(
path: Path,
*,
codesign_path: Path,
) -> tuple[str, ...]:
completed = subprocess.run(
[str(codesign_path), "-d", "--entitlements", ":-", str(path)],
check=True,
capture_output=True,
text=True,
)
if not completed.stdout.strip():
return ()
try:
entitlements = plistlib.loads(completed.stdout.encode())
except plistlib.InvalidFileException as exc:
raise ValueError("managed Codex Lab engine has invalid entitlements") from exc
if not isinstance(entitlements, dict):
raise ValueError("managed Codex Lab engine has invalid entitlements")
return tuple(sorted(key for key, value in entitlements.items() if value is True))


def _require_expected_identity(
identity: EngineIdentity,
*,
Expand Down
114 changes: 92 additions & 22 deletions scripts/codex_lab_package/test_supervisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,58 @@

from codex_lab_package.supervisor import EngineIdentity
from codex_lab_package.supervisor import SupervisorPaths
from codex_lab_package.supervisor import SupervisorTools
from codex_lab_package.supervisor import build_launch_agent_plist
from codex_lab_package.supervisor import build_supervisor_runner
from codex_lab_package.supervisor import inspect_engine
from codex_lab_package.supervisor import install_supervisor


class SupervisorTest(unittest.TestCase):
def _write_engine(self, path: Path, *, source_commit: str = "c" * 40) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
"""#!/bin/sh
if [ "${1:-}" = debug ] && [ "${2:-}" = provenance ]; then
printf '{"schema_version":1,"version":"1.2.3","source_commit":"%s","dirty_state":"clean","build_profile":"release","build_channel":"release","executable_path":"%s"}\\n' "__COMMIT__" "$0"
exit 0
fi
exit 2
""".replace("__COMMIT__", source_commit),
encoding="utf-8",
)
os.chmod(path, 0o755)

def _write_codesign(
self,
path: Path,
*,
entitlement_value: str | None,
) -> None:
entitlement_output = ""
if entitlement_value is not None:
entitlement_output = f"""cat <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict><key>com.apple.security.cs.allow-jit</key><{entitlement_value}/></dict></plist>
EOF
"""
path.write_text(
"""#!/bin/sh
if [ "${1:-}" = --verify ]; then
exit 0
fi
if [ "${2:-}" = --entitlements ]; then
__ENTITLEMENT_OUTPUT__
exit 0
fi
echo 'Identifier=dev.example.codex-lab' >&2
echo 'TeamIdentifier=TEAM123456' >&2
""".replace("__ENTITLEMENT_OUTPUT__", entitlement_output),
encoding="utf-8",
)
os.chmod(path, 0o755)

def _identity(self) -> EngineIdentity:
return EngineIdentity(
build_channel="release",
Expand All @@ -45,6 +90,7 @@ def test_runner_and_plist_pin_direct_websocket_engine(self) -> None:
subprocess.run(["/bin/sh", "-n", str(runner_path)], check=True)
self.assertIn("EXPECTED_SHA256=" + "a" * 64, runner)
self.assertIn("EXPECTED_SOURCE_COMMIT=" + "b" * 40, runner)
self.assertIn("com\\.apple\\.security\\.cs\\.allow-jit", runner)
self.assertIn("LISTEN_URL=ws://127.0.0.1:4766", runner)
self.assertIn("app-server --remote-control --listen", runner)
self.assertEqual(runner.count("in ''|*[!0-9]*) return 0"), 2)
Expand All @@ -61,36 +107,60 @@ def test_inspect_engine_records_signature_and_digest(self) -> None:
root = Path(temp_dir)
engine = root / "codex"
source_commit = "c" * 40
engine.write_text(
"""#!/bin/sh
if [ "${1:-}" = debug ] && [ "${2:-}" = provenance ]; then
printf '{"schema_version":1,"version":"1.2.3","source_commit":"%s","dirty_state":"clean","build_profile":"release","build_channel":"release","executable_path":"%s"}\\n' "__COMMIT__" "$0"
exit 0
fi
exit 2
""".replace("__COMMIT__", source_commit),
encoding="utf-8",
)
os.chmod(engine, 0o755)
self._write_engine(engine, source_commit=source_commit)
codesign = root / "codesign"
codesign.write_text(
"""#!/bin/sh
if [ "${1:-}" = --verify ]; then
exit 0
fi
echo 'Identifier=dev.example.codex-lab' >&2
echo 'TeamIdentifier=TEAM123456' >&2
""",
encoding="utf-8",
)
os.chmod(codesign, 0o755)
self._write_codesign(codesign, entitlement_value="true")

identity = inspect_engine(engine, codesign_path=codesign)
self.assertEqual(identity.source_commit, source_commit)
self.assertEqual(
identity.sha256, hashlib.sha256(engine.read_bytes()).hexdigest()
)

def test_inspect_engine_rejects_missing_v8_jit_entitlement(self) -> None:
for entitlement_value in (None, "false"):
with self.subTest(entitlement_value=entitlement_value):
with tempfile.TemporaryDirectory() as temp_dir:
root = Path(temp_dir)
engine = root / "codex"
self._write_engine(engine)
codesign = root / "codesign"
self._write_codesign(
codesign,
entitlement_value=entitlement_value,
)

with self.assertRaisesRegex(ValueError, "V8 JIT entitlement"):
inspect_engine(engine, codesign_path=codesign)

@unittest.skipUnless(sys.platform == "darwin", "macOS supervisor runner")
def test_runner_check_requires_v8_jit_entitlement(self) -> None:
with tempfile.TemporaryDirectory() as temp_dir:
root = Path(temp_dir)
paths = SupervisorPaths(
lab_home=root / "lab",
launch_agents_dir=root / "LaunchAgents",
)
self._write_engine(paths.managed_cli)
codesign = root / "codesign"
self._write_codesign(codesign, entitlement_value="true")
identity = inspect_engine(paths.managed_cli, codesign_path=codesign)
runner = build_supervisor_runner(
paths,
identity,
tools=SupervisorTools(codesign=codesign),
)
paths.runner.parent.mkdir(parents=True, exist_ok=True)
paths.runner.write_text(runner, encoding="utf-8")
os.chmod(paths.runner, 0o755)

self.assertEqual(subprocess.run([paths.runner, "check"]).returncode, 0)
self._write_codesign(codesign, entitlement_value="false")
self.assertNotEqual(
subprocess.run([paths.runner, "check"]).returncode,
0,
)

def test_install_writes_files_and_bootstraps_expected_service(self) -> None:
with tempfile.TemporaryDirectory() as temp_dir:
root = Path(temp_dir)
Expand Down
Loading