Contents
- 1 External
- 2 Internal
- 3 Overview
- 4 Playground
- 5 withCredentials
- 5.1 usernamePassword Binding — Injecting Username and Password into a Build Step
- 5.1.1 Configuration Map
- 5.1 usernamePassword Binding — Injecting Username and Password into a Build Step
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
- Jenkins Security Concepts
- Jenkins Pipeline Syntax | withCredentials
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
- https://github.com/ovidiuf/playground/tree/master/jenkins/pipelines/credentials-binding-plugin
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:
- https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#interpolation-of-sensitive-environment-variables
and here:
- 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.
#jenkins #credentials #jenkins-job-dsl
Вопрос:
TL;DR: Задания, созданные с помощью Job DSL, не могут найти существующие учетные данные, что позволяет сохранить задание в графическом интерфейсе.
Моя Конфигурация:
- Дженкинс 2.277.4
- Работа DSL 1.77
- Плагин учетных данных 2.3.13
- Плагин привязки учетных данных 1.23 Они довольно старые, но я жду обновления от наших администраторов…
Шаги:
- Дженкинс содержит учетные данные типа «Секретный текст» с идентификатором = foo-bar.пароль .
- Задание job01 создается с помощью задания DSL и использует эти учетные данные, см. Фрагмент:
... job.with { wrappers { credentialsBinding { string('FOO_BAR_PASSWORD', 'foo-bar.password') } } }
- При запуске job01 происходит сбой с
ERROR: Could not find credentials entry with ID 'foo-bar.password'
- Сброс задания
config.yml
приводит к этому блоку оболочки:
... lt;buildWrappersgt; lt;org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrappergt; lt;bindingsgt; lt;org.jenkinsci.plugins.credentialsbinding.impl.StringBindinggt; lt;variablegt;FOO_BAR_PASSWORDlt;/variablegt; lt;credentialsIdgt;foo-bar.passwordlt;/credentialsIdgt; lt;/org.jenkinsci.plugins.credentialsbinding.impl.StringBindinggt; lt;/bindingsgt; lt;/org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrappergt; lt;/buildWrappersgt; ...
- Настройте задание с помощью графического интерфейса, ничего не меняйте, сохраните его.
- Работа работает
- Сброс конфигурации задания.yml теперь дает этот блок-оболочку,
SecretBuildWrapper
который теперь содержит атрибутplugin="credentials-binding@1.23"
... lt;buildWrappersgt; lt;org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrapper plugin="credentials-binding@1.23"gt; lt;bindingsgt; lt;org.jenkinsci.plugins.credentialsbinding.impl.StringBindinggt; lt;credentialsIdgt;foo-bar.passwdlt;/credentialsIdgt; lt;variablegt;FOO_BAR_PASSWORDlt;/variablegt; lt;/org.jenkinsci.plugins.credentialsbinding.impl.StringBindinggt; lt;/bindingsgt; lt;/org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrappergt; lt;/buildWrappersgt; ...
So GUI Save solved the problem and seems to allow Credential Bindings plugin to find the credential.
Кто-нибудь видел это, может быть, с другими версиями компонентов? Исправлена ли она в более новых версиях?
Поскольку мы создаем более 500 рабочих мест таким образом, ручное сохранение не является вариантом. Поэтому я был бы очень рад подсказке для автоматического сохранения заданий, например, по префиксу имени в консоли сценариев.
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 3:41:01 PM8/21/19
to jenkinsc…@googlegroups.com
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 3:47:01 PM8/21/19
to jenkinsc…@googlegroups.com
|
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 3:53:02 PM8/21/19
to jenkinsc…@googlegroups.com
I can reproduce the problem with a minimal new pipeline:
node('serverX&&windows') { withCredentials([usernamePassword(credentialsId: 'customer-testmatch-creds2', passwordVariable: 'TM_PASSWORD', usernameVariable: 'TM_USER')]) { echo 'running with new credentials' } }
The credentials with ID customer-testmatch-creds2 was created after the upgrade.
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 4:16:02 PM8/21/19
to jenkinsc…@googlegroups.com
|
||
|
||
We recently performed a long overdue upgrade from 2.95 to LTS 2.176.2. Jenkins master runs on RHEL 7.7 64 bit, the node where the pipeline is failing is a Windows Server 2012 R2 (64 bit). Master is running: Credentials plugin is at 2.2.1 Pipeline: Multibranch is at 2.21 Jenkins is running directly without reverse proxy, installed via rpm from «jenkins-stable» ([http://pkg.jenkins.io/redhat-stable)] We’re using chrome as a browser but the issue occurs on builds that are triggered via SCM polling so the browser is probably not relevant.
In a Multibranch pipeline we’re using the withCredentials syntax in several places: This has worked fine for several weeks but since the upgrade we get: The pipeline has not changed, the credentials have not been updated. I have found that the snippet generator displays an empty drop down list when I start it from within the «trunk» directory of the Multibranch pipeline. At one point I added a new credential and limited it to the folder of the Multibranch pipeline. The problem is that within the branches (currently only trunk) of the multibranch pipeline the credentials are not visible.
|
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 4:18:02 PM8/21/19
to jenkinsc…@googlegroups.com
We recently performed a long overdue upgrade from 2.95 to LTS 2.176.2.
Jenkins master runs on RHEL 7.7 64 bit, the node where the pipeline is failing is a Windows Server 2012 R2 (64 bit).
Master is running:
java -version
openjdk version «1.8.0_222»
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
C:>java -version
java version «1.8.0_191»
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
Credentials binding plugin is at 1.20
Credentials plugin is at 2.2.1
Pipeline: Multibranch is at 2.21
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 4:20:02 PM8/21/19
to jenkinsc…@googlegroups.com
Change By: | Bram Mertens |
---|---|
Attachment: | jenkins-system-properties.txt |
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 4:37:02 PM8/21/19
to jenkinsc…@googlegroups.com
Using credentials works fine on a test jenkins setup: RHEL 7.6 version 2.179 credentials plugin 2.2.0 credentials binding plugin 1.19 Pipeline plugin 2.6 Pipeline: Multibranch plugin 2.21 Also works fine on another older installation: Jenkins 2.143 on RHEL 6.7 credentials plugin 2.1.18 crdentials binding plugin 1.16 pipeline: multibranch: 2.20 (not used in this setup) |
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 4:52:03 PM8/21/19
to jenkinsc…@googlegroups.com
|
||||
|
bram.mertens@anubex.com (JIRA)
unread,
Aug 21, 2019, 4:53:01 PM8/21/19
to jenkinsc…@googlegroups.com
The attached stacktrace was generated by running the test pipeline (not multibranch) after downgrading the credentials binding plugin to 1.13. |
bram.mertens@anubex.com (JIRA)
unread,
Aug 22, 2019, 12:30:03 PM8/22/19
to jenkinsc…@googlegroups.com
The credentials test pipeline I created also works on another instance of the same LTS version.
RHEL 7.6 , jenkins-2.176.2-1.1.noarch,
Several plugins are slightly older. The ones that catch my eye are:
credentials 2.2.0
credentials-binding 1.19
Versus on the jenkins master that fails:
credentials 2.2.1
credentials-binding 1.20
bram.mertens@anubex.com (JIRA)
unread,
Aug 22, 2019, 3:34:02 PM8/22/19
to jenkinsc…@googlegroups.com
I tried to dowgrade the credentials and credentials binding plugins to credentials 2.2.0 and credentials binding 1.19 and even created a new credentials entry but the problem persists.
bram.mertens@anubex.com (JIRA)
unread,
Aug 26, 2019, 6:58:01 PM8/26/19
to jenkinsc…@googlegroups.com
A colleague found out that the problem is caused by the fact that as part of the upgrade the build authorization was configured to run as a specific user.
The user that is configured does not have the Jobs/Configure permission.
If we grant that permission the job is able to get the credentials as before.
We will investigate the different options described in the Credentials API user guide to avoid granting that user Jobs/Configure permission.
dbeck@cloudbees.com (JIRA)
unread,
Oct 7, 2019, 10:47:02 AM10/7/19
to jenkinsc…@googlegroups.com
|
||||
|
|
Kalle.Niemitalo@procomp.fi (JIRA)
unread,
Nov 28, 2019, 4:05:03 PM11/28/19
to jenkinsc…@googlegroups.com
|
msicker@cloudbees.com (JIRA)
unread,
May 8, 2020, 9:37:02 PM5/8/20
to jenkinsc…@googlegroups.com
|
|
||||||
|
|
Я пытаюсь получить доступ к учетным данным AWS, хранящимся в Jenkins, со следующим в конвейере jenkins (Jenkinsfile
)
steps {
withCredentials([usernamePassword(credentialsId: 'eb1092d1-0f06-4bf9-93c7-32e5f7b9ef76', accessKeyVariable: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY')]) {
sh 'echo $AWS_ACCESS_KEY_ID'
sh 'echo $AWS_SECRET_ACCESS_KEY'
}
}
Его ошибка с
org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: Could not find credentials entry with ID 'eb1092d1-0f06-4bf9-93c7-32e5f7b9ef76'
at org.jenkinsci.plugins.credentialsbinding.MultiBinding.getCredentials(MultiBinding.java:153)
at org.jenkinsci.plugins.credentialsbinding.impl.UsernamePasswordMultiBinding.bind(UsernamePasswordMultiBinding.java:76)
at org.jenkinsci.plugins.credentialsbinding.impl.BindingStep$Execution.start(BindingStep.java:114)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:270)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:178)
at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
at sun.reflect.GeneratedMethodAccessor3000.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:157)
at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:155)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:129)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
at WorkflowScript.run(WorkflowScript:16)
И с
withCredentials([[ $class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'eb1092d1-0f06-4bf9-93c7-32e5f7b9ef76', accessKeyVariable: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sh "echo this is ${env.AWS_ACCESS_KEY_ID}"
sh "echo this is ${env.AWS_SECRET_ACCESS_KEY}"
}
Ошибка
org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: Could not find credentials entry with ID 'eb1092d1-0f06-4bf9-93c7-32e5f7b9ef76'
at org.jenkinsci.plugins.credentialsbinding.MultiBinding.getCredentials(MultiBinding.java:153)
at com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentialsBinding.bind(AmazonWebServicesCredentialsBinding.java:97)
at org.jenkinsci.plugins.credentialsbinding.impl.BindingStep$Execution.start(BindingStep.java:114)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:270)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:178)
at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
at sun.reflect.GeneratedMethodAccessor3000.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:157)
at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
at
У меня есть учетные данные с идентификатором eb1092d1-0f06-4bf9-93c7-32e5f7b9ef76
Я установил CloudBees AWS Credentials Plugin версии 1.24.
Кто-нибудь знает, что здесь не так?
3 ответа
Лучший ответ
Учетные данные eb1092d1-0f06-4bf9-93c7-32e5f7b9ef76
не относятся к типу AWS access key and secret
. Пожалуйста, дважды проверьте, что вы выбрали правильный тип при добавлении учетных данных в Jenkins.
И вы можете проверить с помощью встроенного инструмента Jenkins: Синтаксис конвейера -> Генератор фрагментов, как показано в следующем руководстве:
-
Откройте инструмент через
your jenkins server url/pipeline-syntax/
, например https://my.jenkins.com/pipeline- синтаксис/ -
В раскрывающемся списке примера шага выберите
withCredentials: Bind credentials to variables
. -
Нажмите кнопку «Добавить» и выберите
AWS access key and secret
во всплывающем меню. -
Выберите свои учетные данные из раскрывающегося списка
Credentials
. Если вы не можете найти ни одного в раскрывающемся списке, это означает, что ваши учетные данные не относятся к типуAWS access key and secret
. -
Нажмите кнопку
Generate pipeline script
-
Убедитесь, что
credentialsId
в сгенерированном скрипте равенeb1092d1-0f06-4bf9-93c7-32e5f7b9e
.
23
Etienne Neveu
29 Авг 2022 в 10:34
Преобразование кода из приведенного выше снимка экрана в фрагмент для удобного копирования
withCredentials([[
$class: 'AmazonWebServicesCredentialsBinding',
credentialsId: "credentials-id-here",
accessKeyVariable: 'AWS_ACCESS_KEY_ID',
secretKeyVariable: 'AWS_SECRET_ACCESS_KEY'
]]) {
// AWS Code
}
12
bythe4mile
17 Июл 2021 в 23:28
Возможно, вам придется иметь дело с учетными данными с несколькими полями или типами учетных данных, специфичными для поставщика, которые плагин (пока) не поддерживает.
В этой ситуации у вас есть несколько вариантов:
- Используйте наиболее близкие стандартные учетные данные с несколькими полями (например, имя пользователя с паролем), которые соответствуют вашим требованиям.
- Используйте строковые учетные данные, сериализуйте все поля в секретное значение (например, в формате JSON или в виде строки с разделителями) и проанализируйте их в сценарии задания. (Это последнее средство, когда другие методы не работают, например, когда секретная ротация может привести к изменению нескольких полей.)
Пример: Дженкинс проходит аутентификацию в Secrets Manager, используя основные учетные данные AWS (из среды). У вас есть задание, которое выполняет определенную операцию AWS в другой учетной записи, которая использует дополнительные учетные данные AWS. Вы решили закодировать вторичные учетные данные AWS как JSON в строке учетных данных foo:
node {
withCredentials([string(credentialsId: 'foo', variable: 'secret')]) {
script {
def creds = readJSON text: secret
env.AWS_ACCESS_KEY_ID = creds['accessKeyId']
env.AWS_SECRET_ACCESS_KEY = creds['secretAccessKey']
env.AWS_REGION = 'us-east-1' // or whatever
}
sh "aws sts get-caller-identity" // or whatever
}
}
Типичный пример учетных данных типа имя пользователя и пароль (пример отсюда) будет выглядеть так:
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
// available as an env variable, but will be masked if you try to print it out any which way
// note: single quotes prevent Groovy interpolation; expansion is by Bourne Shell, which is what you want
sh 'echo $PASSWORD'
// also available as a Groovy variable
echo USERNAME
// or inside double quotes for string interpolation
echo "username is $USERNAME"
}
Подробнее1
Подробнее2
0
P.PingGOD
13 Июл 2022 в 18:18