Add opt-in provisioned macOS CLI release candidates (#44307)

## What changed

- Add a tag-release workflow gated by `CODEX_PROVISIONED_MACOS_CANDIDATE` for Apple Silicon and Intel macOS candidate artifacts.
- Package the CLI in `CodexCLI.app` with an embedded provisioning profile and a relocatable `bin/codex` launcher. Validate independently supplied profile, certificate, and team expectations before signing.
- Sign and notarize candidates, then verify signatures, entitlements, architecture, stapling, and Gatekeeper acceptance on macOS. Retain verified artifacts after package smoke tests pass.
- Filter code-mode smoke-test requests to `/v1/responses` so analytics requests are excluded from response parsing.

## Testing

Add tests for profile validation, launcher relocation and symlink handling, standard and provisioned signing flows, and rejection of signing, notarization, identity, and entitlement failures. The candidate workflow runs package smoke tests, including sandboxed code mode.

GitOrigin-RevId: f214f6a23dd10df62cd72a2c63c20cb0864fbc9c
This commit is contained in:
Eric Burke
2026-09-09 21:18:11 +00:00
committed by copyberry
parent 7c88f037d9
commit 45eec73b11
8 changed files with 1143 additions and 2 deletions

View File

@@ -0,0 +1,229 @@
"""Prepare and verify provisioned CLI bundles using an explicitly approved profile."""
import argparse
import hashlib
import json
import os
import plistlib
import re
import shutil
import subprocess
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
BUNDLE_ID = "com.openai.codex.cli"
APP = Path("CodexCLI.app")
EXECUTABLE = APP / "Contents/MacOS/codex"
SIGNING = Path(__file__).resolve().parent
HELPERS = ("bin/codex-code-mode-host", "codex-path/rg", "codex-resources/zsh/bin/zsh")
LAUNCHER = """#!/bin/sh
set -eu
entry="$0"
while [ -L "$entry" ]; do
parent=$(CDPATH= cd -P -- "$(dirname -- "$entry")" && pwd)
entry=$(readlink "$entry")
case "$entry" in /*) ;; *) entry="$parent/$entry" ;; esac
done
bin_dir=$(CDPATH= cd -P -- "$(dirname -- "$entry")" && pwd)
exec "$bin_dir/../CodexCLI.app/Contents/MacOS/codex" "$@"
"""
@dataclass(frozen=True)
class ProfileConfiguration:
"""Independent release expectations; never infer these from the signed package."""
profile: Path
profile_sha256: str
certificate_sha256: str
team_id: str
def __post_init__(self):
for name in ("profile_sha256", "certificate_sha256"):
if not re.fullmatch(r"[0-9a-f]{64}", getattr(self, name)):
raise ValueError(f"{name} must be a lowercase SHA-256 digest")
if not re.fullmatch(r"[A-Z0-9]{10}", self.team_id):
raise ValueError("team_id must be a ten-character Apple Team ID")
def validate_signing_certificate(self, certificate: Path):
certificate_der = subprocess.check_output(
["openssl", "x509", "-in", str(certificate), "-outform", "DER"]
)
if hashlib.sha256(certificate_der).hexdigest() != self.certificate_sha256:
raise ValueError("AKV signing certificate is not authorized by the profile")
def load_profile(configuration: ProfileConfiguration):
# Pin the portal-approved CMS as well as checking its signature. -noverify
# skips OpenSSL's non-Apple trust store, not CMS signature verification.
if (
hashlib.sha256(configuration.profile.read_bytes()).hexdigest()
!= configuration.profile_sha256
):
raise ValueError("Provisioning profile changed; review and update its pin")
profile = plistlib.loads(
subprocess.check_output(
[
"openssl",
"cms",
"-verify",
"-inform",
"DER",
"-noverify",
"-in",
str(configuration.profile),
]
)
)
validate_profile(profile, configuration)
return profile
def validate_profile(profile, configuration: ProfileConfiguration):
allowed = profile["Entitlements"]
if (
profile["TeamIdentifier"] != [configuration.team_id]
or profile["ApplicationIdentifierPrefix"] != [configuration.team_id]
or allowed["com.apple.application-identifier"]
!= f"{configuration.team_id}.{BUNDLE_ID}"
or allowed["com.apple.developer.team-identifier"] != configuration.team_id
or allowed["keychain-access-groups"] != [f"{configuration.team_id}.*"]
or allowed.get("get-task-allow", False)
or not profile.get("ProvisionsAllDevices")
or "ProvisionedDevices" in profile
):
raise ValueError("Profile does not authorize the CLI Developer ID identity")
now = datetime.now(timezone.utc).replace(tzinfo=None)
if not profile["CreationDate"] <= now < profile["ExpirationDate"]:
raise ValueError("Provisioning profile is not currently valid")
if [
hashlib.sha256(cert).hexdigest() for cert in profile["DeveloperCertificates"]
] != [configuration.certificate_sha256]:
raise ValueError("Profile does not authorize the approved signing certificate")
def entitlements(configuration: ProfileConfiguration):
base = plistlib.loads((SIGNING / "codex.entitlements.plist").read_bytes())
return {
**base,
"com.apple.application-identifier": f"{configuration.team_id}.{BUNDLE_ID}",
"com.apple.developer.team-identifier": configuration.team_id,
"keychain-access-groups": [f"{configuration.team_id}.{BUNDLE_ID}"],
}
def prepare(package, reports, configuration: ProfileConfiguration):
load_profile(configuration)
metadata = json.loads((package / "codex-package.json").read_text())
if (
metadata["variant"] != "codex"
or metadata["layoutVersion"] != 1
or metadata["target"] not in ("aarch64-apple-darwin", "x86_64-apple-darwin")
or metadata["entrypoint"] != "bin/codex"
):
raise ValueError("Expected a canonical macOS CLI package")
for relative in ("bin/codex", *HELPERS):
path = package / relative
if path.is_symlink() or not path.is_file() or not os.access(path, os.X_OK):
raise ValueError(f"Expected a regular executable: {relative}")
# Refuse to overwrite a previously prepared or signed bundle.
(package / EXECUTABLE).parent.mkdir(parents=True, exist_ok=False)
(package / "bin/codex").rename(package / EXECUTABLE)
(package / "bin/codex").write_text(LAUNCHER)
(package / "bin/codex").chmod(0o755)
contents = package / APP / "Contents"
shutil.copyfile(configuration.profile, contents / "embedded.provisionprofile")
(contents / "Info.plist").write_bytes(
plistlib.dumps(
{
"CFBundleIdentifier": BUNDLE_ID,
"CFBundleExecutable": "codex",
"CFBundleName": "Codex CLI",
"CFBundlePackageType": "APPL",
"CFBundleVersion": "1",
}
)
)
reports.mkdir(parents=True, exist_ok=True)
# Keep expected entitlements separate from the shared verifier's extracted
# codex-entitlements.plist, otherwise it would overwrite its own expectation.
(reports / "codex-provisioned-entitlements.plist").write_bytes(
plistlib.dumps(entitlements(configuration))
)
def verify(package, reports, expected_target, configuration: ProfileConfiguration):
"""Check profile and certificate pins; the signing driver verifies code."""
load_profile(configuration)
if (
package / APP / "Contents/embedded.provisionprofile"
).read_bytes() != configuration.profile.read_bytes():
raise ValueError("Embedded profile differs from the reviewed profile")
if (package / "bin/codex").read_text() != LAUNCHER:
raise ValueError("Unexpected CLI launcher")
metadata = json.loads((package / "codex-package.json").read_text())
if metadata["target"] != expected_target:
raise ValueError(
"Package target differs from the requested verification target"
)
reports.mkdir(parents=True, exist_ok=True)
(reports / "codex-provisioned-entitlements.plist").write_bytes(
plistlib.dumps(entitlements(configuration))
)
# sign_macos_cli_package.py owns shared architecture, signature and entitlement
# checks. Here, require the exact certificate authorized by the profile.
for relative in (EXECUTABLE, *(Path(helper) for helper in HELPERS)):
binary = package / relative
target = package / APP if relative == EXECUTABLE else binary
prefix = reports / f"{binary.name}-cert-"
subprocess.run(
["codesign", "-d", f"--extract-certificates={prefix}", str(target)],
check=True,
)
if (
hashlib.sha256(Path(f"{prefix}0").read_bytes()).hexdigest()
!= configuration.certificate_sha256
):
raise ValueError(f"Unexpected signing certificate: {relative}")
def parse_profile_args(parser, configuration: ProfileConfiguration | None):
"""Require independent profile expectations unless the caller supplies them."""
if configuration is None:
parser.add_argument("--profile", type=Path, required=True)
parser.add_argument("--profile-sha256", required=True)
parser.add_argument("--certificate-sha256", required=True)
parser.add_argument("--team-id", required=True)
args = parser.parse_args()
if configuration is None:
configuration = ProfileConfiguration(
args.profile, args.profile_sha256, args.certificate_sha256, args.team_id
)
return args, configuration
def main(configuration: ProfileConfiguration | None = None):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("operation", choices=("prepare", "verify", "validate-profile"))
parser.add_argument("--package", type=Path, default=Path("package"))
parser.add_argument("--reports", type=Path, default=Path("provisioned-reports"))
parser.add_argument("--certificate", type=Path)
parser.add_argument(
"--target", choices=("aarch64-apple-darwin", "x86_64-apple-darwin")
)
args, configuration = parse_profile_args(parser, configuration)
if args.certificate:
configuration.validate_signing_certificate(args.certificate)
if args.operation == "validate-profile":
load_profile(configuration)
elif args.operation == "prepare":
prepare(args.package, args.reports, configuration)
else:
if not args.target:
parser.error("--target is required for verification")
verify(args.package, args.reports, args.target, configuration)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,177 @@
"""Sign and verify macOS CLI packages using the shared AKV and native tools."""
import argparse
import os
import subprocess
import sys
from pathlib import Path
import provisioned_macos_cli_package as bundle
def main(configuration: bundle.ProfileConfiguration | None = None):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("operation", choices=("sign", "verify"))
parser.add_argument("package", type=Path)
args, configuration = bundle.parse_profile_args(parser, configuration)
package = args.package.resolve(strict=True)
if not package.is_dir():
parser.error("package must be an extracted CLI package directory")
repo_root = os.environ.get("CODEX_REPO_ROOT")
if not repo_root:
parser.error("CODEX_REPO_ROOT must be set")
reports = Path(repo_root) / "signing-verification"
reports.mkdir(parents=True, exist_ok=True)
provisioned = os.environ.get("PROVISIONED_MACOS", "false") == "true"
if provisioned:
if args.operation == "sign":
configuration.validate_signing_certificate(
Path(os.environ["OAI_AKV_SIGNING_CERTIFICATE_PEM"])
)
bundle.prepare(package, reports, configuration)
else:
bundle.verify(package, reports, os.environ["TARGET"], configuration)
for relative in ("bin/codex", *bundle.HELPERS):
binary = package / relative
name = binary.name
target = binary
identifier = name
entitlements = bundle.SIGNING / f"{name}.entitlements.plist"
if provisioned and relative == "bin/codex":
binary = package / bundle.EXECUTABLE
target = package / bundle.APP
identifier = bundle.BUNDLE_ID
entitlements = reports / "codex-provisioned-entitlements.plist"
if args.operation == "sign":
command = [
"bash",
str(bundle.SIGNING / "sign_macos_code.sh"),
"--target",
str(target),
"--identity",
"unused",
"--deep",
"false",
"--options",
"runtime",
"--timestamp",
"true",
]
if relative.startswith("bin/"):
command.extend(
["--identifier", identifier, "--entitlements", str(entitlements)]
)
else:
command.extend(["--identifier", f"com.openai.codex.{name}"])
subprocess.run(command, check=True)
with (reports / f"{name}-signature.yaml").open("wb") as output:
subprocess.run(
["rcodesign", "print-signature-info", str(binary)],
stdout=output,
check=True,
)
if not provisioned:
subprocess.run(
[
"bash",
str(bundle.SIGNING / "notarize_macos_binary_with_akv.sh"),
"--binary",
str(binary),
"--report-dir",
str(reports / name),
],
check=True,
)
else:
target_triple = os.environ["TARGET"]
architectures = {
"aarch64-apple-darwin": "arm64",
"x86_64-apple-darwin": "x86_64",
}
if target_triple not in architectures:
raise ValueError(f"Unexpected macOS target: {target_triple}")
subprocess.run(
["lipo", str(binary), "-verify_arch", architectures[target_triple]],
check=True,
)
subprocess.run(
[
"codesign",
"--verify",
"--strict",
"--verbose=2",
"--test-requirement",
# Require Apple's Developer ID Application certificate chain.
(
"=anchor apple generic"
" and certificate 1[field.1.2.840.113635.100.6.2.6] exists"
" and certificate leaf[field.1.2.840.113635.100.6.1.13] exists"
),
str(target),
],
check=True,
)
signature = reports / f"{name}-signature.txt"
with signature.open("wb") as output:
subprocess.run(
["codesign", "-d", "--verbose=4", str(target)],
stderr=output,
check=True,
)
actual = reports / f"{name}-entitlements.plist"
with actual.open("wb") as output:
subprocess.run(
["codesign", "-d", "--entitlements", ":-", str(target)],
stdout=output,
check=True,
)
if relative.startswith("bin/"):
expected = reports / f"{name}-expected.plist"
subprocess.run(
[
"plutil",
"-convert",
"xml1",
"-o",
str(expected),
str(entitlements),
],
check=True,
)
subprocess.run(["plutil", "-convert", "xml1", str(actual)], check=True)
subprocess.run(["diff", "-u", str(expected), str(actual)], check=True)
elif actual.stat().st_size:
raise ValueError(
f"Bundled helper {name} must not have signing entitlements"
)
if provisioned and args.operation == "sign":
archive = Path(os.environ["RUNNER_TEMP"]) / "provisioned-cli.zip"
subprocess.run(["zip", "-q", "-r", str(archive), "."], cwd=package, check=True)
command = [
sys.executable,
str(bundle.SIGNING / "notarize_with_akv.py"),
"--file",
str(archive),
"--report-log",
str(reports / "notarization-developer-log.json"),
"--max-wait-seconds",
"1200",
]
with (
(reports / "notarization.log").open("w") as output,
subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True
) as process,
):
assert process.stdout is not None
for line in process.stdout:
print(line, end="", flush=True)
output.write(line)
if returncode := process.wait():
raise subprocess.CalledProcessError(returncode, command)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,217 @@
"""Exercise profile validation, relocation and signing without release credentials."""
import copy
import hashlib
import json
import plistlib
import shutil
import ssl
import subprocess
import tarfile
import tempfile
import unittest
from dataclasses import replace
from datetime import datetime, timedelta, timezone
from pathlib import Path
import provisioned_macos_cli_package as bundle
class ProvisioningTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
directory = tempfile.TemporaryDirectory()
cls.addClassCleanup(directory.cleanup)
root = Path(directory.name)
key = root / "test-key.pem"
certificate = root / "test-certificate.pem"
subprocess.run(
[
"openssl",
"req",
"-x509",
"-newkey",
"rsa:2048",
"-nodes",
"-keyout",
str(key),
"-out",
str(certificate),
"-days",
"1",
"-subj",
"/CN=CLI provisioning test/OU=TESTTEAM01",
],
check=True,
capture_output=True,
)
cert_der = ssl.PEM_cert_to_DER_cert(certificate.read_text())
now = datetime.now(timezone.utc).replace(tzinfo=None, microsecond=0)
cls.profile = {
"TeamIdentifier": ["TESTTEAM01"],
"ApplicationIdentifierPrefix": ["TESTTEAM01"],
"Entitlements": {
"com.apple.application-identifier": "TESTTEAM01.com.openai.codex.cli",
"com.apple.developer.team-identifier": "TESTTEAM01",
"keychain-access-groups": ["TESTTEAM01.*"],
},
"CreationDate": now - timedelta(days=1),
"ExpirationDate": now + timedelta(days=1),
"ProvisionsAllDevices": True,
"DeveloperCertificates": [cert_der],
}
payload = root / "profile.plist"
payload.write_bytes(plistlib.dumps(cls.profile))
profile_path = root / "test.provisionprofile"
subprocess.run(
[
"openssl",
"cms",
"-sign",
"-binary",
"-nodetach",
"-outform",
"DER",
"-in",
str(payload),
"-signer",
str(certificate),
"-inkey",
str(key),
"-out",
str(profile_path),
],
check=True,
capture_output=True,
)
cls.configuration = bundle.ProfileConfiguration(
profile=profile_path,
profile_sha256=hashlib.sha256(profile_path.read_bytes()).hexdigest(),
certificate_sha256=hashlib.sha256(cert_der).hexdigest(),
team_id="TESTTEAM01",
)
class ProvisionedCliTests(ProvisioningTestCase):
def test_profile_configuration_fails_closed(self):
self.assertEqual(bundle.load_profile(self.configuration), self.profile)
for changes in (
{"profile_sha256": "0" * 64},
{"certificate_sha256": "0" * 64},
{"team_id": "OTHERTEAM1"},
{"profile_sha256": ""},
{"certificate_sha256": ""},
{"team_id": ""},
):
with self.subTest(changes=changes), self.assertRaises(ValueError):
bundle.load_profile(replace(self.configuration, **changes))
def test_rejects_profile_with_wrong_identity_certificate_or_validity(self):
for field, value in (
("TeamIdentifier", ["OTHERTEAM"]),
("DeveloperCertificates", [b"another certificate"]),
(
"ExpirationDate",
datetime(2000, 1, 1, tzinfo=timezone.utc).replace(tzinfo=None),
),
(
"CreationDate",
datetime(2099, 1, 1, tzinfo=timezone.utc).replace(tzinfo=None),
),
("ProvisionsAllDevices", False),
("ProvisionedDevices", ["device"]),
):
with self.subTest(field=field):
profile = copy.deepcopy(self.profile)
profile[field] = value
with self.assertRaises(ValueError):
bundle.validate_profile(profile, self.configuration)
for field, value in (
(
"com.apple.application-identifier",
f"{self.configuration.team_id}.another.app",
),
("keychain-access-groups", [f"{self.configuration.team_id}.another.app"]),
("get-task-allow", True),
):
with self.subTest(field=field):
profile = copy.deepcopy(self.profile)
profile["Entitlements"][field] = value
with self.assertRaises(ValueError):
bundle.validate_profile(profile, self.configuration)
def test_archive_relocation_copy_and_symlink_preserve_launcher(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
package = root / "original package"
metadata = {
"variant": "codex",
"layoutVersion": 1,
"target": "aarch64-apple-darwin",
"entrypoint": "bin/codex",
}
for relative in ("bin/codex", *bundle.HELPERS):
path = package / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text('#!/bin/sh\nprintf "%s\\n" "$@"\nexit 23\n')
path.chmod(0o755)
(package / "codex-package.json").write_text(json.dumps(metadata))
original_binary = (package / "bin/codex").read_bytes()
bundle.prepare(package, root / "reports", self.configuration)
with self.assertRaises(FileExistsError):
bundle.prepare(package, root / "reports", self.configuration)
with self.assertRaisesRegex(ValueError, "Package target differs"):
bundle.verify(
package, root / "reports", "x86_64-apple-darwin", self.configuration
)
self.assertEqual(
(package / bundle.EXECUTABLE).read_bytes(), original_binary
)
self.assertEqual(
json.loads((package / "codex-package.json").read_text()), metadata
)
archive_path = root / "package.tar.gz"
with tarfile.open(archive_path, "w:gz") as archive:
archive.add(package, arcname=".")
relocated = root / "relocated package"
with tarfile.open(archive_path) as archive:
archive.extractall(relocated, filter="data")
shutil.rmtree(package)
# npm currently dereferences symlinks when copying packages. The
# launcher remains a script and the provisioned executable stays put.
copied = root / "copied package"
shutil.copytree(relocated, copied)
link = root / "installed codex"
link.symlink_to(Path("copied package/bin/codex"))
absolute_link = root / "absolute codex"
absolute_link.symlink_to(link)
for entry in (
relocated / "bin/codex",
copied / "bin/codex",
link,
absolute_link,
):
with self.subTest(entry=entry):
result = subprocess.run(
[str(entry), "space argument", "*", "--flag"],
cwd="/",
capture_output=True,
text=True,
check=False,
)
self.assertEqual(
(result.returncode, result.stdout, result.stderr),
(23, "space argument\n*\n--flag\n", ""),
)
(copied / bundle.APP / "Contents/embedded.provisionprofile").write_bytes(
b"tampered"
)
with self.assertRaisesRegex(ValueError, "Embedded profile differs"):
bundle.verify(
copied, root / "reports", "aarch64-apple-darwin", self.configuration
)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,293 @@
"""Exercise package signing and native verification with generated credentials."""
import itertools
import json
import os
import shutil
import ssl
import subprocess
import sys
import tempfile
import unittest
import zipfile
from pathlib import Path
import provisioned_macos_cli_package as bundle
from test_provisioned_macos_cli_package import ProvisioningTestCase
NATIVE_TOOL = """#!/usr/bin/env python3
import json, os, plistlib, sys
from pathlib import Path
name = Path(sys.argv[0]).name
args = sys.argv[1:]
with open(os.environ["CALL_LOG"], "a") as log:
log.write(json.dumps([name, *args]) + "\\n")
if name == "codesign":
for arg in args:
if arg.startswith("--extract-certificates="):
Path(arg.split("=", 1)[1] + "0").write_bytes(Path(os.environ["MOCK_CERTIFICATE"]).read_bytes())
if "--test-requirement" in args and os.environ.get("MOCK_WRONG_SIGNING_IDENTITY"):
print("code failed to satisfy specified code requirement(s)", file=sys.stderr)
sys.exit(1)
if "--entitlements" in args:
target = Path(args[-1]).name
if target == "CodexCLI.app":
source = Path(os.environ["CODEX_REPO_ROOT"]) / "signing-verification/codex-provisioned-entitlements.plist"
elif target in ("codex", "codex-code-mode-host"):
source = Path(os.environ["MOCK_SIGNING_SCRIPTS"]) / (target + ".entitlements.plist")
else:
sys.exit(0)
if os.environ.get("MOCK_WRONG_ENTITLEMENTS"):
sys.stdout.buffer.write(plistlib.dumps({"unexpected": True}))
else:
sys.stdout.buffer.write(source.read_bytes())
elif name == "plutil":
source = Path(args[-1])
target = Path(args[args.index("-o") + 1]) if "-o" in args else source
target.write_bytes(plistlib.dumps(plistlib.loads(source.read_bytes())))
"""
class MacosSigningTests(ProvisioningTestCase):
def fixture(self, root, provisioned, target="aarch64-apple-darwin"):
source = Path(bundle.__file__).parent
common = Path(os.path.commonpath((source, bundle.SIGNING)))
helpers = root / source.relative_to(common)
scripts = root / bundle.SIGNING.relative_to(common)
helpers.mkdir(parents=True, exist_ok=True)
scripts.mkdir(parents=True, exist_ok=True)
for name in ("provisioned_macos_cli_package.py", "sign_macos_cli_package.py"):
shutil.copyfile(source / name, helpers / name)
for path in bundle.SIGNING.glob("*.entitlements.plist"):
shutil.copyfile(path, scripts / path.name)
(root / "record.py").write_text(
"import json, os, sys\n"
"with open(os.environ['CALL_LOG'], 'a') as log:\n"
" log.write(json.dumps(sys.argv[1:]) + '\\n')\n"
"if os.environ.get('FAIL_TOOL') == sys.argv[1]:\n"
" print('fixture stdout', flush=True)\n"
" print('fixture stderr', file=sys.stderr, flush=True)\n"
" sys.exit(17)\n"
)
for name in ("sign_macos_code.sh", "notarize_macos_binary_with_akv.sh"):
(scripts / name).write_text(
'python3 "$CODEX_REPO_ROOT/record.py" "$(basename "$0")" "$@"\n'
)
(scripts / "notarize_with_akv.py").write_text(
"import os, runpy, sys\n"
"sys.argv.insert(1, 'notarize_with_akv.py')\n"
"runpy.run_path(os.environ['CODEX_REPO_ROOT'] + '/record.py')\n"
)
for name in ("rcodesign", "codesign", "lipo", "plutil"):
path = root / name
path.write_text(NATIVE_TOOL)
path.chmod(0o755)
certificate_der = self.profile["DeveloperCertificates"][0]
certificate = root / "certificate.pem"
certificate.write_text(ssl.DER_cert_to_PEM_cert(certificate_der))
(root / "certificate.der").write_bytes(certificate_der)
package = root / "package with spaces"
for relative in ("bin/codex", *bundle.HELPERS):
path = package / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("#!/bin/sh\nexit 0\n")
path.chmod(0o755)
(package / "codex-package.json").write_text(
json.dumps(
{
"variant": "codex",
"layoutVersion": 1,
"target": target,
"entrypoint": "bin/codex",
}
)
)
env = {
key: value
for key, value in os.environ.items()
if key not in ("GITHUB_WORKSPACE", "CODEX_PROVISIONING_HELPER")
}
env.update(
CODEX_REPO_ROOT=str(root),
RUNNER_TEMP=str(root),
TARGET=target,
PATH=f"{root}{os.pathsep}{os.environ['PATH']}",
CALL_LOG=str(root / "calls.jsonl"),
PROVISIONED_MACOS=str(provisioned).lower(),
OAI_AKV_SIGNING_CERTIFICATE_PEM=str(certificate),
MOCK_CERTIFICATE=str(root / "certificate.der"),
MOCK_SIGNING_SCRIPTS=str(scripts),
)
return package, helpers / "sign_macos_cli_package.py", env
def run_driver(self, driver, operation, package, env):
return subprocess.run(
[
sys.executable,
str(driver),
operation,
str(package),
"--profile",
str(self.configuration.profile),
"--profile-sha256",
self.configuration.profile_sha256,
"--certificate-sha256",
self.configuration.certificate_sha256,
"--team-id",
self.configuration.team_id,
],
env=env,
capture_output=True,
text=True,
timeout=30,
check=False,
)
def test_standard_and_provisioned_signing_and_verification(self):
for provisioned, target in itertools.product(
(False, True), ("aarch64-apple-darwin", "x86_64-apple-darwin")
):
with (
self.subTest(provisioned=provisioned, target=target),
tempfile.TemporaryDirectory() as directory,
):
root = Path(directory).resolve()
package, driver, env = self.fixture(root, provisioned, target)
result = self.run_driver(driver, "sign", package, env)
self.assertEqual(result.returncode, 0, result.stderr)
result = self.run_driver(driver, "verify", package, env)
self.assertEqual(result.returncode, 0, result.stderr)
calls = [
json.loads(line)
for line in (root / "calls.jsonl").read_text().splitlines()
]
signing = [call for call in calls if call[0] == "sign_macos_code.sh"]
self.assertEqual(
[call[call.index("--target") + 1] for call in signing],
[
str(package / relative)
for relative in (
bundle.APP if provisioned else "bin/codex",
*bundle.HELPERS,
)
],
)
self.assertEqual(
signing[0][signing[0].index("--entitlements") + 1],
str(
root
/ "signing-verification/codex-provisioned-entitlements.plist"
)
if provisioned
else str(
Path(env["MOCK_SIGNING_SCRIPTS"]) / "codex.entitlements.plist"
),
)
self.assertEqual(
["--entitlements" in call for call in signing],
[True, True, False, False],
)
self.assertEqual(
[call[0] for call in calls if call[0].startswith("notarize")],
["notarize_with_akv.py"]
if provisioned
else ["notarize_macos_binary_with_akv.sh"] * 4,
)
self.assertEqual(
[call[1:] for call in calls if call[0] == "lipo"],
[
[
str(package / relative),
"-verify_arch",
"arm64" if target.startswith("aarch64") else "x86_64",
]
for relative in (
bundle.EXECUTABLE if provisioned else "bin/codex",
*bundle.HELPERS,
)
],
)
if provisioned:
with zipfile.ZipFile(root / "provisioned-cli.zip") as archive:
self.assertEqual(
archive.read(
"CodexCLI.app/Contents/embedded.provisionprofile"
),
self.configuration.profile.read_bytes(),
)
self.assertEqual(
archive.read("bin/codex").decode(), bundle.LAUNCHER
)
self.assertTrue(
all(
helper in archive.namelist()
for helper in bundle.HELPERS
)
)
def test_signing_and_notarization_failures_stop_the_driver(self):
for tool in ("sign_macos_code.sh", "notarize_with_akv.py"):
with self.subTest(tool=tool), tempfile.TemporaryDirectory() as directory:
root = Path(directory).resolve()
package, driver, env = self.fixture(root, True)
result = self.run_driver(
driver, "sign", package, {**env, "FAIL_TOOL": tool}
)
self.assertNotEqual(result.returncode, 0)
calls = [
json.loads(line)
for line in (root / "calls.jsonl").read_text().splitlines()
]
self.assertEqual(calls[-1][0], tool)
if tool == "notarize_with_akv.py":
self.assertEqual(
(root / "signing-verification/notarization.log").read_text(),
"fixture stdout\nfixture stderr\n",
)
self.assertIn("fixture stdout\nfixture stderr\n", result.stdout)
else:
self.assertFalse((root / "provisioned-cli.zip").exists())
def test_verification_rejects_wrong_signing_identity_and_entitlements(self):
for provisioned, failure in itertools.product(
(False, True), ("MOCK_WRONG_SIGNING_IDENTITY", "MOCK_WRONG_ENTITLEMENTS")
):
with (
self.subTest(provisioned=provisioned, failure=failure),
tempfile.TemporaryDirectory() as directory,
):
root = Path(directory).resolve()
package, driver, env = self.fixture(root, provisioned)
signed = self.run_driver(driver, "sign", package, env)
self.assertEqual(signed.returncode, 0, signed.stderr)
result = self.run_driver(
driver, "verify", package, {**env, failure: "true"}
)
self.assertNotEqual(result.returncode, 0)
if failure == "MOCK_WRONG_SIGNING_IDENTITY":
self.assertIn(
"code failed to satisfy specified code requirement(s)",
result.stderr,
)
else:
self.assertIn("unexpected", result.stdout)
def test_cli_requires_independent_profile_configuration(self):
with tempfile.TemporaryDirectory() as directory:
result = subprocess.run(
[
sys.executable,
str(Path(bundle.__file__).with_name("sign_macos_cli_package.py")),
"verify",
directory,
],
capture_output=True,
text=True,
check=False,
)
self.assertEqual(result.returncode, 2)
self.assertIn("the following arguments are required", result.stderr)
if __name__ == "__main__":
unittest.main()