#30216·fastlane

[tests] The spec suite writes credentials into the developer's real login keychain

Author: lacostejCreated Sep 12, 2026Updated Sep 12, 2026

What happens

Running the spec suite writes into the developer's real login keychain, and leaves things there. It is not a leak of test data into a scratch location; it is the same keychain the developer keeps their own credentials in.

Verified on a machine after ordinary suite runs:

$ security find-internet-password -s "match_https://github.com/fastlane/fastlane/tree/master/certificates"
0x00000007 <blob>="match_https://github.com/fastlane/fastlane/tree/master/certificates"
"cdat"<timedate>=... "20260912101127Z\000"

That timestamp is from a suite run, not from any use of fastlane. Three certificates are there too, all from match/spec/fixtures/:

iPhone Distribution: Felix Krause (439BBM9367)
Apple iPhone OS Provisioning Profile Signing
TestFixture

Why it reaches the real keychain

Two separate paths.

Passwords. match/spec/change_password_spec.rb:7 runs Match::ChangePassword.update with the storage faked but Encryption::OpenSSL left real. match/lib/match/change_password.rb:34-35 then calls:

ruby
encryption.clear_password
encryption.store_password(new_password)

which reach match/lib/match/encryption/openssl.rb:70,75:

ruby
Security::InternetPassword.add(server_name(self.keychain_name), "", password)
Security::InternetPassword.delete(server: server_name(self.keychain_name))

The security gem runs security add-internet-password … and security delete-internet-password … with no keychain argument (security-0.1.5/lib/security/password.rb:99,107), so both act on the session's default keychain regardless of what keychain_name says.

Certificates. fastlane_core/lib/fastlane_core/keychain_importer.rb:24 runs security import, and fastlane_core/lib/fastlane_core/provisioning_profile.rb:117,119 runs security cms -D -k. Both use bare backticks rather than Actions.sh, so the Helper.sh_enabled? gate that makes most shell-outs inert under test does not apply. Driven by the requires_security: true examples in match/spec/runner_spec.rb and by match/spec/importer_spec.rb.

A subprocess tracer over a full run recorded security executing for real from 39 distinct command/example pairs.

Why there is no isolation lever

HOME does not help. security add-internet-password with no -k resolves the default keychain through the session, not through a path, so pointing HOME elsewhere does not redirect it. rake test_isolated seeds a keychain under a throwaway HOME and that covers the -k-taking paths, but not the password ones.

MATCH_KEYCHAIN_NAME exists and defaults to login.keychain, but the password calls above never pass it down to security.

So this sits with the system clipboard (#30210) in the category of resources with no isolation lever at all: there is one default keychain per logged-in session, and the only fix is for the specs to stop reaching it.

Under the parallel split

Two workers holding match specs interleave on the same keychain rows — one adding an internet password while another deletes it.

There is also a worse failure mode already documented in internal/rakelib/isolated.rake: with no usable keychain, security puts up a modal dialog and waits. A worker in that state hangs rather than failing, which is indistinguishable from a slow worker.

Suggested fix

Stub rather than isolate, as with the clipboard.

  • match/spec/change_password_spec.rb — stub Match::Encryption::OpenSSL the way match/spec/runner_spec.rb:146 already does, or stub Security::InternetPassword the way match/spec/utils_spec.rb:12 does. Both patterns are already in the repo.
  • The requires_security: true examples — stub FastlaneCore::ProvisioningProfile.parse. The method does take an explicit keychain_path, so a per-worker keychain is expressible, but no spec uses it today and stubbing is the smaller change.

Notes

Pre-existing, not introduced by the parallel split; the split makes it contend rather than merely litter. Related: #30210 is the same shape with the pasteboard, and #30186 covers security cms -D importing certificates as a side effect of parsing profiles.