#30186·fastlane

security cms -D imports certificates into the user's default keychain when parsing provisioning profiles

Author: lacostejCreated Sep 10, 2026Updated Sep 10, 2026

What happens

fastlane decodes provisioning profiles with security cms -D. As part of verifying the CMS signature, macOS imports the signing certificate into the default keychain. So parsing a profile silently adds certificates to the user's login keychain.

Evidence

Running fastlane's own test suite against a freshly created, empty keychain:

certificates in the keychain before: 0
certificates in the keychain after:  4

Three come from match/spec/importer_spec.rb decoding test.mobileprovision and test.provisionprofile, one from fastlane/spec/actions_specs/verify_build_spec.rb decoding an embedded profile.

It is easy to miss because it is idempotent: once the signer certificate is present, a second run adds nothing, so the count only changes on a machine that has not done it before.

The same is visible from the other direction. With no keychain at all, security cms -D fails with security: cert import failed: A default keychain could not be found, which names the import explicitly. With any keychain present, even an empty one, it succeeds.

Where

fastlane/lib/fastlane/actions/verify_build.rb:72
fastlane_core/lib/fastlane_core/provisioning_profile.rb:117
sigh/lib/sigh/local_manage.rb:137
sigh/lib/assets/resign.sh:372,488,667

Possible direction

provisioning_profile.rb already has a -k variant one line below the unqualified call:

ruby
decoded = `security cms -D -i "#{path}" 2> #{err}`                                    # 117
decoded = `security cms -D -i "#{path}" -k "#{keychain_path.shellescape}" 2> #{err}`  # 119

so the mechanism for directing the import at a chosen keychain already exists. It is used when keychain_path is given and skipped otherwise. Whether the right default is a temporary keychain, or simply documenting the behaviour, is a judgement call for the maintainers.

Not covered here

Whether this is intended. It may be an accepted cost of using security cms for decoding, in which case the issue is that it is undocumented.

Found while auditing the test suite for order dependence (#30184), where an isolated HOME made it visible.