-
New Feature
-
Resolution: Fixed
-
Minor
-
None
-
-
credentials-2.3.0
As a pipeline author, suppose I have a pipeline that performs a deployment action that requires credentials from Jenkins. A naive approach might be to add my credentials to the global Jenkins credential store (call it deployKey as its id); then I can reference it in my pipeline later like so:
node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: 'deployKey', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } }
But then I want to make my pipeline more secure. One option I might have is to have a dedicated Jenkins instance for running deployments. This is a large maintenance burden (e.g., trusted.ci.j.io versus ci.j.io), so digging deeper into Jenkins' existing features, I find user-scoped credentials. I can simply use credentials attached to my user account instead of Jenkins itself, though in order for my pipeline to recognize and use these credentials, I find that I must make them parameterized to the build itself so that I can select my credentials upon starting a build (there's an alternative option using the Authorize Project plugin, but this plugin is not widely used). A neat side-effect of this functionality is that other users can also deploy using the same pipeline but with their own user-scoped credentials. This can also allow me the flexibility of using a default global credential and allowing users to override that specifically for a pipeline run.
Thus, I modify my pipeline to add a build parameter for the deploy credentials as well as using a modified syntax in withCredentials to indicate that the credentialId parameter being provided is in fact a build parameter name and not the actual credential id. Combined, we get the following updated pipeline:
properties([parameters([credentials(credentialType: 'com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials', name: 'deployKey', required: true)])]) node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: '${deployKey}', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } }
Notice how we need to use a special syntax: credentialsId: '${deployKey}'. This syntax is misleading because it can be easily confused with the similar but not equivalent GString syntax: credentialsId: "${deployKey}". In fact, this latter syntax would never work for a user-scoped credential because user-scoped credentials are currently only looked up if the credential id is provided using the former template syntax.
What I am proposing we change here is to make credential parameters referenced by name take precedent over a globally-scoped credential with an id of the same name as the parameter name itself. Thus, we could update the above pipeline using this feature to be a little simpler:
properties([parameters([credentials(credentialType: 'com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials', name: 'deployKey', required: true)])]) node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: 'deployKey', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } }
The beauty of this approach is that it allows me to go from the first pipeline to the third pipeline simply by updating my build to add a credential parameter with the same name as the credential id I was using before that I want to migrate to a user account. I don't even have to touch the rest of the pipeline!
This issue relates to JENKINS-47699 in that it's a useful point to help support that feature.
- relates to
-
JENKINS-44772 User Scoped credentials are not used by the "withCredentials" pipeline step
-
- Open
-
-
JENKINS-38963 User-scoped credentials cannot be looked up in pipeline
-
- Resolved
-
-
JENKINS-44774 User Scoped credentials don't appear in credentials drop down lists
-
- Resolved
-
-
JENKINS-47699 Cannot use user-scoped credentials from pipeline input step parameters
-
- Resolved
-
-
JENKINS-44773 User Scoped credentials are not used by the "git" pipeline step
-
- Closed
-
-
JENKINS-47864 Allow to select User Scope Credentials
-
- Resolved
-
[JENKINS-58170] Allow credential parameters to shadow credential ids in lookup
Status | Original: Open [ 1 ] | New: In Progress [ 3 ] |
Status | Original: In Progress [ 3 ] | New: In Review [ 10005 ] |
Description |
Original:
As a pipeline author, suppose I have a pipeline that performs a deployment action that requires credentials from Jenkins. A naive approach might be to add my credentials to the global Jenkins credential store (call it {{deployKey}} as its id); then I can reference it in my pipeline later like so: {code:java} node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: 'deployKey', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } } {code} But then I want to make my pipeline more secure. One option I might have is to have a dedicated Jenkins instance for running deployments. This is a _large_ maintenance burden (e.g., trusted.ci.j.io versus ci.j.io), so digging deeper into Jenkins' existing features, I find user-scoped credentials. I can simply use credentials attached to my user account instead of Jenkins itself, though in order for my pipeline to recognize and use these credentials, I find that I must make them parameterized to the build itself so that I can select my credentials upon starting a build (there's an alternative option using the Authorize Project plugin, but this plugin is not widely used). A neat side-effect of this functionality is that other users can also deploy using the same pipeline but with their own user-scoped credentials. This can also allow me the flexibility of using a default global credential and allowing users to override that specifically for a pipeline run. Thus, I modify my pipeline to add a build parameter for the deploy credentials as well as using a modified syntax in {{withCredentials}} to indicate that the {{credentialId}} parameter being provided is in fact a build parameter name and not the actual credential id. Combined, we get the following updated pipeline: {code:java} properties([parameters([credentials(credentialType: 'com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials', name: 'deployKey', required: true)])]) node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: '${deployKey}', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } } {code} Notice how we need to use a special syntax: {{credentialsId: '${deployKey}'}}. This syntax is misleading because it can be easily confused with the similar but not equivalent GString syntax: {{credentialsId: "${deployKey}"}}. In fact, this latter syntax would never work for a user-scoped credential because user-scoped credentials are currently only looked up if the credential id is provided using that template syntax. What I am proposing we change here is to make credential parameters referenced by name take precedent over a globally-scoped credential with an id of the same name as the parameter name itself. Thus, we could update the above pipeline using this feature to be a little simpler: {code:java} properties([parameters([credentials(credentialType: 'com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials', name: 'deployKey', required: true)])]) node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: 'deployKey', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } } {code} The beauty of this approach is that it allows me to go from the first pipeline to the third pipeline simply by updating my build to add a credential parameter with the same name as the credential id I was using before that I want to migrate to a user account. I don't even have to touch the rest of the pipeline! This issue relates to |
New:
As a pipeline author, suppose I have a pipeline that performs a deployment action that requires credentials from Jenkins. A naive approach might be to add my credentials to the global Jenkins credential store (call it {{deployKey}} as its id); then I can reference it in my pipeline later like so: {code:java} node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: 'deployKey', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } } {code} But then I want to make my pipeline more secure. One option I might have is to have a dedicated Jenkins instance for running deployments. This is a _large_ maintenance burden (e.g., trusted.ci.j.io versus ci.j.io), so digging deeper into Jenkins' existing features, I find user-scoped credentials. I can simply use credentials attached to my user account instead of Jenkins itself, though in order for my pipeline to recognize and use these credentials, I find that I must make them parameterized to the build itself so that I can select my credentials upon starting a build (there's an alternative option using the Authorize Project plugin, but this plugin is not widely used). A neat side-effect of this functionality is that other users can also deploy using the same pipeline but with their own user-scoped credentials. This can also allow me the flexibility of using a default global credential and allowing users to override that specifically for a pipeline run. Thus, I modify my pipeline to add a build parameter for the deploy credentials as well as using a modified syntax in {{withCredentials}} to indicate that the {{credentialId}} parameter being provided is in fact a build parameter name and not the actual credential id. Combined, we get the following updated pipeline: {code:java} properties([parameters([credentials(credentialType: 'com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials', name: 'deployKey', required: true)])]) node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: '${deployKey}', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } } {code} Notice how we need to use a special syntax: {{credentialsId: '${deployKey}'}}. This syntax is misleading because it can be easily confused with the similar but not equivalent GString syntax: {{credentialsId: "${deployKey}"}}. In fact, this latter syntax would never work for a user-scoped credential because user-scoped credentials are currently only looked up if the credential id is provided using the former template syntax. What I am proposing we change here is to make credential parameters referenced by name take precedent over a globally-scoped credential with an id of the same name as the parameter name itself. Thus, we could update the above pipeline using this feature to be a little simpler: {code:java} properties([parameters([credentials(credentialType: 'com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials', name: 'deployKey', required: true)])]) node { // ... stage('Deploy') { withCredentials([usernameColonPassword(credentialsId: 'deployKey', variable: 'DEPLOY_CREDENTIALS')]) { sh 'curl -u "${DEPLOY_CREDENTIALS}" ...' } } } {code} The beauty of this approach is that it allows me to go from the first pipeline to the third pipeline simply by updating my build to add a credential parameter with the same name as the credential id I was using before that I want to migrate to a user account. I don't even have to touch the rest of the pipeline! This issue relates to |
Link | New: This issue relates to JENKINS-44772 [ JENKINS-44772 ] |
Link |
New:
This issue relates to |
Link |
New:
This issue relates to |
Link |
New:
This issue relates to |
Link |
New:
This issue relates to |
Link |
New:
This issue relates to |
Resolution | New: Fixed [ 1 ] | |
Status | Original: In Review [ 10005 ] | New: Fixed but Unreleased [ 10203 ] |