Automate the management of signing certificates and provisioning profiles required for app distribution.
Overview
Code signing is required for:
- App Store distribution
- Ad-hoc distribution
- Development builds
- Enterprise distribution
The CLI provides a streamlined signing fetch command that:
- Resolves your bundle ID
- Finds matching certificates
- Locates or creates provisioning profiles
- Downloads everything to your local machine
Quick Start
Fetch Signing Assets for App Store
For App Store distribution:
asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_STORE \
--output ./signing
This will:
- Find your App Store distribution certificates
- Locate or create an App Store provisioning profile
- Download certificates as
.cer files
- Download the provisioning profile as
.mobileprovision
Fetch Signing Assets for Development
For development builds (requires device IDs):
asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_DEVELOPMENT \
--device "DEVICE_ID1,DEVICE_ID2" \
--output ./signing
Profile Types
iOS Profiles
- IOS_APP_STORE: App Store distribution
- IOS_APP_DEVELOPMENT: Development builds
- IOS_APP_ADHOC: Ad-hoc distribution
- IOS_APP_INHOUSE: Enterprise distribution
macOS Profiles
- MAC_APP_STORE: Mac App Store distribution
- MAC_APP_DEVELOPMENT: Mac development
- MAC_APP_DIRECT: Mac direct distribution
- MAC_CATALYST_APP_DEVELOPMENT: Mac Catalyst development
- MAC_CATALYST_APP_STORE: Mac Catalyst App Store
tvOS Profiles
- TVOS_APP_STORE: tvOS App Store
- TVOS_APP_DEVELOPMENT: tvOS development
- TVOS_APP_ADHOC: tvOS ad-hoc distribution
- TVOS_APP_INHOUSE: tvOS enterprise distribution
Complete Signing Workflow
Register your bundle ID (if new)
First-time setup for a new app:asc bundle-ids create \
--identifier "com.example.myapp" \
--name "My App" \
--platform IOS
Verify it exists:asc bundle-ids list --identifier "com.example.myapp"
Register development devices (for development profiles)
For development and ad-hoc profiles, register test devices:asc devices create \
--name "Jane's iPhone" \
--platform IOS \
--udid "00008030-XXXXXXXXXXXX"
List all registered devices:asc devices list --platform IOS
Create certificates (if needed)
Generate a Certificate Signing Request (CSR) on your Mac:# Using Keychain Access:
# 1. Open Keychain Access
# 2. Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority
# 3. Enter your email and name
# 4. Select "Saved to disk"
# 5. Save as CertificateSigningRequest.certSigningRequest
Upload the CSR to create a certificate:asc certificates create \
--type IOS_DISTRIBUTION \
--csr-path ./CertificateSigningRequest.certSigningRequest
List existing certificates:asc certificates list --type IOS_DISTRIBUTION
Fetch signing assets
Download everything at once:asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_STORE \
--output ./signing
The output directory will contain:signing/
├── My_App_Distribution.mobileprovision
└── ABC123DEF456.cer
Install certificates and profiles
Install the certificate (double-click or use CLI):# Import certificate into keychain
security import signing/ABC123DEF456.cer -k ~/Library/Keychains/login.keychain-db
Install the provisioning profile:# Copy to Xcode's provisioning profile directory
cp signing/*.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/
Or double-click the .mobileprovision file to install via Xcode.
Automatic Profile Creation
If no matching profile exists, use --create-missing to automatically create one:
asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_STORE \
--create-missing \
--output ./signing
For development profiles with specific devices:
asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_DEVELOPMENT \
--device "DEVICE_ID1,DEVICE_ID2,DEVICE_ID3" \
--create-missing \
--output ./signing
Certificate Management
List All Certificates
Filter by Type
asc certificates list --type IOS_DISTRIBUTION
asc certificates list --type IOS_DEVELOPMENT
asc certificates list --type MAC_APP_DISTRIBUTION
Check Certificate Expiration
asc certificates list --output json | jq '.data[] | {name: .attributes.name, expires: .attributes.expirationDate}'
Revoke a Certificate
Revoking a certificate will invalidate all provisioning profiles that use it. Only revoke certificates that are compromised or no longer needed.
asc certificates delete --id "CERTIFICATE_ID" --confirm
Provisioning Profile Management
List Profiles
asc profiles list --type IOS_APP_STORE
Get Profile Details
asc profiles get --id "PROFILE_ID"
Download a Specific Profile
asc profiles download --id "PROFILE_ID" --output ./my-profile.mobileprovision
Delete a Profile
asc profiles delete --id "PROFILE_ID" --confirm
CI/CD Integration
GitHub Actions Example
name: Build and Sign
on:
push:
branches: [main]
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Install asc CLI
run: |
curl -fsSL https://raw.githubusercontent.com/rudrankriyam/App-Store-Connect-CLI/main/install.sh | bash
- name: Configure ASC credentials
env:
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
ASC_PRIVATE_KEY: ${{ secrets.ASC_PRIVATE_KEY }}
run: |
echo "Credentials configured via environment variables"
- name: Fetch signing assets
run: |
asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_STORE \
--output ./signing
- name: Install certificate
run: |
# Create temporary keychain
security create-keychain -p "temp_password" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "temp_password" build.keychain
security set-keychain-settings -t 3600 -u build.keychain
# Import certificate
security import signing/*.cer -k build.keychain -A
security set-key-partition-list -S apple-tool:,apple: -s -k "temp_password" build.keychain
- name: Install provisioning profile
run: |
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp signing/*.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/
- name: Build app
run: |
xcodebuild archive \
-project MyApp.xcodeproj \
-scheme MyApp \
-archivePath ./build/MyApp.xcarchive
GitLab CI Example
stages:
- sign
- build
fetch_signing:
stage: sign
tags:
- macos
script:
- curl -fsSL https://raw.githubusercontent.com/rudrankriyam/App-Store-Connect-CLI/main/install.sh | bash
- |
asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_STORE \
--output ./signing
artifacts:
paths:
- signing/
expire_in: 1 hour
build_app:
stage: build
tags:
- macos
dependencies:
- fetch_signing
script:
- security import signing/*.cer -k ~/Library/Keychains/login.keychain-db
- cp signing/*.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/
- xcodebuild archive -project MyApp.xcodeproj -scheme MyApp -archivePath ./build/MyApp.xcarchive
Advanced Usage
Filter Certificates by Type
When fetching, you can filter which certificates to download:
asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_STORE \
--certificate-type IOS_DISTRIBUTION \
--output ./signing
Fetch for Multiple Bundle IDs
For apps with multiple targets:
# Main app
asc signing fetch --bundle-id com.example.myapp --profile-type IOS_APP_STORE --output ./signing/main
# Today widget extension
asc signing fetch --bundle-id com.example.myapp.widget --profile-type IOS_APP_STORE --output ./signing/widget
# Watch app
asc signing fetch --bundle-id com.example.myapp.watchapp --profile-type IOS_APP_STORE --output ./signing/watch
Verify App Association
Ensure the bundle ID matches your app:
asc signing fetch \
--app "YOUR_APP_ID" \
--bundle-id com.example.myapp \
--profile-type IOS_APP_STORE \
--output ./signing
The CLI will validate that the bundle ID is associated with the specified app.
Troubleshooting
”No certificates found”
Problem: No distribution certificates exist for the account.
Solution: Create a new certificate:
- Generate CSR in Keychain Access
- Create certificate:
asc certificates create --type IOS_DISTRIBUTION --csr-path ./CertificateSigningRequest.certSigningRequest
“Bundle ID not found”
Problem: The bundle identifier doesn’t exist in App Store Connect.
Solution: Register the bundle ID:
asc bundle-ids create --identifier com.example.myapp --name "My App" --platform IOS
“Device IDs required for development profiles”
Problem: Development profiles require registered devices.
Solution: Register devices and include their IDs:
# List device UDIDs
asc devices list --platform IOS --output json | jq '.data[] | {name: .attributes.name, udid: .attributes.udid}'
# Fetch with device IDs
asc signing fetch \
--bundle-id com.example.myapp \
--profile-type IOS_APP_DEVELOPMENT \
--device "DEVICE_ID1,DEVICE_ID2"
“Failed to create profile”
Problem: Profile creation failed due to missing prerequisites.
Solution: Verify requirements:
- Bundle ID exists
- Valid certificates exist
- For development: devices are registered
- Account has necessary permissions
Certificate Not Installing
Problem: Double-clicking the .cer file doesn’t import the certificate.
Solution: Use the security command:
security import signing/certificate.cer -k ~/Library/Keychains/login.keychain-db
Verify installation:
security find-certificate -c "Apple Distribution" -p ~/Library/Keychains/login.keychain-db
Best Practices
-
Automate certificate renewal: Set up alerts for expiring certificates (they expire after 1 year)
-
Use different certificates for different environments: Separate development and distribution certificates
-
Protect private keys: Never commit certificates or private keys to version control
-
Use CI/CD secrets: Store API keys and certificates as encrypted secrets in your CI/CD platform
-
Regenerate profiles after certificate renewal: When you renew certificates, regenerate all associated profiles
-
Keep device lists updated: Regularly add new test devices and remove old ones
-
Use
--create-missing in CI: Ensures profiles are created if they don’t exist
-
Clean up old profiles: Delete unused profiles to avoid confusion