Skip to main content

Overview

Code signing is one of the most challenging aspects of iOS development. fastlane provides several actions to simplify certificate and provisioning profile management.

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

match(type: "appstore")

Parameters

type
string
Profile type: appstore, adhoc, development, or enterprise
app_identifier
string or array
Bundle identifier(s) for your app
git_url
string
URL to the git repository for storing certificates
git_branch
string
default:"master"
Git branch to use
storage_mode
string
default:"git"
Storage mode: git, google_cloud, s3, gitlab_secure_files
readonly
boolean
default:"false"
Only fetch existing certificates and profiles (don’t create new ones)
force_for_new_devices
boolean
default:"false"
Renew profiles when new devices are added
username
string
Your Apple ID username
team_id
string
Your Developer Portal team ID
platform
string
default:"ios"
Platform: ios, macos, tvos
api_key
hash
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"
)

Supported Platforms

  • iOS
  • macOS

Alternative: Individual Actions

cert (get_certificates)

Fetch or create iOS code signing certificates.
cert is an alias for get_certificates.

Basic Usage

cert

Parameters

development
boolean
default:"false"
Create a development certificate instead of distribution
username
string
Your Apple ID username
team_id
string
Your Developer Portal team ID
output_path
string
default:"."
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

sigh

Parameters

adhoc
boolean
default:"false"
Create an ad-hoc profile
development
boolean
default:"false"
Create a development profile
app_identifier
string
Bundle identifier for the app
username
string
Your Apple ID username
team_id
string
Your Developer Portal team ID
output_path
string
default:"."
Path to store the profile
filename
string
Custom filename for the profile
force
boolean
default:"false"
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
string
Path to your Xcode project
use_automatic_signing
boolean
default:"false"
Enable or disable automatic signing
team_id
string
Team ID for signing
targets
array
Specific targets to update (defaults to all)
build_configurations
array
Specific build configurations to update (defaults to all)
code_sign_identity
string
Code signing identity (e.g., “iPhone Distribution”)
profile_name
string
Provisioning profile name
profile_uuid
string
Provisioning profile UUID
bundle_identifier
string
Bundle identifier to set
entitlements_file_path
string
Path to entitlements file
sdk
string
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"]
)

Supported Platforms

  • iOS
  • macOS

Complete Code Signing Workflows

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
)
Use arrays for apps with extensions:
match(
  type: "appstore",
  app_identifier: [
    "com.example.app",
    "com.example.app.widget",
    "com.example.app.extension"
  ]
)
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
)

Build docs developers (and LLMs) love