Jenkins Credentials 插件终极指南:7种方式安全托管密码与密钥
-
-
- 📈 凭证管理全生命周期流程图
- 一、核心组件:Credentials 插件的三大支柱
-
- 1. Credentials Binding Plugin(绑定插件)
- 2. Credentials Provider(凭证提供者)
- 3. Scope(作用域)
- 二、第一步:确认插件安装状态
- 三、第二步:全面解析5种常用凭证类型
-
- 类型1:Secret Text(秘密文本)
- 类型2:Username with Password(用户名密码)
- 类型3:SSH Username with Private Key(SSH密钥)
- 类型4:Secret File(秘密文件)
- 类型5:Certificate(客户端证书)
- 四、第三步:声明式 Pipeline 中的高级用法
-
- 1. 环境变量级注入
- 2. 文件夹级凭证隔离
- 五、第四步:六大安全加固铁律
- 📚 常见问题排查
-
- 问题1:报错 `Credentials not found`
- 问题2:`withCredentials` 块内的变量在 `sh` 中为空
- 问题3:流水线日志中凭证显示为 `****`
- 💎 总结
-
|
🌺The Begin🌺点点关注,收藏不迷路🌺 ⬇ ⬇ 底部 ⬇ ⬇ |
在Jenkins流水线中,数据库密码、Docker仓库Token、SSH私钥、云服务AK/SK等敏感信息一旦明文硬编码,就等于把服务器大门敞开。Credentials Binding Plugin 是Jenkins官方提供的凭证管理方案,它能将敏感信息**加密存储** 并在运行时**安全注入**。
📈 凭证管理全生命周期流程图
先通过一张图理解Credentials插件从创建到使用的完整链路:
#mermaid-svg-9G8qD8lvGcD73Eii{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9G8qD8lvGcD73Eii .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9G8qD8lvGcD73Eii .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9G8qD8lvGcD73Eii .error-icon{fill:#552222;}#mermaid-svg-9G8qD8lvGcD73Eii .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9G8qD8lvGcD73Eii .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9G8qD8lvGcD73Eii .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9G8qD8lvGcD73Eii .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9G8qD8lvGcD73Eii .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9G8qD8lvGcD73Eii .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9G8qD8lvGcD73Eii .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9G8qD8lvGcD73Eii .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9G8qD8lvGcD73Eii .marker.cross{stroke:#333333;}#mermaid-svg-9G8qD8lvGcD73Eii svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9G8qD8lvGcD73Eii p{margin:0;}#mermaid-svg-9G8qD8lvGcD73Eii .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-9G8qD8lvGcD73Eii .cluster-label text{fill:#333;}#mermaid-svg-9G8qD8lvGcD73Eii .cluster-label span{color:#333;}#mermaid-svg-9G8qD8lvGcD73Eii .cluster-label span p{background-color:transparent;}#mermaid-svg-9G8qD8lvGcD73Eii .label text,#mermaid-svg-9G8qD8lvGcD73Eii span{fill:#333;color:#333;}#mermaid-svg-9G8qD8lvGcD73Eii .node rect,#mermaid-svg-9G8qD8lvGcD73Eii .node circle,#mermaid-svg-9G8qD8lvGcD73Eii .node ellipse,#mermaid-svg-9G8qD8lvGcD73Eii .node polygon,#mermaid-svg-9G8qD8lvGcD73Eii .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9G8qD8lvGcD73Eii .rough-node .label text,#mermaid-svg-9G8qD8lvGcD73Eii .node .label text,#mermaid-svg-9G8qD8lvGcD73Eii .image-shape .label,#mermaid-svg-9G8qD8lvGcD73Eii .icon-shape .label{text-anchor:middle;}#mermaid-svg-9G8qD8lvGcD73Eii .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9G8qD8lvGcD73Eii .rough-node .label,#mermaid-svg-9G8qD8lvGcD73Eii .node .label,#mermaid-svg-9G8qD8lvGcD73Eii .image-shape .label,#mermaid-svg-9G8qD8lvGcD73Eii .icon-shape .label{text-align:center;}#mermaid-svg-9G8qD8lvGcD73Eii .node.clickable{cursor:pointer;}#mermaid-svg-9G8qD8lvGcD73Eii .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9G8qD8lvGcD73Eii .arrowheadPath{fill:#333333;}#mermaid-svg-9G8qD8lvGcD73Eii .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9G8qD8lvGcD73Eii .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9G8qD8lvGcD73Eii .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9G8qD8lvGcD73Eii .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9G8qD8lvGcD73Eii .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9G8qD8lvGcD73Eii .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9G8qD8lvGcD73Eii .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9G8qD8lvGcD73Eii .cluster text{fill:#333;}#mermaid-svg-9G8qD8lvGcD73Eii .cluster span{color:#333;}#mermaid-svg-9G8qD8lvGcD73Eii div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9G8qD8lvGcD73Eii .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9G8qD8lvGcD73Eii rect.text{fill:none;stroke-width:0;}#mermaid-svg-9G8qD8lvGcD73Eii .icon-shape,#mermaid-svg-9G8qD8lvGcD73Eii .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9G8qD8lvGcD73Eii .icon-shape p,#mermaid-svg-9G8qD8lvGcD73Eii .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9G8qD8lvGcD73Eii .icon-shape .label rect,#mermaid-svg-9G8qD8lvGcD73Eii .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9G8qD8lvGcD73Eii .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9G8qD8lvGcD73Eii .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9G8qD8lvGcD73Eii :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Secret Text
Username Password
SSH Private Key
Secret File
Certificate
声明式
脚本式
🔐 管理员创建凭证
选择凭证类型
API Token / 密码
登录凭据对
Git连接私钥
.env / kubeconfig
PKCS12客户端证书
📦 存入Jenkins加密存储
👤 配置权限范围
🔧 Pipeline中引用
引用方式
credentials('ID')
withCredentials 片段
🔓 运行时解密为环境变量/文件
✅ 任务执行完毕自动销毁
❌ 日志自动脱敏隐藏
一、核心组件:Credentials 插件的三大支柱
在深入操作之前,必须理解三个关键概念:
1. Credentials Binding Plugin(绑定插件)
这是核心插件,作用是将存储的凭证"绑定"到构建环境变量或临时文件中。Jenkins 2.0+ 默认集成此插件。
2. Credentials Provider(凭证提供者)
决定凭证的存储位置和加密方式:
- System:默认提供者,凭证存储在 $JENKINS_HOME/credentials.xml,用 AES-128 加密。
- Folder:Folder级别的凭证,只有特定文件夹下的任务可见。
- User:个人凭证,仅创建者本人可用。
3. Scope(作用域)
- Global:所有节点和任务都能访问。
- System:仅Jenkins系统本身(如连接Slave节点)使用,普通Pipeline不可见。
二、第一步:确认插件安装状态
在开始管理凭证前,确保以下插件已更新到最新版。
- Credentials Plugin(核心基础)
- Credentials Binding Plugin(用于Pipeline绑定)
- Plain Credentials Plugin(支持明文凭证类型)
提示: 大部分现代Jenkins发行版已默认包含这些插件,如缺失请直接安装。
三、第二步:全面解析5种常用凭证类型
进入 Manage Jenkins → Credentials → System → Global credentials → Add Credentials,你会看到完整的类型列表。
类型1:Secret Text(秘密文本)
适用场景: API Token、OAuth Refresh Token、Webhook Secret。
| Kind | Secret text |
| Secret | ghp_xxxxxxxxxxxxxxxxxxxx |
| ID | github-api-token |
| Description | GitHub个人访问令牌 |
Pipeline引用:
withCredentials([string(credentialsId: 'github-api-token', variable: 'GITHUB_TOKEN')]) {
sh 'curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user'
}
类型2:Username with Password(用户名密码)
适用场景: Docker Hub登录、Nexus私服认证、数据库连接。
| Kind | Username with password |
| Username | admin |
| Password | P@ssw0rd123! |
| ID | nexus-login |
Pipeline引用:
withCredentials([usernamePassword(
credentialsId: 'nexus-login',
usernameVariable: 'NEXUS_USER',
passwordVariable: 'NEXUS_PASS'
)]) {
sh 'docker login nexus.mycompany.com -u $NEXUS_USER -p $NEXUS_PASS'
}
类型3:SSH Username with Private Key(SSH密钥)
适用场景: Git拉取代码、Ansible免密登录、SCP传输文件。
| Kind | SSH Username with private key |
| Username | git |
| Private Key | —–BEGIN OPENSSH PRIVATE KEY—– (直接粘贴) |
| Passphrase | (如果密钥有密码则填写) |
| ID | gitlab-ssh-key |
Pipeline引用(声明式):
pipeline {
agent any
stages {
stage('Clone Private Repo') {
steps {
git credentialsId: 'gitlab-ssh-key',
url: 'git@gitlab.com:team/private-repo.git'
}
}
}
}
类型4:Secret File(秘密文件)
适用场景: kubeconfig配置文件、Maven settings.xml、.env环境文件。
| Kind | Secret file |
| File | 上传 kubeconfig-prod.yaml |
| ID | prod-kubeconfig |
Pipeline引用:
withCredentials([file(credentialsId: 'prod-kubeconfig', variable: 'KUBECONFIG_FILE')]) {
sh 'kubectl –kubeconfig=$KUBECONFIG_FILE get pods'
}
原理: Jenkins会将文件写入构建节点的临时目录,构建结束后立即删除,不留痕迹。
类型5:Certificate(客户端证书)
适用场景: 双向TLS认证、容器镜像仓库MTLS连接。
| Kind | Certificate |
| Certificate | 上传 client-cert.p12 |
| Password | keystore-password |
| ID | mtls-client-cert |
Pipeline引用:
withCredentials([certificate(
credentialsId: 'mtls-client-cert',
keystoreVariable: 'KEYSTORE_PATH',
passwordVariable: 'KEYSTORE_PASS'
)]) {
sh 'curl –cert-type P12 –cert $KEYSTORE_PATH:$KEYSTORE_PASS https://secure-api.example.com'
}
四、第三步:声明式 Pipeline 中的高级用法
新版Jenkins推荐使用声明式语法直接注入凭证。
1. 环境变量级注入
pipeline {
agent any
environment {
// 直接映射全局凭证到环境变量
SONAR_TOKEN = credentials('sonar-token-id')
DOCKER_HUB = credentials('docker-hub-credentials')
}
stages {
stage('Sonar Scan') {
steps {
sh 'sonar-scanner -Dsonar.login=$SONAR_TOKEN'
}
}
stage('Docker Push') {
steps {
sh 'docker login -u $DOCKER_HUB_USR -p $DOCKER_HUB_PSW'
sh 'docker push myapp:latest'
}
}
}
}
注意: credentials() 方法会自动为 UsernamePassword 类型凭证创建 _USR 和 _PSW 两个后缀变量。
2. 文件夹级凭证隔离
如果你的Jenkins有多个团队共享,务必使用 Folder Plugin 创建独立空间:
五、第四步:六大安全加固铁律
技术落地后,必须遵守安全规范才能发挥作用。
永远不要在 println 中打印凭证 Jenkins会尝试脱敏,但如果用 echo ${PASSWORD} 直接输出,可能意外泄露。应使用 maskPasswords 过滤。
最小权限原则分配Scope 能用 Folder 级别的绝不用 Global;能用 User 的绝不给 System。
定期轮换密钥 在凭证的 Description 中填写 过期时间,并配合 Configuration as Code (JCasC) 插件统一管理。
禁止在共享库中硬编码凭证ID 将凭证ID作为Pipeline参数传入,而不是写死在 vars/logic.groovy 中。
备份加密密钥 $JENKINS_HOME/secrets/master.key 和 hudson.util.Secret 文件是解密的命脉,必须离线安全备份。
审计日志追踪 安装 Audit Trail Plugin,记录谁在什么时间访问了哪个凭证ID。
📚 常见问题排查
问题1:报错 Credentials not found
原因: 凭证ID大小写敏感或作用域不匹配。 解决: 进入 Credentials 页面,鼠标悬停在凭证上,确认ID拼写完全一致。
问题2:withCredentials 块内的变量在 sh 中为空
原因: 引号问题导致Shell无法解析环境变量。 解决: sh 步骤必须使用双引号:
// 错误:单引号不解析变量
sh 'echo $MY_SECRET'
// 正确:双引号解析
sh "echo $MY_SECRET"
问题3:流水线日志中凭证显示为 ****
这是Jenkins的自动脱敏机制,证明插件工作正常。不要试图绕过它。
💎 总结
Credentials Binding Plugin 是Jenkins安全体系的基石。通过本文你已掌握:
告别硬编码,从今天起让你的Jenkins流水线密不透风!

|
🌺The End🌺点点关注,收藏不迷路🌺 ⬆ ⬆ 顶部 ⬆ ⬆ |

