Overview
Code signing proves that your app and its extensions come from a trusted source (you) and haven’t been tampered with. Every target in your app—main app, widgets, App Clips, extensions—requires its own code signature.How Code Signing Works
Each target needs:- Certificate - Identifies you as the developer (shared across all targets)
- Provisioning Profile - Links your app ID, certificate, and device IDs
- Entitlements - Permissions the target needs
Automatic Code Signing (Xcode)
First-Time Setup
-
Open Xcode:
- Select each target in the project navigator
- Go to Signing & Capabilities tab
- Check “Automatically manage signing”
- Select your Team from the dropdown
Xcode will automatically create provisioning profiles and register App IDs for all targets.
Development Team ID
Set your Apple Team ID inapp.json:
- In Xcode: Signing & Capabilities → Team dropdown shows ID in parentheses
- Apple Developer Portal: Membership page → Team ID
EAS Build (Automatic)
EAS Build handles code signing automatically for all targets.How It Works
- Syncs entitlements - The plugin exports entitlements via
withEASTargets:
- Creates App IDs - EAS registers all bundle identifiers
- Generates profiles - Creates provisioning profiles for each target
- Downloads certificates - Uses your distribution certificate
- Signs all targets - Applies signatures during build
EAS Setup
eas.json:
Running a Build
- Detects all targets from your config
- Creates provisioning profiles
- Signs each target
- Embeds targets in the app bundle
The first build takes longer as EAS registers App IDs and creates profiles. Subsequent builds reuse credentials.
Manual Code Signing
For custom CI/CD or advanced setups.1. Register App IDs
For each target, register an App ID in Apple Developer Portal:2. Configure Capabilities
For each App ID, enable required capabilities:- App Groups - For data sharing
- Associated Domains - For App Clips and universal links
- Push Notifications - For remote notifications
- Sign in with Apple - For authentication
- Etc.
3. Create Provisioning Profiles
For each target:- Go to Provisioning Profiles
- Click + to create new profile
- Select profile type:
- Development - For local testing
- Ad Hoc - For TestFlight internal testing
- App Store - For App Store distribution
- Select the App ID
- Select your certificate
- Select devices (Development/Ad Hoc only)
- Download and install
4. Install Profiles
Double-click.mobileprovision files or:
5. Configure Xcode
For each target:- Select target in Xcode
- Signing & Capabilities tab
- Uncheck “Automatically manage signing”
- Select provisioning profile from dropdown
Build Settings
The plugin automatically configures code signing build settings:DEVELOPMENT_TEAM- Your Team IDCODE_SIGN_STYLE-AutomaticorManualCODE_SIGN_ENTITLEMENTS- Path to entitlements filePRODUCT_BUNDLE_IDENTIFIER- Bundle IDPROVISIONING_PROFILE_SPECIFIER- Profile name (manual signing)
App Clip Signing
App Clips have additional requirements:1. Parent Application Identifier
Automatically set by the plugin:2. Associated Domains
Required for launching from websites:3. AASA File
Publish an Apple App Site Association file at:Troubleshooting
Common Issues
Code signing error: No profile found
Code signing error: No profile found
Solution:
- Open Xcode Signing tab
- Enable “Automatically manage signing”
- Select your Team
- Xcode will create profiles
- Re-run your build
Entitlements don't match provisioning profile
Entitlements don't match provisioning profile
Solution:
- Check entitlements in
expo-target.config.js - Verify capabilities are enabled for App ID in Developer Portal
- Regenerate provisioning profile
- Download and install new profile
App Groups not in provisioning profile
App Groups not in provisioning profile
Solution:
- Go to App ID in Developer Portal
- Enable “App Groups” capability
- Configure App Group ID (matches entitlements)
- Regenerate provisioning profile
- Download and install
Multiple targets with same bundle ID
Multiple targets with same bundle ID
Solution:
- Each target needs a unique bundle ID
- Use dot notation:
.widget,.clip,.share - Or specify absolute:
com.example.widget - Re-run
npx expo prebuild --clean
EAS Build fails with provisioning error
EAS Build fails with provisioning error
Solution:
- Check
appleTeamIdinapp.json - Verify bundle IDs are unique
- Check entitlements are valid
- Try deleting credentials:
eas credentials - Run build again (will recreate credentials)
Debug Commands
CI/CD Integration
GitHub Actions
Fastlane
Best Practices
- Use EAS Build - Simplest and most reliable
- Set
appleTeamId- Required for consistent builds - Enable automatic signing - For local development
- Use unique bundle IDs - Never reuse across targets
- Enable capabilities - Match entitlements in Developer Portal
- Test profiles - Build locally before CI/CD
- Document setup - Team members need same Team ID access
Next Steps
Development workflow
Learn the development workflow
EAS Build
Learn more about EAS Build