Skip to main content
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:
  1. Resolves your bundle ID
  2. Finds matching certificates
  3. Locates or creates provisioning profiles
  4. 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

1

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"
2

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
3

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
4

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
5

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

asc certificates list

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:
  1. Generate CSR in Keychain Access
  2. 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

  1. Automate certificate renewal: Set up alerts for expiring certificates (they expire after 1 year)
  2. Use different certificates for different environments: Separate development and distribution certificates
  3. Protect private keys: Never commit certificates or private keys to version control
  4. Use CI/CD secrets: Store API keys and certificates as encrypted secrets in your CI/CD platform
  5. Regenerate profiles after certificate renewal: When you renew certificates, regenerate all associated profiles
  6. Keep device lists updated: Regularly add new test devices and remove old ones
  7. Use --create-missing in CI: Ensures profiles are created if they don’t exist
  8. Clean up old profiles: Delete unused profiles to avoid confusion