Overview
Code signing is one of the most challenging aspects of iOS development. fastlane provides several actions to simplify certificate and provisioning profile management.
Recommended: match (sync_code_signing)
match
The recommended approach for code signing. Stores certificates and profiles in a git repository for easy team synchronization.
sync_code_signing is an alias for match.
Why match?
One code signing identity for the whole team
Easy setup on new machines
No more “certificate invalid” errors
Works with multiple teams and apps
Supports all provisioning profile types
Basic Usage
Parameters
Profile type: appstore, adhoc, development, or enterprise
Bundle identifier(s) for your app
URL to the git repository for storing certificates
Storage mode: git, google_cloud, s3, gitlab_secure_files
Only fetch existing certificates and profiles (don’t create new ones)
Renew profiles when new devices are added
Your Developer Portal team ID
Platform: ios, macos, tvos
App Store Connect API key
Shared Values
MATCH_PROVISIONING_PROFILE_MAPPING - Maps bundle IDs to profile names
SIGH_PROFILE_TYPE - Profile type for use with build_app
Examples
# App Store profile
match ( type: "appstore" , app_identifier: "tools.fastlane.app" )
# Development profile (readonly mode for CI)
match ( type: "development" , readonly: true )
# Multiple bundle identifiers
match (
app_identifier: [ "tools.fastlane.app" , "tools.fastlane.sleepy" ]
)
# Using sync_code_signing alias
sync_code_signing (
type: "appstore" ,
app_identifier: "tools.fastlane.app"
)
# Complete setup
match (
type: "appstore" ,
app_identifier: "com.example.app" ,
git_url: "https://github.com/myteam/certificates" ,
git_branch: "main" ,
username: "[email protected] " ,
team_id: "XXXXXXXXXX"
)
# For CI/CD (readonly mode)
match (
type: "appstore" ,
readonly: true ,
app_identifier: "com.example.app"
)
# Update profiles when adding new devices
match (
type: "development" ,
force_for_new_devices: true
)
Integration with build_app
match automatically configures build_app:
# match sets up everything
match ( type: "appstore" )
# build_app automatically uses the right profiles
build_app ( scheme: "MyApp" )
# export_method and provisioning profiles are set automatically
Initial Setup
# Run once to initialize match
match (
type: "development" ,
app_identifier: "com.example.app" ,
git_url: "https://github.com/myteam/certificates"
)
Alternative: Individual Actions
cert (get_certificates)
Fetch or create iOS code signing certificates.
cert is an alias for get_certificates.
Basic Usage
Parameters
Create a development certificate instead of distribution
Your Developer Portal team ID
Path to store the certificate
Examples
# Get distribution certificate
cert
# Get development certificate
cert ( development: true )
# Using get_certificates
get_certificates (
username: "[email protected] " ,
output_path: "./certs"
)
sigh (get_provisioning_profile)
Fetch or create iOS provisioning profiles.
sigh is an alias for get_provisioning_profile.
Basic Usage
Parameters
Create a development profile
Bundle identifier for the app
Your Developer Portal team ID
Path to store the profile
Custom filename for the profile
Force recreate the profile
Examples
# Get App Store profile
sigh
# Get ad-hoc profile
sigh ( adhoc: true )
# Get development profile
sigh ( development: true )
# Complete configuration
sigh (
app_identifier: "com.example.app" ,
username: "[email protected] " ,
team_id: "XXXXXXXXXX" ,
output_path: "./profiles"
)
Project Configuration Actions
update_code_signing_settings
Update Xcode project code signing settings.
Basic Usage
update_code_signing_settings (
use_automatic_signing: false ,
path: "MyApp.xcodeproj"
)
Parameters
Path to your Xcode project
Enable or disable automatic signing
Specific targets to update (defaults to all)
Specific build configurations to update (defaults to all)
Code signing identity (e.g., “iPhone Distribution”)
Provisioning profile name
Provisioning profile UUID
Path to entitlements file
SDK to set settings for (e.g., “iphoneos*“)
Examples
# Enable manual code signing
update_code_signing_settings (
use_automatic_signing: false ,
path: "MyApp.xcodeproj"
)
# Enable automatic code signing
update_code_signing_settings (
use_automatic_signing: true ,
path: "MyApp.xcodeproj"
)
# Configure manual signing
update_code_signing_settings (
use_automatic_signing: false ,
path: "MyApp.xcodeproj" ,
team_id: "QABC123DEV" ,
bundle_identifier: "com.demoapp.QABC123DEV" ,
code_sign_identity: "iPhone Distribution" ,
sdk: "iphoneos*" ,
profile_name: "Demo App Deployment Profile" ,
entitlements_file_path: "Demo App/generated/New.entitlements"
)
# Update specific targets only
update_code_signing_settings (
use_automatic_signing: false ,
path: "MyApp.xcodeproj" ,
targets: [ "MyApp" , "MyAppExtension" ]
)
# Update specific configurations
update_code_signing_settings (
use_automatic_signing: false ,
path: "MyApp.xcodeproj" ,
build_configurations: [ "Release" , "Beta" ]
)
Complete Code Signing Workflows
Using match (Recommended)
lane :release do
# Get App Store certificates and profiles
match ( type: "appstore" )
# Build automatically uses match settings
build_app ( scheme: "MyApp" )
# Upload to App Store
upload_to_app_store
end
lane :beta do
# Get TestFlight certificates and profiles
match ( type: "appstore" )
# Build
build_app ( scheme: "MyApp" )
# Upload to TestFlight
upload_to_testflight
end
lane :development do
# Get development certificates and profiles
match (
type: "development" ,
force_for_new_devices: true
)
# Build for testing
build_app (
scheme: "MyApp" ,
export_method: "development"
)
end
Using cert and sigh
lane :release do
# Get certificate
cert
# Get provisioning profile
sigh ( app_identifier: "com.example.app" )
# Build
build_app (
scheme: "MyApp" ,
export_method: "app-store"
)
# Upload
upload_to_app_store
end
CI/CD with match
lane :ci_build do
# Setup CI
setup_ci
# Get certificates and profiles (readonly mode)
match (
type: "appstore" ,
readonly: true
)
# Build
build_app ( scheme: "MyApp" )
# Upload
upload_to_testflight
end
Manual Signing Configuration
lane :configure_signing do
# Disable automatic signing
update_code_signing_settings (
use_automatic_signing: false ,
path: "MyApp.xcodeproj"
)
# Get certificates and profiles
match ( type: "appstore" )
# Update project with match profiles
update_code_signing_settings (
use_automatic_signing: false ,
path: "MyApp.xcodeproj" ,
profile_name: ENV [ "sigh_com.example.app_appstore_profile-name" ]
)
end
Best Practices
match is the best solution for teams: # One command to get everything
match ( type: "appstore" )
build_app ( scheme: "MyApp" )
Never create certificates in CI: match (
type: "appstore" ,
readonly: true # Only fetch, never create
)
Handle multiple bundle identifiers
Use arrays for apps with extensions: match (
type: "appstore" ,
app_identifier: [
"com.example.app" ,
"com.example.app.widget" ,
"com.example.app.extension"
]
)
Use App Store Connect API keys
Avoid storing passwords: api_key = app_store_connect_api_key (
key_id: "D383SF739" ,
issuer_id: "6053b7fe-68a8-4acb-89be-165aa6465141" ,
key_filepath: "./AuthKey_D383SF739.p8"
)
match (
type: "appstore" ,
api_key: api_key
)