Skip to content

Update auth logic #3789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 7, 2021
Merged

Update auth logic #3789

merged 3 commits into from
Oct 7, 2021

Conversation

yim-lee
Copy link
Contributor

@yim-lee yim-lee commented Oct 5, 2021

Motivation:
SwiftPM should support using credentials stored in keychain for binary
download and registry authentication.

Modifications:

  • Wire up KeychainAuthorizationProvider in SwiftTool. Add --no-keychain option which allows user to opt-out.
  • Update netrc logic to either:
    • Load from a user-defined .netrc file
    • Default to .netrc file found in current workspace (if any) and/or
      user's home directory.
  • Deprecate Workspace.Configuration.Netrc

rdar://83682028

@tomerd
Copy link
Contributor

tomerd commented Oct 5, 2021

haha, I also worked on some of this with #3790

happy to take yours and close mine

Motivation:
SwiftPM should support using credentials stored in keychain for binary
download and registry authentication.

Modifications:
- Wire up `KeychainAuthorizationProvider` in `SwiftTool`. Add `--no-keychain` option which allows user to opt-out.
- Update netrc logic to either:
  - Load from a user-defined `.netrc` file
  - Default to `.netrc` file found in current workspace (if any) and/or
    user's home directory.
- Deprecate `Workspace.Configuration.Netrc`

rdar://83682028
@yim-lee
Copy link
Contributor Author

yim-lee commented Oct 5, 2021

Rebased to include #3790 changes and resolved all review comments.

@yim-lee
Copy link
Contributor Author

yim-lee commented Oct 5, 2021

@swift-ci please smoke test


return providers.isEmpty ? .none : CompositeAuthorizationProvider(providers, observabilityScope: self.observabilityScope)
}

func getNetrcConfigFile() throws -> AbsolutePath? {
func getNetrcAuthorizationProviders() throws -> [NetrcAuthorizationProvider] {
Copy link
Contributor

@tomerd tomerd Oct 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my expectation as a user would be a single netrc file loaded, with the following priority:

  • custom one specified via cli flag
  • project local
  • home directory

@yim-lee @mattt did you have a different semantic in mind?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For .netrc files, I think that's a good option, yeah.

Alternatively, we could say:

  • If you specify a --netrc-path, use only that
  • Otherwise, consult project local (./.netrc) and fallback to the user shared (~/.netrc)

This approach would give us the convenience of cascading, while being able to keep the behavior you described (for example, if we only wanted to load the local or shared .netrc file, we could pass it as --netrc-file).

The only downside is that this is more complex, and lacking sufficient diagnostics, could make it difficult for the user to understand where credentials are coming from.

Copy link
Contributor

@tomerd tomerd Oct 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personally as a use I would expect the former (ie only load a single file, no fallback / merge with shared one). maybe we can investigate what other tools are doing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also cc @neonichu @abertelrud for opinions

Copy link
Contributor

@tomerd tomerd Oct 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like curl only supports single location, either one specified with a flag or ~/.netrc: https://everything.curl.dev/usingcurl/netrc#the-netrc-file-format

I wonder if this is a good policy for us to due to security reasons - so users don't want to accidentally check in the .netrc file

@robertlacroix @andyp-apple opinions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is a good policy for us to due to security reasons - so users don't want to accidentally check in the .netrc file

FWIW, we added .netrc to the default project template .gitignore file with #3511, which helps mitigate this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, we could say:

  • If you specify a --netrc-path, use only that
  • Otherwise, consult project local (./.netrc) and fallback to the user shared (~/.netrc)

This is my understanding of the expected behavior described in SE-0292 and what I think I've implemented in this PR. My assumption is that local netrc would not have as many credentials as the user one (if both files exist), so for a given URL if credentials is not found in local netrc then looking for it in user netrc sounds reasonable to me.

It sounds like based on @tomerd and @mattt's comments that a single netrc file is fine. If that's the case I will remove this part of the changes and reduce the PR to simply add keychain auth.

Copy link
Contributor

@tomerd tomerd Oct 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yim-lee yes what you did is per spec, and correct. my question is more conceptual: if we got the spec right or if that would surprise users. there is also the option of not supporting project local at all IMO. in any case, I will leave it to @mattt to decide as he is the proposal author, unless we hear from the security folks something stronger.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yim-lee @tomerd Since we have the spec from SE-0292 and this PR that implements the spec, I think we should go with that for now. If we find that this behavior is confusing or not what we want, we can amend this and update the spec / documentation in tandem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm

@testable import Commands
import SPMTestSupport
import TSCBasic
import XCTest

final class SwiftToolTests: XCTestCase {
func testNetrcLocations() throws {
func testNetrcAuthorizationProviders() throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<3

@tomerd
Copy link
Contributor

tomerd commented Oct 7, 2021

@yim-lee good to merge?

@tomerd tomerd merged commit 85189ac into swiftlang:main Oct 7, 2021
do {
let localPath = packageRoot.appending(component: ".netrc")
// make sure there isn't a user home one
try localFileSystem.removeFileTree(userHomePath)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests probably shouldn't touch user's .netrc file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants