Skip to content

Discussion for Credential Persistence integration #330

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

Closed
alerickson opened this issue Jan 25, 2021 · 7 comments
Closed

Discussion for Credential Persistence integration #330

alerickson opened this issue Jan 25, 2021 · 7 comments
Labels
Milestone

Comments

@alerickson
Copy link
Member

alerickson commented Jan 25, 2021

Proposal to use SecretManagement module to add credential persistence to PSGet v3. (blog post here).

Beginning initial design discussion and investigations in this issue.
cc: @PaulHigin

@SydneyhSmith
Copy link
Collaborator

I wanted to share some of my initial thoughts on this feature...these are just initial thoughts--- totally open to
other ideas/lots of feedback 😄

High Level Scenario

I want to be able to provide a credential when I register repositiries so that
I can install (or find/update) a module from a repository which requires authentication,
without needing to provide the credential at install time.

In other words when I install a module using PowerShellGet I want it to know:

  1. Whether or not authentication is required
  2. Where the credential is stored
  3. How to pull and provide the credential to the repository

Considerations

PowerShellGet does not have a mechanism for securely storing credentials,
building and maintaining a credential store for this purpose is a non-goal of
this feature.

High Level Design proposal

  • Add an -Authentication parameter to the Register-PSResourceRepository
  • Add an authentication dimension to the PSRespositoryItem object
  • The -Authentication parameter will take a hashtable which specifies the vault and secret where the credential is stored
  • This format indicates that the user is utilizing the SecretManagement interface with any registered vault of their choosing
  • SecretStore may be recommended as a vault but users should be able to use any vault they choose
  • SecretManagement supports 5 secret types: byte[], string, SecureString, PSCredential, Hashtable
  • Based on user feedback we could also potentially support an indication using the -Authenication parameter that interactive credentials will be provided (perhaps "Interactive")
  • Detailed error messaging to indicate why authentication failed (SecretManagement wasnt installed, no vault was available, the vault couldnt be reached etc.)
  • When Intall-PSResource is called and the prioritized repository is determined, a check will also be made to the Authentication property
  • How exactly the credential is passed to various repositories is a bit of a mystery to me at the moment 😄
  • Since not all repositories requires authentication (principally PSGallery) PowerShellGet will not take a dependency
    on SecretManagement

Demo.txt

Register-PSResourceRepository myRepo -URL path/to/my/repo -Authentication @{vault = mySecretStore, secret = myRepoCred}
Install-PSResouce -Name myModule -Repository myRepo

Open questions

  • Are there some repositories that require interactive auth?

cc: @alerickson

@PaulHigin
Copy link
Contributor

This looks good. But I wonder why not just use SecretManagement outside PSGet?

Install-PSResource -Name myModule -Repository myRepo -ProxyCredential (Get-Secret -Name myRepoCred -Vault mySecretStore)

But if we want to integrate a credential store more tightly with PSGet, another option would be to just integrate the Microsoft.PowerShell.SecretStore module directly (without SecretManagement). This would remove the vault choice and always store credentials on the local machine with SecretStore. No vault options, but also less complex.

# Registers myRepo and stores credential in SecretStore for repo name 'myRepo'
Register-PSResourceRepository myRepo -URL path/to/my/repo -Credential $credential
Install-PSResource -Name myModule -Repository myRepo

@cansuerdogan
Copy link
Contributor

We are very excited about the possibility of this feature!

I would like to provide two user cases that highlight how this feature would help my team:

Context:

Currently our Artifactory instance is set up to allow anonymous authentication from a set of approved IP addresses. This allows us to not pass in any credentials when we are registering our Powershell repository or pulling down packages on internally managed Jenkins agent VMs or local developer machines. However, Artifactory's anonymous auth configuration is limiting us because we cannot easily move our CI workflows to Github Actions or Azure DevOps pipelines due to the whitelisting requirement. We would like to get away from it while ensuring our packages are still only accessible internally. This feature would enable us to enforce auth for our Powershell repositories without having to update all of our build scripts to provide credentials for package handling.

