jenkinsci / azure-keyvault-plugin

Jenkins plugin for Azure Keyvault
https://plugins.jenkins.io/azure-keyvault/
MIT License
14 stars 21 forks source link

Using multiple key vaults #70

Open MikalaiHryniuk opened 3 years ago

MikalaiHryniuk commented 3 years ago

Your checklist for this issue

Description

It would be great to be able to connect multiple key vaults. Is this something that is already supported and what I missed in the documentation?

timja commented 3 years ago

It depends on what you want to do,

In pipeline it's supported there's a key vault url override you can use.

The credential provider currently just supports one vault

MikalaiHryniuk commented 3 years ago

@timja In my case, I have a lot of values ​​in three key vaults and getting these values ​​describing each in the pipeline is a very big problem.

timja commented 3 years ago

We have something fairly crazy here that allows it:

https://github.com/hmcts/cnp-jenkins-library/blob/master/vars/withTeamSecrets.groovy

https://github.com/hmcts/draft-store/blob/master/Jenkinsfile_CNP#L13-L29

Does that help? or are you after something else?

MikalaiHryniuk commented 3 years ago

Maybe this will help. Thank. Is there a chance that you will add the ability to use multiple vaults in the future?

timja commented 3 years ago

Possibly based on demand, how would you see it working?

Are you looking for it with the credential provider? possibly with different credentials per vault?

I think it would have to be namespaced then,

something like myteam-dev/my-secret

MikalaiHryniuk commented 3 years ago

I think I'm not the only one with this issue. And yes, in my opinion the most logical solution would be with separate credentials for each vault. It is very bad from a security point of view to store keys for all environments in one vault.

timja commented 3 years ago

Via withAzureKeyvault you can access as many vaults as you want, but it requires nesting which isn't ideal.

Are you wanting this to be easier to use in withAzureKeyvault or using the credential provider where you just go withCredentials([string(credentialsId: 'github-api-token', variable: 'GITHUB_API_TOKEN')]) { ?

MikalaiHryniuk commented 3 years ago

For us the best solution is to connect via configuration-as-code plugin. If we could just connect a second key vault, as I've shown below, that would be great. All other methods do not suit us very much

unclassified:
  azureKeyVault:
    credentialID: "azure_credentials"
    keyVaultURL: https://some.vault.azure.net/
  azureKeyVault:
    credentialID: "azure_credentials2"
    keyVaultURL: https://some2.vault.azure.net/
timja commented 3 years ago

Sure makes sense.

FYI @chriskilding similar to your AWS issue

MikalaiHryniuk commented 3 years ago

@timja Is there a chance that you will implement such a solution within a couple of months, or is there no chance?

timja commented 3 years ago

There's a chance but no plans right now,

If someone else were to contribute it then I can spare the time to review, guide and test it.

chriskilding commented 3 years ago

Yep we've got the same issue in the AWS Secrets Manager: https://github.com/jenkinsci/aws-secrets-manager-credentials-provider-plugin/issues/70

My plan was to introduce some kind of optional namespace argument to the credentials API plugin. This would allow providers, including the Azure one, to surface credentials stored in different vaults or accounts alongside each other, without name clashes.

Starter for ten is something like this in the Jenkinsfile (in your case the namespace would be a vault name instead of an account ID):

pipeline {
    agent any
    stages {
        stage('Deploy to staging') {
            environment {
                API_KEY = credentials('api-key', namespace: '1111111111')
            }
            steps {
                sh 'curl -X POST -u "foo:$API_KEY" https://example.com'
            }
        }
        stage('Deploy to production') {
            environment {
                API_KEY = credentials('api-key', namespace: '2222222222')
            }
            steps {
                sh 'curl -X POST -u "foo:$API_KEY" https://example.com'
            }
        }
    }
}

As you suggest we'd then also need a way to configure namespaces on the credential providers in the casc.yaml.

The idea needs work but, with more discussion, could be made viable.

timja commented 3 years ago

My suggestion without the 'namespace' feature support is to just prefix it with the vault name / account id in AWS and then a separator like a /, e.g. teamvault/my-secret

bashkiby commented 3 years ago

It will be very useful for me also

chriskilding commented 3 years ago

Does Azure have a notion of / separators within secret names to create a hierarchy?

For example can you have things like

AWS does have this, and that's what complicates just adding the account ID as a prefix. The plugin won't know which bit of the combined name is an account ID and what's part of the hierarchy.

timja commented 3 years ago

No azure has separate ‘vaults’ for that