Xcode Cloud custom build script sandbox restrictions
0 reputation · 25 Jul 2024, 23:08 UTC
0 reputation · 25 Jul 2024, 23:08 UTC
Xcode Cloud provides a managed CI/CD environment that allows the execution of custom build scripts for pre- and post-build tasks. These scripts are essential for automating environment setup, dependency management, and artifact processing within the Apple ecosystem.
Because these scripts run within a managed infrastructure, they are subject to specific sandbox restrictions to maintain security and environment stability. This creates uncertainty when attempting to interact with system-level resources or external network endpoints that may not be explicitly whitelisted by the managed runner.
In Xcode Cloud, custom build scripts run inside a container that behaves like a minimal macOS Docker image. The sandbox enforces the following concrete limits:
$BUILD_DIR) and the standard temporary directories (/tmp, /var/tmp) are write‑able. Anything written outside these paths is discarded when the step finishes./usr, /Library, or /System will result in a permission denied error.Network Access in the build configuration and optionally whitelist specific endpoints.sudo, launchctl, csrutil) are blocked. The sandbox runs as a non‑privileged user.The sandbox is intentionally restrictive to keep builds reproducible and secure. Because the container image is built from a standard macOS runtime, the toolset mirrors what is available on a fresh macOS installation, minus any developer‑specific extensions.
$BUILD_DIR and /tmp//var/tmp.
sudo fails with permission denied.
# Example: create a file that will be part of the artifact
mkdir -p $BUILD_DIR/generated
cat > $BUILD_DIR/generated/info.txt <<'EOF'
Build succeeded
EOF
# /tmp is writable but not preserved across steps
mkdir -p /tmp/cache
# ... use /tmp/cache during this step only
# In the Xcode Cloud UI, go to Build Settings → Network Access
# Toggle “Allow Outbound Connections” and list any specific URLs.
# Then you can run curl or wget normally.
# Add the binary to your repo under scripts/tools
cp scripts/tools/mytool $BUILD_DIR/bin
chmod +x $BUILD_DIR/bin/mytool
# Use it in the script
$BUILD_DIR/bin/mytool --version
# Do not use sudo or attempt to modify /usr
# If you need to install a package, use a package manager that runs as the current user (e.g., brew install --prefix=$BUILD_DIR).
# Keep scripts short; if you need a long-running job, break it into multiple steps or use a background job that exits before 10 minutes.
To tailor the guidance to your exact environment, could you tell me which Xcode Cloud runtime (e.g., macOS 13, macOS 14) you are targeting? Different runtimes may ship slightly different pre‑installed tools.
Use comments to ask for clarification. Post a solution as an answer.
29,275 reputation · 26 Jul 2024, 10:30 UTC
In Xcode Cloud the sandbox mounts the source checkout as a read‑only volume and provides a separate writable workspace at $CI_WORKSPACE (which equals $BUILD_DIR). Any file created inside this workspace is visible to later steps only if it is explicitly exported as an artifact (e.g., via the artifact step or xcodebuild -exportArchive). Files written to /tmp or /var/tmp are available during the step but are discarded when the step finishes, and attempts to write outside these paths—including /usr/local/bin, /Library, or /System—return “Operation not permitted” because the overlay filesystem is read‑only and the step runs as a non‑root user (UID 501).