Jenkins Credentials Binding Plugin: Difference between revisions
(20 intermediate revisions by the same user not shown) | |||
Line 12: | Line 12: | ||
=Overview= | =Overview= | ||
This plugin allows credentials defined in the Jenkins server to be bound to environment variables or | This plugin allows credentials defined in the Jenkins server to be bound to environment variables or Groovy variables to be used fro miscellaneous build steps, inside a closure. It uses a <tt>[[#withCredentials|withCredentials]]</tt> step whose programming model is explained below. The advantage of using this pattern is that the credentials are maintained securely by the Jenkins instance and they are automatically masked in the logs. | ||
=Playground= | =Playground= | ||
Line 25: | Line 25: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
The following bindings are available: | The following bindings are available: | ||
* usernamePassword | * [[#usernamePassword|usernamePassword]] | ||
* sshUserPrivateKey | * sshUserPrivateKey | ||
* certificate | * certificate | ||
Line 38: | Line 38: | ||
and more. | and more. | ||
==Injecting Username and Password into a Build Step== | ==<span id='usernamePassword'></span>usernamePassword Binding - Injecting Username and Password into a Build Step== | ||
A typical pattern to project username and password into a build step: | A typical pattern to project a username and a password stored as a Jenkins [[Jenkins_Security_Concepts#Username_with_Password|Username with Password credential]] into a build step: | ||
<syntaxhighlight lang='groovy'> | <syntaxhighlight lang='groovy'> | ||
withCredentials([usernamePassword(credentialsId: ' | withCredentials([usernamePassword(credentialsId: 'test-credential', usernameVariable: 'username', passwordVariable: 'password')]) { | ||
/ | sh 'echo $username' | ||
// | echo password | ||
echo "username is $username" | |||
// | } | ||
</syntaxhighlight> | |||
The binding injects the username and the password read from the Jenkins credentials vault as environment variable '''and''' Groovy variables, available in the closure. If the credential entry whose ID is specified is not declared, the step fails with: | |||
<syntaxhighlight lang='text'> | |||
ERROR: Could not find credentials entry with ID 'test-credential' | |||
</syntaxhighlight> | |||
Both the username and the password will be masked if printing is attempted: | |||
<syntaxhighlight lang='text'> | |||
[Pipeline] { | |||
[Pipeline] withCredentials | |||
Masking supported pattern matches of $username or $password | |||
[Pipeline] { | |||
[Pipeline] sh | |||
+ echo **** | |||
**** | |||
[Pipeline] echo | |||
**** | |||
[Pipeline] echo | |||
Warning: A secret was passed to "echo" using Groovy String interpolation, which is insecure. | |||
Affected argument(s) used the following variable(s): [username] | |||
See https://jenkins.io/redirect/groovy-string-interpolation for details. | |||
username is **** | |||
[Pipeline] } | |||
[Pipeline] // withCredentials | |||
</syntaxhighlight> | |||
⚠️ Standard security practice requires to not pass the security sensitive elements as variables that will be string-interpolated, but only as environment variables. If passed as variables, the sensitive environment variable will be interpolated during Groovy evaluation, and the environment variable’s value could be made available earlier than intended, resulting in sensitive data leaking in various contexts. In the following example: | |||
<syntaxhighlight lang='groovy'> | |||
pipeline { | |||
environment { | |||
EXAMPLE_CREDS = credentials('example-credentials-id') | |||
} | |||
stages { | |||
stage('Example') { | |||
steps { | |||
/* WRONG! */ | |||
sh("curl -u ${EXAMPLE_CREDS_USR}:${EXAMPLE_CREDS_PSW} https://example.com/") | |||
} | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
Should Groovy perform the interpolation, the sensitive value will be injected directly into the arguments of the sh step, which among other issues, means that the literal value will be visible as an argument to the sh process on the agent in OS process listings. Using single-quotes instead of double-quotes when referencing these sensitive environment variables prevents this type of leaking: | |||
<syntaxhighlight lang='groovy'> | |||
pipeline { | |||
environment { | |||
EXAMPLE_CREDS = credentials('example-credentials-id') | |||
} | |||
stages { | |||
stage('Example') { | |||
steps { | |||
/* CORRECT */ | |||
sh('curl -u $EXAMPLE_CREDS_USR:$EXAMPLE_CREDS_PSW https://example.com/') | |||
/* ALSO CORRECT */ | |||
sh("curl -u \$EXAMPLE_CREDS_USR:\$EXAMPLE_CREDS_PSW https://example.com/") | |||
} | |||
} | |||
} | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
More details available here: {{External|https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#interpolation-of-sensitive-environment-variables}} and here: {{External|https://github.com/ovidiuf/playground/blob/master/jenkins/pipelines/credentials-binding-plugin/Jenkinsfile}} | |||
===Configuration Map=== | |||
* credentialsId: the ID of the Jenkins credential that contains the username and password. | |||
* usernameVariable: the name of the environment variable and Groovy variable used to project the username into the pipeline. | |||
* passwordVariable: the name of the environment variable and Groovy variable used to project the password into the pipeline. |
Latest revision as of 10:43, 10 April 2021
External
- https://wiki.jenkins.io/display/JENKINS/Credentials+Binding+Plugin
- https://plugins.jenkins.io/credentials-binding/
- https://www.jenkins.io/doc/pipeline/steps/credentials-binding/#withcredentials-bind-credentials-to-variables
- https://docs.cloudbees.com/docs/cloudbees-ci/latest/cloud-secure-guide/injecting-secrets
Internal
Overview
This plugin allows credentials defined in the Jenkins server to be bound to environment variables or Groovy variables to be used fro miscellaneous build steps, inside a closure. It uses a withCredentials step whose programming model is explained below. The advantage of using this pattern is that the credentials are maintained securely by the Jenkins instance and they are automatically masked in the logs.
Playground
withCredentials
The step can be configured with a binding list and executes a closure within which the credentials are projected:
withCredentials(<binding-list>) {
// closure
}
The following bindings are available:
- usernamePassword
- sshUserPrivateKey
- certificate
- dockerCert
- file
- kubeconfigContent
- kubeconfigFile
- vaultString
- zip
- azureServicePrincipal
- $class: 'AmazonWebServicesCredentialsBinding'
and more.
usernamePassword Binding - Injecting Username and Password into a Build Step
A typical pattern to project a username and a password stored as a Jenkins Username with Password credential into a build step:
withCredentials([usernamePassword(credentialsId: 'test-credential', usernameVariable: 'username', passwordVariable: 'password')]) {
sh 'echo $username'
echo password
echo "username is $username"
}
The binding injects the username and the password read from the Jenkins credentials vault as environment variable and Groovy variables, available in the closure. If the credential entry whose ID is specified is not declared, the step fails with:
ERROR: Could not find credentials entry with ID 'test-credential'
Both the username and the password will be masked if printing is attempted:
[Pipeline] {
[Pipeline] withCredentials
Masking supported pattern matches of $username or $password
[Pipeline] {
[Pipeline] sh
+ echo ****
****
[Pipeline] echo
****
[Pipeline] echo
Warning: A secret was passed to "echo" using Groovy String interpolation, which is insecure.
Affected argument(s) used the following variable(s): [username]
See https://jenkins.io/redirect/groovy-string-interpolation for details.
username is ****
[Pipeline] }
[Pipeline] // withCredentials
⚠️ Standard security practice requires to not pass the security sensitive elements as variables that will be string-interpolated, but only as environment variables. If passed as variables, the sensitive environment variable will be interpolated during Groovy evaluation, and the environment variable’s value could be made available earlier than intended, resulting in sensitive data leaking in various contexts. In the following example:
pipeline {
environment {
EXAMPLE_CREDS = credentials('example-credentials-id')
}
stages {
stage('Example') {
steps {
/* WRONG! */
sh("curl -u ${EXAMPLE_CREDS_USR}:${EXAMPLE_CREDS_PSW} https://example.com/")
}
}
}
}
Should Groovy perform the interpolation, the sensitive value will be injected directly into the arguments of the sh step, which among other issues, means that the literal value will be visible as an argument to the sh process on the agent in OS process listings. Using single-quotes instead of double-quotes when referencing these sensitive environment variables prevents this type of leaking:
pipeline {
environment {
EXAMPLE_CREDS = credentials('example-credentials-id')
}
stages {
stage('Example') {
steps {
/* CORRECT */
sh('curl -u $EXAMPLE_CREDS_USR:$EXAMPLE_CREDS_PSW https://example.com/')
/* ALSO CORRECT */
sh("curl -u \$EXAMPLE_CREDS_USR:\$EXAMPLE_CREDS_PSW https://example.com/")
}
}
}
}
More details available here:
and here:
Configuration Map
- credentialsId: the ID of the Jenkins credential that contains the username and password.
- usernameVariable: the name of the environment variable and Groovy variable used to project the username into the pipeline.
- passwordVariable: the name of the environment variable and Groovy variable used to project the password into the pipeline.