It's 2 a.m., and the third person on the team just ran fastlane build on the same cloud Mac — and CI failed instantly with an invalid certificate error. All three of them had run match locally at some point, and none of them noticed that their own action had already knocked another teammate's freshly imported signing certificate out of the system's default Keychain. This kind of incident is almost inevitable when a team shares one cloud Mac for builds. Here's how we centralized certificate management with fastlane match and solved the headache of Keychain repeatedly prompting for a password over headless remote sessions.
The Problem: Why Certificates Keep Breaking on a Shared Cloud Mac
For local development, one Mac usually serves one person, so certificates dropped into the default Keychain never collide. But a cloud Mac rented by the day is often shared across a team: you SSH in to build today, a teammate remotely logs in to tweak a config and build again tomorrow. If everyone independently runs fastlane match development or manually imports a p12, the certificate entries in the system's default Keychain get overwritten, deleted, and recreated over and over — eventually producing the classic error: "certificate exists but the private key can't be found during signing."
The root cause is two things getting conflated: certificate storage and distribution, versus the certificate's temporary authorization inside a local Keychain. The former should be centrally managed; only the latter needs per-session isolation.
The Core Idea Behind fastlane match
match encrypts development certificates, distribution certificates, and their matching provisioning profiles, then stores them all in a single dedicated Git repository. Everyone on the team — including automation accounts on the cloud Mac — pulls the same set of certificates from that repository instead of regenerating their own in the Apple Developer portal. This guarantees identical signing results for the same Bundle ID across any machine, and sidesteps the old "certificate count exceeds Apple's quota" problem.
The value of match isn't "auto-generating certificates" — it's "nobody needs to generate their own certificates anymore." That single sentence dictates how it should be used: only one person (or a single CI initialization job) should ever perform write operations; every other scenario should pull in read-only mode.
Bootstrapping the Certificate Repo on a Cloud Mac
In your cloud Mac project directory, first make sure Matchfile points to a private repository, not a public one:
git_url("git@github.com:your-org/certs-private.git")
storage_mode("git")
type("appstore")
Run the initial bootstrap exactly once, on a single trusted machine:
fastlane match appstore --readonly false
After that, every pull performed on any cloud Mac should include --readonly true, ensuring it only fetches existing certificates and never attempts to regenerate them:
fastlane match appstore --readonly true
Issue the deployment user a dedicated, read-only Git deploy key instead of stuffing everyone's personal SSH keys onto the cloud Mac. The permission boundary is cleaner, and you don't have to revoke access one by one when staff changes.
Unattended Keychain Unlock over Headless Remote Sessions
A cloud Mac is mostly accessed via SSH or VNC — nobody is physically sitting at the screen typing a password. The system's default login Keychain frequently ends up locked between sessions, and the moment codesign runs, it pops an authorization dialog — which will simply hang an unattended CI trigger.
The fix is to create a dedicated signing Keychain, separate from the login Keychain:
security create-keychain -p "$KEYCHAIN_PWD" signing.keychain
security set-keychain-settings -lut 21600 signing.keychain
security unlock-keychain -p "$KEYCHAIN_PWD" signing.keychain
security import cert.p12 -k signing.keychain -P "$P12_PWD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PWD" signing.keychain
list=$(security list-keychains -d user | tr -d '"')
security list-keychains -d user -s signing.keychain $list
The set-key-partition-list step is easy to miss — skip it, and codesign will still pop an authorization prompt even though the Keychain is already unlocked. Keep this dedicated Keychain limited to signing certificates only, don't mix it with everyday passwords, and when the rental ends or the project changes hands, simply deleting this Keychain is far cleaner than scrubbing the default one.
Certificate Pulling and Cleanup After a CI Trigger
Automation should run in the following order, with any step failure halting the pipeline immediately rather than letting it continue:
| Step | Command/Action | On Failure |
|---|---|---|
| Unlock dedicated Keychain | security unlock-keychain |
Abort immediately, file a ticket instead of silently retrying |
| Read-only certificate pull | fastlane match … --readonly true |
Abort, prompt to run a write operation on the primary machine first |
| Run the build | xcodebuild archive |
Preserve build logs for troubleshooting |
| Clean up temporary Keychain references | security delete-keychain signing.keychain (as needed) |
Log whether cleanup succeeded |
If the cloud Mac is rented by the day and gets handed off to another task or reclaimed at the end of the rental, this last cleanup step matters even more: the dedicated signing Keychain, any temporarily downloaded p12 files, and provisioning profiles under ~/Library/MobileDevice/Provisioning Profiles should all be wiped at the end of the job — don't assume the next rental period inherits a clean environment. Whether a given machine spec and node meet your team's concurrent build demands is worth confirming in the control panel before scheduling, since compile-speed differences between chip variants directly affect how long everyone else waits in the queue.
Team Collaboration and Permission Boundaries
Splitting up responsibilities clearly saves a lot of debugging time down the road:
- Certificate write access: grant it to only one person or one initialization pipeline; everyday team members and automation accounts on the cloud Mac all use
--readonly true. - Repository access: use a deploy key for the certificate repo instead of personal account keys, so access can be revoked per person or per machine independently.
- Local Keychain isolation: assign each user or each parallel build lane its own dedicated Keychain file and build directory, so nobody overwrites the default Keychain.
- Password and token storage: inject
KEYCHAIN_PWD,P12_PWD, and the Git deploy key through environment variables or CI's encrypted secrets — never hardcode them into script files.
Pre-Launch Checklist
- [ ]
Matchfilepoints to a private repository, and nobody on the team has ever stored certificate history in a public one; - [ ] Every match command run on the cloud Mac includes
--readonly true; - [ ]
set-key-partition-listhas been applied to the dedicated signing Keychain, confirmingcodesignno longer prompts; - [ ] Each parallel user/build lane has its own separate Keychain file and build directory;
- [ ] A cleanup script deletes the dedicated Keychain and temporary provisioning profiles before the job or rental period ends.
Once certificate management and Keychain unlocking are handled as two separate concerns, a team can take turns building on the same cloud Mac without stepping on each other's certificates. New hires joining the project just need to clone the repo once and run a single read-only command — no need to request new certificates.
Frequently asked questions
Can the match certificate repo just be a public Git repo?
No. match encrypts p12 certificates and provisioning profiles before storing them, but a public repo still leaks structure and metadata. Use a private repo and issue a read-only token to the deploy user on your cloud Mac.
Do I need to type the Keychain password every time the cloud Mac reboots?
No. Create a dedicated signing keychain with security create-keychain using a fixed password, disable auto-lock with security set-keychain-settings, grant codesign access with -A, then run one unlock script after each new session login.
Will certificates conflict if multiple people build on the same cloud Mac?
Yes, if everyone runs match independently the default keychain gets repeatedly imported and exported. Give each person a separate build directory and dedicated keychain file, and use match's readonly mode so it only reads existing certs instead of regenerating them.
HireVPS
Try a dedicated cloud Mac mini today
Rent by the day, get SSH/VNC credentials in 2 minutes, and upgrade your configuration anytime.