From f8714ca061a0ac639c3e20d0a90741f9d393b7fe Mon Sep 17 00:00:00 2001 From: MikeK968 <148596801+MikeK968@users.noreply.github.com> Date: Tue, 5 May 2026 21:55:03 -0500 Subject: [PATCH 1/2] =?UTF-8?q?[build-tools]=20Fix=20iOS=20local=20build?= =?UTF-8?q?=20on=20macOS=20Tahoe=20=E2=80=94=20drop=20-v=20from=20find-ide?= =?UTF-8?q?ntity=20in=20findIdentitiesByTeamId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Keychain.findIdentitiesByTeamId` runs `security find-identity -v -s "()" ` to verify that the dist cert was imported into the freshly-created build keychain. The `-v` ("valid identities only") flag requires the full trust chain (dist cert -> Apple WWDR Intermediate -> Apple Root CA) to resolve from the keychain(s) in the search list. The build keychain only holds the cert + private key; Apple Root CA lives in /Library/Keychains/System.keychain. `security find-identity` does not aggregate trust resolution across keychains passed as positional args โ€” only `security list-keychains -s` does, and that's session-wide and would mutate the user's environment. On macOS 26 (Tahoe), this caused `find-identity -v` to return 0 identities even when the cert+key were correctly imported, falsely tripping `ensureCertificateImported` with "Distribution certificate ... hasn't been imported successfully". Dropping `-v` fixes the presence check across macOS versions. Codesign performs its own trust resolution downstream via Security.framework (which does aggregate across keychains), so signing still succeeds. Existing integration test `packages/build-tools/src/ios/credentials/__integration-tests__/keychain.test.ios.ts` ("shouldn't throw any error if the certificate has been imported successfully") covers this scenario and now passes on Tahoe. Closes #3678 --- CHANGELOG.md | 2 ++ .../build-tools/src/ios/credentials/keychain.ts | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f9a5c3f72..ba5afb60c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ This is the log of notable changes to EAS CLI and related packages. ### ๐Ÿ› Bug fixes +- [build-tools] Fix `eas build --local` for iOS on macOS 26 (Tahoe) where `Keychain.findIdentitiesByTeamId` falsely reported the dist certificate as not imported. The `-v` flag on `security find-identity` requires the full trust chain to resolve from the build keychain alone, but the build keychain only holds the cert + private key โ€” Apple Root CA lives in `/Library/Keychains/System.keychain` and `find-identity` does not aggregate trust resolution across keychains. Dropped `-v`; presence check now works across macOS versions and codesign continues to resolve trust downstream via `Security.framework`. ([#TODO](https://github.com/expo/eas-cli/pull/TODO) by [@kearnsm293-afk](https://github.com/kearnsm293-afk)) + ### ๐Ÿงน Chores ## [18.11.0](https://github.com/expo/eas-cli/releases/tag/v18.11.0) - 2026-05-05 diff --git a/packages/build-tools/src/ios/credentials/keychain.ts b/packages/build-tools/src/ios/credentials/keychain.ts index b9fb807389..47b95fa5fc 100644 --- a/packages/build-tools/src/ios/credentials/keychain.ts +++ b/packages/build-tools/src/ios/credentials/keychain.ts @@ -97,9 +97,23 @@ export default class Keychain { } private async findIdentitiesByTeamId(teamId: string): Promise { + // Note: no `-v` flag. `-v` ("valid identities only") requires the full + // trust chain (dist cert -> Apple WWDR Intermediate -> Apple Root CA) to + // resolve from the keychain(s) in the search list. The build keychain + // created above only holds the dist cert + private key; Apple Root CA + // lives in /Library/Keychains/System.keychain. `security find-identity` + // does not aggregate trust resolution across keychains passed as + // positional args (only `security list-keychains -s` does, and that's + // session-wide and undesirable). On macOS 26 (Tahoe), this caused + // `find-identity -v -s "()" ` to return 0 + // identities even when the cert+key were correctly imported, falsely + // tripping `ensureCertificateImported`. Without `-v`, the presence + // check works correctly across macOS versions; codesign performs its + // own trust resolution downstream via Security.framework (which does + // aggregate across keychains), so signing still succeeds. const { output } = await spawn( 'security', - ['find-identity', '-v', '-s', `(${teamId})`, this.keychainPath], + ['find-identity', '-s', `(${teamId})`, this.keychainPath], { stdio: 'pipe', } From 97189a0baa20ef8fb3e5b489be354e450e951cd9 Mon Sep 17 00:00:00 2001 From: MikeK968 <148596801+MikeK968@users.noreply.github.com> Date: Tue, 5 May 2026 21:55:47 -0500 Subject: [PATCH 2/2] Update CHANGELOG.md with real PR number (#3679) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba5afb60c7..892d8d7fff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ This is the log of notable changes to EAS CLI and related packages. ### ๐Ÿ› Bug fixes -- [build-tools] Fix `eas build --local` for iOS on macOS 26 (Tahoe) where `Keychain.findIdentitiesByTeamId` falsely reported the dist certificate as not imported. The `-v` flag on `security find-identity` requires the full trust chain to resolve from the build keychain alone, but the build keychain only holds the cert + private key โ€” Apple Root CA lives in `/Library/Keychains/System.keychain` and `find-identity` does not aggregate trust resolution across keychains. Dropped `-v`; presence check now works across macOS versions and codesign continues to resolve trust downstream via `Security.framework`. ([#TODO](https://github.com/expo/eas-cli/pull/TODO) by [@kearnsm293-afk](https://github.com/kearnsm293-afk)) +- [build-tools] Fix `eas build --local` for iOS on macOS 26 (Tahoe) where `Keychain.findIdentitiesByTeamId` falsely reported the dist certificate as not imported. The `-v` flag on `security find-identity` requires the full trust chain to resolve from the build keychain alone, but the build keychain only holds the cert + private key โ€” Apple Root CA lives in `/Library/Keychains/System.keychain` and `find-identity` does not aggregate trust resolution across keychains. Dropped `-v`; presence check now works across macOS versions and codesign continues to resolve trust downstream via `Security.framework`. ([#3679](https://github.com/expo/eas-cli/pull/3679) by [@kearnsm293-afk](https://github.com/kearnsm293-afk)) ### ๐Ÿงน Chores