[tests] The spec suite writes credentials into the developer's real login keychain
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
TestFixtureWhy 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:
encryption.clear_password
encryption.store_password(new_password)which reach match/lib/match/encryption/openssl.rb:70,75:
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— stubMatch::Encryption::OpenSSLthe waymatch/spec/runner_spec.rb:146already does, or stubSecurity::InternetPasswordthe waymatch/spec/utils_spec.rb:12does. Both patterns are already in the repo.- The
requires_security: trueexamples — stubFastlaneCore::ProvisioningProfile.parse. The method does take an explicitkeychain_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.
Source: fastlane/fastlane