18.2.4 凭据管理与敏感信息保护
凭据管理与敏感信息保护#
凭据是Jenkins连接外部系统的核心资产,必须做到最小可见、最小使用与全生命周期管理。推荐统一使用Jenkins Credentials System集中管理,禁止在Pipeline脚本、配置文件或日志中明文保存敏感信息。
原理草图:凭据存储与使用路径
flowchart LR
Dev[开发/运维] -->|创建/更新| CredUI[Jenkins Credentials System]
CredUI --> Store[凭据存储(域/文件夹/全局)]
Store --> Job[Job/Folder权限控制]
Job --> Agent[构建节点/容器]
Agent --> Ext[外部系统: Git/Registry/DB/Cloud]
Job -.mask.-> Log[控制台日志(脱敏)]
凭据分类与命名规范
- 按用途分类:源码访问、制品仓库、云平台、数据库、通知通道、签名证书等。
- 采用可追溯命名:业务-环境-系统-用途,如 pay-prod-git-ssh。
- 设置明确的描述与负责人,便于审计与交接。
凭据存储与范围控制
- 优先使用Folder级或Job级范围,避免全局暴露。
- dev/test/prod环境分离凭据与权限。
- 结合RBAC限制仅对需要的角色可见与可用。
示例:通过Jenkins CLI导入凭据(可审计、可批量)
前置:下载
jenkins-cli.jar,并确保管理员账号已配置API Token
# 1) 下载CLI
wget http://jenkins.example.com/jnlpJars/jenkins-cli.jar
# 2) 准备凭据XML(用户名/密码示例)
cat > /tmp/cred-git.xml <<'EOF'
<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
<scope>GLOBAL</scope>
<id>pay-prod-git-http</id>
<description>pay prod git http</description>
<username>gituser</username>
<password>gitpass</password>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
EOF
# 3) 导入到全局域(需管理员权限)
java -jar jenkins-cli.jar -s http://jenkins.example.com \
-auth admin:APITOKEN \
create-credentials-by-xml system::system::jenkins _ < /tmp/cred-git.xml
# 预期:返回 "Created credentials"
Pipeline中安全使用凭据
- 使用withCredentials或credentials指令注入变量,避免硬编码。
- 配置日志遮罩,禁止set -x输出敏感变量。
示例:withCredentials安全注入
pipeline {
agent any
environment {
REGISTRY = "registry.example.com"
}
stages {
stage('Login Registry') {
steps {
withCredentials([usernamePassword(
credentialsId: 'pay-prod-registry',
usernameVariable: 'REG_USER',
passwordVariable: 'REG_PASS'
)]) {
sh '''
# 禁止调试输出,防止泄露
set +x
echo "logging to $REGISTRY"
echo "$REG_PASS" | docker login $REGISTRY -u "$REG_USER" --password-stdin
'''
}
}
}
}
}
敏感信息脱敏与日志保护
- 启用“Secret Masking”,在控制台输出中自动遮罩敏感值。
- 审查脚本中echo、set -x等命令。
- 对构建日志设置访问权限与保留策略。
示例:危险命令排查与替换
# 危险:会打印环境变量
set -x
echo "$REG_PASS"
# 安全替换
set +x
echo "registry login ok"
凭据轮换与审计
- 制定轮换策略(30/90天),结合外部系统密钥过期机制。
- 建立变更记录与审计流程,确保可追溯。
- 过期或未使用凭据及时清理。
示例:查询未使用凭据(Groovy脚本控制台)
import com.cloudbees.plugins.credentials.CredentialsProvider
import jenkins.model.Jenkins
def usedIds = [] as Set
Jenkins.instance.items.each { job ->
def text = job.getConfigFile().asString()
text.findAll(/credentialsId="([^"]+)"/) { m -> usedIds << m[1] }
}
def all = CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.Credentials.class,
Jenkins.instance, null, null
)
all.each { c ->
if (!usedIds.contains(c.id)) {
println "Unused: ${c.id} | ${c.description}"
}
}
与外部密钥管理系统集成
- 使用Vault、云厂商KMS等作为凭据源,减少本地存储风险。
- 通过插件实现动态凭据与短期Token,提高安全性。
排错清单(常见错误与定位)
1. Pipeline报“Credentials not found”
- 检查凭据ID大小写与作用域(Folder/Global)。
- 确认Job在对应Folder下,且权限允许访问。
2. 日志中仍出现明文密码
- 检查脚本是否set -x或echo变量。
- 确认是否使用withCredentials注入。
3. CLI创建凭据失败
- 核对API Token权限。
- 确认XML格式与scope、id字段合法。
练习
1. 创建一个Folder级凭据pay-test-git-ssh,并在该Folder下的Pipeline中完成Git拉取。
2. 将一个Pipeline中的硬编码密码替换为withCredentials注入,并验证日志脱敏效果。
3. 使用Groovy脚本列出未使用凭据,并清理一个无用ID。