This guide describes how to import new certificates and keys into your encrypted certificates repository using the SwiftlaneCLI certs add command.
-
Build the SwiftlaneCLI tool:
swift build
-
Have your encrypted certificates repository URL ready:
export CODESIGNING_CERTS_REPO_URL="git@github.com:myorg/encrypted-certs.git"
- Importing App Store Connect API Keys (.p8)
- Importing Code Signing Certificates (.p12)
- Verification
- Troubleshooting
- Security Notes
App Store Connect API keys are simple unencrypted .p8 files that can be imported directly.
CODESIGNING_CERTS_REPO_URL="git@github.com:myorg/encrypted-certs.git" \
.build/debug/SwiftlaneCLI certs add \
--cloned-repo-dir $(pwd)/tmp \
--log-level verbose \
~/Downloads/AuthKey_ABCDEFGHIK.p8- The
.p8file will be encrypted using your repository password (you'll be prompted to enter it) - The encrypted file will be committed to the repository
- The file will be stored at:
authKeys/AuthKey_ABCDEFGHIK.p8
Note: Use a strong password for your repository encryption. This password will be used to decrypt the files when you need to use them.
Code signing certificates (Development, Distribution, Developer ID Application, etc.) require a few additional steps because they are exported from Keychain as password-protected P12 files.
The process involves:
- Exporting the certificate and private key from Keychain as a
.p12file - Decrypting the P12 file to extract the certificate and private key
- Renaming the extracted files with meaningful names
- Importing the files into the encrypted repository
- Cleaning up the decrypted files (security-critical step)
- Open the Keychain Access application
- Select the My Certificates category from the sidebar
- Find the certificate you want to export
- Certificates with a private key will show a dropdown arrow ▶
- Click the arrow to verify the private key is present
- Right-click on the certificate and select Export "Certificate Name"
- Choose a location to save the
.p12file - Important: Enter a secure password when prompted
- This password encrypts the P12 file during export
- This is NOT the same password used for the encrypted certificates repository
- macOS requires a password for P12 export - files exported without a password will be corrupted
Important: Export one certificate+key pair at a time!
While Keychain Access allows you to select and export multiple certificates into a single .p12 file, DO NOT do this. The decryption script only supports extracting one certificate-key pair per P12 file. If you export multiple certificates together, only the first pair will be decrypted, and the rest will be lost.
Always export each certificate individually into separate .p12 files.
Result: You now have a .p12 file containing both the certificate and its private key.
Before importing into Swiftlane, you need to decrypt the P12 file to extract the certificate and private key separately.
./decrypt_p12_from_keychain.sh \
-f path/to/your/certandkey.p12 \
-k pem \
-x pem \
-o SIGN \
-v-f: Path to your P12 file-k pem: Output format for the private key (PEM format)-x pem: Output format for the certificate (PEM format)-o SIGN: Output directory (will be created if it doesn't exist)-v: Verbose output
The script will:
- Prompt you for the P12 password (the one you set during export)
- Extract the certificate and private key
- Create a
SIGNdirectory in your current working directory - Save the extracted files:
SIGN/ ├── extracted_private_key.pem └── extracted_certificate.crt
find SIGNExpected output:
SIGN/extracted_private_key.pem
SIGN/extracted_certificate.crt
Give the extracted files meaningful names to help identify them later:
mv SIGN/extracted_private_key.pem SIGN/my_DeveloperIDApplication.pem
mv SIGN/extracted_certificate.crt SIGN/my_DeveloperIDApplication.crtNaming suggestions:
- For Developer ID Application:
DeveloperIDApplication_YourName.pem/.crt - For Developer ID Installer:
DeveloperIDInstaller_YourName.pem/.crt - For iOS Distribution:
iOSDistribution_YourCompany.pem/.crt - For iOS Development:
iOSDevelopment_YourName.pem/.crt
Note: The filename is only for your reference. When these files are imported into the keychain later, the filename won't matter - the certificate's actual name comes from its internal metadata.
Now import all files in the SIGN directory into your encrypted certificates repository.
ls -al SIGNExpected output:
drwxr-xr-x 4 user staff 128 Nov 26 12:00 .
drwxr-xr-x 20 user staff 640 Nov 26 12:00 ..
-rw-r--r-- 1 user staff 1234 Nov 26 12:00 my_DeveloperIDApplication.crt
-rw-r--r-- 1 user staff 1679 Nov 26 12:00 my_DeveloperIDApplication.pem
CODESIGNING_CERTS_REPO_URL="git@github.com:myorg/encrypted-certs.git" \
.build/debug/SwiftlaneCLI certs add \
--cloned-repo-dir $(pwd)/tmp \
--log-level verbose \
SIGN/*- You'll be prompted to enter your repository encryption password
- All files in the SIGN directory will be encrypted
- The encrypted files will be committed to the repository
- The changes will be pushed to the remote repository
Look for these messages in the output:
[master 9dc601e] [swiftlane] Imported: my_DeveloperIDApplication.crt, my_DeveloperIDApplication.pem
Followed by:
git push --set-upstream origin HEAD
If you see these messages, everything went smoothly!
IMPORTANT: After successful import, you must delete the SIGN directory containing the unencrypted private keys and certificates.
rm -rf SIGNWhy this is critical:
- The SIGN directory contains your unencrypted private keys
- Leaving these files on disk is a security risk
- Once imported into the encrypted repository, these files are no longer needed
- Always verify the import was successful (check the git push output) before deleting
After importing, verify the files are in your repository:
- Navigate to your encrypted certificates repository on GitHub/GitLab/etc.
- You should see your newly added files:
- For
.p8keys:authKeys/AuthKey_ABCDEFGHIK.p8 - For certificates: The
.crtand.pemfiles in thecertsdirectory
- For
Important: The files in the repository will be encrypted. You won't be able to read their contents directly on GitHub - they can only be decrypted using your repository password.
- Check the verbose logs (
--log-level verbose) for detailed error messages
- Repository Password: Use a strong, unique password for your encrypted certificates repository. This password protects all certificates and keys stored in the repository.
- P12 Export Password: This is temporary and only used during the export/import process. It can be different from your repository password.
- Never commit unencrypted certificates: Always use the
SwiftlaneCLI certs addcommand to ensure files are encrypted before being committed. - Keep your private keys secure: The decrypted files in the
SIGNdirectory contain your private keys. Delete them after successful import.