swift-package-manager: Fails to save credentials to keychain when using login command with token option
Description
Hi,
When attempting to execute the package-registry login
command using the token
option, the credentials fail to save to the keychain resulting in a -25308
error.
Since Xcode only supports registry credentials saved in Keychain, using netrc
to authorize does not work either (as mentioned in this issue discussion).
This makes it impossible to do things like xcodebuild -resolvePackageDependencies
in a CI pipeline. Please note suggested solutions like this one and this one assume access to the Keychain UI which is not available in a CI pipeline/context (e.g., Creating a build using Xcode Cloud).
Thank you in advance for your help!
Expected behavior
The credentials should be persisted in the keychain without error.
Actual behavior
When executing the command mentioned, the following error occurs:
Failed to save credentials for \‘https://my_domain.d.codeartifact.the_region.amazonaws.com/[](https://my_domain.d.codeartifact.the_region.amazonaws.com/)’ to keychain: status -25308”
Steps to reproduce
CI Pipeline example 1 - Amazon EC2 running macOS 13.5.2, Xcode 15.0:
(Assumes AWS CLI is installed and configured)
- Get authorization token
export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain my_domain --domain-owner my_domain_owner_id --region my_region --query authorizationToken --output text --profile my_profile`
- Set registry
swift package-registry set --global https://my_domain.d.codeartifact.my_region.amazonaws.com/swift/my_repo/
- Log in to registry
swift package-registry login https://my_domain.d.codeartifact.my_region.amazonaws.com/swift/my_repo/login --token ${CODEARTIFACT_AUTH_TOKEN}
- Login is successful (but credentials are not saved to keychain)
CI Pipeline example 2 - Xcode Cloud running macOS 13.5.2, Xcode 15.1:
(occurs post clone of repo as part of ci_post_clone.sh
script)
- Install AWS CLI and configure
- Get authorization token
export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain my_domain --domain-owner my_domain_owner_id --region my_region --query authorizationToken --output text --profile my_profile`
- Set registry
swift package-registry set --global https://my_domain.d.codeartifact.my_region.amazonaws.com/swift/my_repo/
- Log in to registry
swift package-registry login https://my_domain.d.codeartifact.my_region.amazonaws.com/swift/my_repo/login --token ${CODEARTIFACT_AUTH_TOKEN}
- Login is successful (but credentials are not saved to keychain)
Swift Package Manager version/commit hash
Swift Package Manager - Swift 5.9.0
Swift & OS version (output of swift --version ; uname -a
)
CI Pipeline example 1 - Amazon EC2 running macOS 13.5.2, Xcode 15.0:
swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)
Target: arm64-apple-macosx13.0
Darwin github-runner-macos-02 22.6.0 Darwin Kernel Version 22.6.0: Wed Jul 5 22:22:52 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T8103 arm64
CI Pipeline example 2 - Xcode Cloud running macOS 13.5.2, Xcode 15.1:
swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
Target: x86_64-apple-macosx13.0
Darwin e1b43c42-7e4f-47a9-9e31-f99a59f26be5-f46ffd7c-f6l9d-vm.podset-vms.dt-skywagon-workers-prod-vm.svc.kube.us-west-3f.k8s.cloud.apple.com 22.6.0 Darwin Kernel Version 22.6.0: Wed Jul 5 22:21:56 PDT 2023; root:xnu-8796.141.3~6/RELEASE_X86_64 x86_64
About this issue
- Original URL
- State: open
- Created 6 months ago
- Comments: 42 (4 by maintainers)
@sebsto – I actually was able to get it working via
security
with a minor tweak 🎉TL;DR, instead of just including
/usr/bin/xcodebuild
as a preapproved application (using-T
) when re-adding the password (viasecurity add-internet-password
), I saw that my CI machine (github actions) was using a different xcodebuild (Applications/Xcode_15.0.1.app/Contents/Developer/usr/bin/xcodebuild
), so I included that also./usr/bin/xcodebuild
, I saw that my CI machine (github actions) was using a different xcodebuild (Applications/Xcode_15.0.1.app/Contents/Developer/usr/bin/xcodebuild
), so I included that also@sebsto tried your approach and it worked! Thank you both again (@toheebster) for your efforts!
My only concern is my lack of understanding about all the unrelated items in the login keychain that get deleted (certs, app passwords, etc.). Wondering if I should/can export/move those from/to the keychain I’m creating.
I still need to test this approach in the CI pipeline using Xcode Cloud servers. Will follow up about that shortly.
Thank @toheebster - you made it - I confirm this works.
The main two differences with what I tried
you delete the item created by SwiftPM first. If you don’t a second item is created in the keychain, despite the
-U
(update) flag. This might cause confusion to application consuming the token as we don’t know which item they picked up.The
security set-internet-password-partition-list
is required. I should have known. I use that to import signing keys.I just tested end to end with a slightly different script, but this is a matter of personal taste 😃
Prepare the keychain
Get CodeArtifact token and repo
Login (this creates the entry in the keychain
Delete and recreate the entry, as @toheebster said 😃
@Joel-Bell-okcupid now that we have one workaround (and two sets of script for your convenience) - can you test on your side and report back ?
@toheebster I told you I spent 4 hours last night on that. Of course, I verified. Using the
security find-internet-password -w
option on a laptop + using thediff
command + copying over the working keychain from my machine to EC2 Mac … all failedYou’re redoing all my thought process from last night. Please try it yourself. I gave up after 4 hours. I will try the programmatic approach in SwiftPM source code instead.