Set up Fastlane Match to store certificates and provisioning profiles in an encrypted repository so every developer and CI machine signs iOS builds identically.
iOS code signing is a notorious pain point. Each developer machine and each CI runner needs a valid certificate and a matching provisioning profile, and keeping them all in sync manually leads to the classic "works on my machine" signing failures.
Match takes a different approach. It generates your signing certificates and provisioning profiles once, encrypts them, and stores them in a shared location, usually a private Git repository.
Every machine then fetches and decrypts the same assets. The result is that everyone signs with identical credentials.
New team members and fresh CI runners get set up in minutes instead of hours of certificate wrangling, which is exactly why Match has become such a widely adopted part of the Fastlane toolkit.
The underlying insight is that signing assets are just files that need to be shared securely. Instead of each person exporting and importing certificates by hand, Match makes a single encrypted source of truth that every machine reads from, which is what eliminates the drift between machines.
Match needs somewhere to store encrypted signing assets. The most common choice is a dedicated private Git repository, separate from your app's source code.
Create an empty private repo, for example named something like ios-certificates. Match will populate it with encrypted certificates and profiles.
Make sure it is private, since even encrypted signing material should never be public.
Match also supports other storage backends such as cloud object storage, but a private Git repo is the simplest and most widely used starting point. You can migrate storage later if your needs change.
Keeping this repository separate from your application code is deliberate. It means you can grant narrow, read-only access to CI for signing assets without exposing your source, and you can audit access to signing material independently of who can read the app.
From your project root, run fastlane match init. This creates a Matchfile in your fastlane directory where you configure the storage mode and the URL of your certificates repository.
During initialization you specify the Git URL of the private repo you created. Match records this so future commands know where to read and write.
Commit the Matchfile to your app repository.
It contains configuration, not secrets, so it is safe to share with your team. The encryption passphrase and repository access remain the things you must protect separately.
During init you also choose the storage mode, typically git. Recording the mode and repository URL in the Matchfile means teammates do not have to remember or retype those details on every command.
Now generate the actual certificates and profiles. Run a command for each signing type you need, such as fastlane match development for development builds and fastlane match appstore for distribution and TestFlight.
The first time you run these, Match creates the certificates and provisioning profiles in your Apple Developer account, encrypts them, and pushes them to your storage repo. You will be asked to set a passphrase that encrypts the contents.
Guard that passphrase carefully.
It is the key that unlocks all your signing material, and anyone with the passphrase plus repo access can sign as your team. Store it in a secrets manager, never in plain text in a repository.
Choose the passphrase once and share it through a secure channel with the people who need it. Because it decrypts every certificate and profile in the repo, treat it with the same care you would give a production database password.
In your Fastfile, call the match action at the start of any lane that builds a signed app. For a TestFlight or App Store lane, request the appstore type so the correct distribution assets are fetched.
Match installs the certificate into the machine's keychain and the provisioning profile where Xcode expects it, then build_app can produce a correctly signed .ipa.
Because every machine fetches the same assets, a build that signs correctly on one developer's machine will sign correctly everywhere, including CI.
This consistency is the entire point. It converts signing from a per-machine gamble into a predictable, repeatable step.
If a lane builds multiple targets, request each signing type it needs. An app plus an extension, for instance, each require their own profile, and calling match for every identifier ensures all of them are in place before build_app runs.
On CI, Match needs three things: access to the certificates repo, the encryption passphrase, and Apple authentication. Provide the passphrase through the MATCH_PASSWORD environment variable set as an encrypted CI secret.
Give CI read-only access to the certificates repo. A common practice is a deploy key or token scoped to read the repo only, so the pipeline can fetch assets but cannot alter them. Pair this with the readonly option so Match never tries to regenerate certificates on CI.
For Apple authentication, use an App Store Connect API key so Match and your upload steps run without interactive prompts.
These three pieces together let a headless runner fetch and use signing assets safely, without the ability to modify shared credentials.
A good test of your CI setup is to run the signing step on a fresh runner and confirm it succeeds without any manual intervention. If it does, you have genuinely non-interactive signing, which is the property that makes unattended releases possible.
Certificates and profiles expire and occasionally need regeneration, for instance when you add a new device or a certificate lapses. When that happens, a team member with write access runs the appropriate match command to renew and re-push the assets.
New developers simply run the match commands to fetch and decrypt existing assets with the shared passphrase. No manual certificate export or import is required.
Establish a clear owner for signing changes.
Because everyone shares the same assets, an accidental regeneration by one person affects the whole team, so coordinate renewals deliberately rather than letting anyone run destructive commands ad hoc.
Treat the encryption passphrase and repo access as high-value secrets. Store the passphrase in your secrets manager, not in plain text, and rotate it if you suspect exposure.
Use read-only access on CI and reserve write access for a small number of trusted maintainers. This limits the blast radius if a CI token leaks.
Finally, keep the certificates repo private and audit who has access periodically.
Match dramatically simplifies signing, but the convenience of shared credentials means access control is your responsibility. A short, deliberate access list is far safer than broad, forgotten permissions.
It stores your iOS signing certificates and provisioning profiles in encrypted form, typically in a private Git repository, so every machine can fetch and use identical signing assets.
Yes, when the repo is private and the contents are encrypted with a strong passphrase that you keep secret. The passphrase and repo access are the critical things to protect.
Give CI read-only access to the certificates repo, supply the encryption passphrase via an encrypted secret, use the readonly option, and authenticate to Apple with an App Store Connect API key.
They run the relevant match commands and, with the shared passphrase, fetch and decrypt the existing signing assets. No manual certificate export or import is needed.