Give Codex Cloud a Mac for iOS builds
Codex Cloud tasks run in OpenAI's cloud VMs. With a NoMac API key in the environment and NoMac's domains allowed, a task can build and test an iOS app on a cloud Mac with Xcode.
· 5 min read
Need a Mac for this? NoMac gives your agent full macOS with Xcode for $0.80 an hour, billed by the minute. Start now →
Codex Cloud runs each task in its own VM in OpenAI's cloud. Building an iOS app takes Xcode, and Xcode runs only on macOS. So when a task should prove that a Swift change compiles, or run the tests in the iOS Simulator, it needs a Mac it can reach. NoMac gives it one: the task starts a Mac, sends the code, runs xcodebuild there and stops the Mac when it is done.
Not tested end to end: we have not run this setup in Codex Cloud. The steps follow OpenAI's documentation for cloud environments, as of October 2026, and NoMac's own requirements. The environment must allow the domains below, or no request reaches NoMac.
What the task needs
- ·A NoMac API key in the environment, as
NOMAC_API_KEY. - ·Internet access to
nomac.app. For the CLI, alsoregistry.npmjs.organd NoMac's session gateway (step 3). - ·For the CLI, Node 20 or newer, the OpenSSH client and rsync.
startcreates a key withssh-keygen;syncandpulluse ssh and rsync. - ·NoMac credit: $0.80 an hour while a Mac runs, billed by the minute.
Step 1: make an API key
Sign in at nomac.app/keys and create a key. It starts with nmk_. Anyone holding it can start Macs on your credit, so put it only in Codex's settings, never in the repository.
Step 2: add the key to the environment
In the environment configuration, select Manage beside Environment variables and add NOMAC_API_KEY with the key as its value. OpenAI's cloud environments page says environment variables are “passed directly to programs in the environment”, and the NoMac CLI reads that variable.
The same page offers network secrets: programs see a placeholder, and Codex's proxy puts the real value into HTTPS requests to the domains you allow. We have not tested NoMac with them, so this guide uses an environment variable.
In a Codex Cloud (Legacy) environment, OpenAI's legacy page says secrets reach only the setup script and are removed before the agent starts. Use an environment variable there too.
Step 3: allow NoMac on the network
Turn on Allow Codex to access internet. Under Allow domains, choose Package managers, which includes registry.npmjs.org for npx, and add nomac.app under Additional allowed domains.
That covers NoMac's REST API and the CLI's start, status and stop. The CLI's exec, ssh, sync and pull connect to NoMac's session gateway instead, over HTTPS on port 443 (ssh and sync as a WebSocket). The gateway is a separate host, not under nomac.app: the API returns it for each session, as the gateway field of POST /api/v1/mac/sessions/:id/access. Allow that host as well, or choose All (unrestricted).
In Codex Cloud (Legacy), the internet access page says access is blocked during the agent phase by default. If you turn it on and restrict HTTP methods to GET, HEAD and OPTIONS, NoMac cannot work: starting a Mac and running a command are POST requests, and stopping one is a DELETE.
Step 4: tell Codex how to use the Mac
Add a section like this to the repository's AGENTS.md and adjust the scheme:
## iOS builds
- For anything that needs Xcode (builds, tests, the Simulator), use a
NoMac cloud Mac. NOMAC_API_KEY is set. https://nomac.app/llms.txt
explains NoMac.
- Start one Mac per task and reuse it:
npx -y @nomac/cli@latest start --json
- Send the working tree, then build:
npx -y @nomac/cli@latest sync .
npx -y @nomac/cli@latest exec --wait 600 -- xcodebuild -scheme MyApp \
-destination 'generic/platform=iOS Simulator' build
- Read the full compiler output before changing code.
- Before you finish, always run: npx -y @nomac/cli@latest stop --jsonsync puts the project in ~/drive/src on the Mac, under the checkout folder's name, and exec runs there. A command still running when --wait ends keeps running; exec exits 75 and prints how to wait for it.
Without the CLI
If the environment can reach only nomac.app, the task can use the REST API with curl and the same key: POST /api/v1/mac/sessions starts a Mac, POST /api/v1/mac/sessions/:id/jobs?wait=30 runs a command and returns its output, and DELETE /api/v1/mac/sessions/:id stops it. Files go to the Mac through POST /api/v1/mac/sessions/:id/files, up to 3 MiB each, or the Mac clones the repository itself. The API reference has every endpoint.
Costs and limits
- ·$0.80 an hour while the Mac is ready, billed by the minute. Queue and setup time are free. A five-minute build costs about 7 cents.
- ·A session stops after two hours or $5 by default.
--max-durationand--max-costonstartchange that. - ·One Mac at a time by default: a
startwhile a Mac runs uses that Mac. - ·Stopping deletes the VM and everything outside
~/drive. The 50 GB drive keeps the project and build caches, so the next task's build is incremental.
Why hosted agents need this at all is in why cloud coding agents can't build your iOS app. Taking a build on to TestFlight is in Codex to TestFlight, and every command is in the CLI reference.