Documentation Index
Fetch the complete documentation index at: https://docs.asccli.sh/llms.txt
Use this file to discover all available pages before exploring further.
Code Signing
Manage signing certificates and provisioning profiles for app distribution
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 --paginate
Register development devices (for development profiles)
For development and ad-hoc profiles, register test devices:asc devices register \
--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 \
--certificate-type IOS_DISTRIBUTION \
--csr ./CertificateSigningRequest.certSigningRequest
List existing certificates:asc certificates list --certificate-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 --certificate-type IOS_DISTRIBUTION
asc certificates list --certificate-type IOS_DEVELOPMENT
asc certificates list --certificate-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 revoke --id "CERTIFICATE_ID" --confirm
Provisioning Profile Management
List Profiles
asc profiles list --profile-type IOS_APP_STORE
Get Profile Details
asc profiles view --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/rorkai/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/rorkai/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 --certificate-type IOS_DISTRIBUTION --csr ./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