Build infrastructure scenario:

As I mentioned, we have our own Jenkins instances and we prep our agent VMs via Packer image creation and running Chef post-provision. As part of this configuration, we are registering our Powershell repositories on the VM, in the user profile that Jenkins masters are using for establishing connections to their agents. All builds, then, proceed to run their scripts as these users on agents and no further authentication for Powershell packages is required with this setup. When we need to roll these VM user account passwords as part of our security practices, it is sufficient to update the Jenkins credential and re-establish the connection.
If we were to switch to forced auth today, not only we would need to pass in credentials during PSRepository registration, but also with every Module command, which would require a lot of changes in our build scripts. With this feature though, switching auth would only have the minimal impact of updating repository registration during agent setup. When it comes to supporting SecretManagement vs SecretStore, especially on CI infrastructure, having access to Azure Key Vault for these credentials would be immensely helpful for password rolling, because then we wouldn't need to update anything on the VM. We would just continue to read the new value from a key vault without any interruptions or maintenance.

Local developer scenario:

The same conditions apply to local developer machines and workflows. Because currently there isn't a way to store PowerShellGet credentials locally, every time a developer needs to pull down a module, they would get prompted with a credentials popup and this could be disruptive. Whereas, this feature would give them the ability to set it up once and forget about it, until maybe they have to update their password.

@SteveL-MSFT
Copy link
Member

I think it makes sense to have some integration between PowerShellGet and SecretManagement so that the user doesn't have to explicitly pass credentials or know to pass which credentials for a specific repository.

I think it's ok to require pre-provisioning a vault with SecretManagement with the secret needed to authenticate, and then at PSRepository registration time inform PowerShellGet which secret to get from SecretManagement (secret name and vault) so it's implicit for any request to that PSRepository.

Since most users may not need this capability, the dependency on SecretManagement should be a soft dependency where if they try to use the feature, the error message should direct them to a doc page explaining how to make it work rather than requiring install as a dependent module.

@fsackur
Copy link
Contributor

fsackur commented Aug 11, 2021

I am in favour of avoiding an explicit hard requirement on another module when only a minority of use cases need it. We added Az modules into our dependency tree too eagerly, and now all my terminals incur a 20-second lag :-/

@cansuerdogan
Copy link
Contributor

I've opened a pull request that follows the design proposal. The implementation only introduces a soft dependency on SecretManagement.

  • Everything works as it does now if you are not registering repositories with -Authentication.
  • It is assumed that the secret vault setup has already been done prior to invoking PowerShellGet. Otherwise, it throws the same SecretManagement errors if you are trying to use a vault that does not exist, or if SecretManagement module is not available, etc.

Looking forward to getting your feedback!

@PaulHigin
Copy link
Contributor

I started looking at the PR and then this associated Issue. I feel this is a good start but am not sure if this is the correct design yet. For example I feel the parameter name should not be -Authentication but maybe be -Credential or -CredentialInfo. 'Authentication' usually specifies an authentication type, not authentication credentials.

Also I feel we need to spend time thinking about error messages if/when SecretManagement is not installed, not configured, or the secret information is not available. My concern is that SecretManagement error messages will be confusing to users, since the persistence mechanism is kind of buried in PowerShellGet. We may want to test and/or catch errors and display better messages.

Also it may make more sense to store/retrieve authentication information as PSCredential since it encompasses username/password. But would this be too limiting? Would later repositories have different authentication mechanisms, and if so is there a way we can support them?

I will continue my PR review and feel this is a great feature, but we will probably have to make some design user experience changes.

In the future we will provide more written guidelines on how to propose/discuss new features, get acceptance, and create a implementing PR.

/cc @StevenBucher98

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

No branches or pull requests

6 participants