User credentials in a Jenkins pipeline
The Credentials User Guide implies you can use user credentials. These are credentials that are owned and managed by a user instead of the administrator or the owner of a folder.
The guide explains how to use them with Freestyle jobs (classic Jenkins jobs) but not how to use them with the newer declarative pipeline jobs.
In this post, I’ll show you how to:
- Set up a job to ask for credentials when triggered.
- Allow users to provide their user credentials as a parameter.
- Configure the pipeline job to use the passed in credentials.
Setup Jenkins
As a normal user you shouldn’t have to worry about this part. If the steps below don’t work, then you may have to bring this to the attention of your Jenkins administrator.
To use user credentials the user kicking off the build needs to have the
Credentials/UseOwn
permission.
By default this is inherited by Item/Build
(AKA Job/Build
) but not
recursively!
This means that if “MyGroup” has the permission Item/Build
then the user
isn’t given Credentials/UseOwn
. You have to give the user Item/Build
directly.
Managing permissions without groups is hard. Instead, the administrator can run this groovy (via the Script Console or via the CLI):
// Give everyone "Credentials/UseOwn"
System.setProperty("com.cloudbees.plugins.credentials.UseOwnPermission", "true")
To make it permanent the administrator should put it in an init.groovy.d
file.
Steps
As a normal end user of Jenkins, you can put these steps in your
declarative pipeline
(e.g., Jenkinsfile
):
-
Add a
parameters
section if one doesn’t exist already. -
Within the
parameters
section, add acredentials
section./* EXAMPLE */ parameters { credentials( credentialType: 'com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl', defaultValue: '', description: 'The credentials needed to deploy.', name: 'deployCredentialsId', required: true ) }
-
Within a
steps
section, use thewithCredentials()
method, using the credentialsId specified above wrapped with${...}
./* EXAMPLE */ steps { withCredentials([usernamePassword( credentialsId: '${deployCredentialsId}', usernameVariable: 'DEPLOY_USERNAME', passwordVariable: 'DEPLOY_PASSWORD', )]) { sh './my-command.bash --username="${DEPLOY_USERNAME}" --password="${DEPLOY_PASSWORD}"' } }
Caveats
withCredentials
can only use the user credentials if the user kicks off
the build.
Builds triggered remotely (via URL) or via a cron specification won’t work.
This is because the build runs (by default) as ACL.SYSTEM
. ACL.SYSTEM
doesn’t have permission to read any user’s credentials.
The ${<parameter_name>}
is a
bit of magic
that fetches the credentials as stored in the parameter, by passing the
permission check.