跳到主要内容

凭证管理

Jenkins 里最大的安全漏洞往往是"把密码硬编码进流水线"或"把私钥提交进 Git"。Credentials 机制把敏感信息与流水线代码解耦,让凭证只存一处、引用时动态注入。

本篇目标:能创建和管理各类凭证,用 credentials() 在流水线安全引用,并了解与 Vault / 云密钥系统的集成。


1. Credentials 类型​

Manage Jenkins → Credentials → System → Global credentials(或文件夹级凭证):

类型用途
Username with password仓库账号、镜像仓库账号、HTTP 基本认证
SSH Username with private keyGit SSH 拉取、SSH 执行命令
Secret textAPI Token、密钥、Webhook Token
Secret file证书文件、kubeconfig、密钥文件
Certificate客户端证书 / CA 证书
Docker Host CertificateDocker 守护进程 TLS 凭据
Vault 动态凭证从 HashiCorp Vault 动态获取(见下文)
凭证存储位置

凭证默认加密存储在 $JENKINS_HOME/secrets/。备份 $JENKINS_HOME 即备份凭证,务必用与业务同等的方式保护备份文件(见第 14、15 篇)。

2. 在流水线中引用凭证​

2.1 凭据绑定(Credentials Binding)​

pipeline {
agent any
stages {
stage('登录镜像仓库') {
steps {
withCredentials([usernamePassword(
credentialsId: 'harbor-registry-auth',
usernameVariable: 'REGISTRY_USER',
passwordVariable: 'REGISTRY_PASS'
)]) {
sh '''
docker login -u "$REGISTRY_USER" -p "$REGISTRY_PASS" registry.company.com
'''
}
}
}
}
}

关键点:

  • 用 credentialsId 引用,不写明文;
  • usernameVariable / passwordVariable 指定变量名,环境变量只在 withCredentials 块内有效;
  • Secret text 用 string(variable: 'TOKEN', credentialsId: 'xxx');
  • 注意不要 echo 这些变量,日志里会泄露。

2.2 Git 仓库凭据​

Pipeline 从 Git 拉取代码时在 Job 配置(或流水线 git 步骤)中引用凭证:

stage('检出代码') {
steps {
git branch: 'main',
url: 'https://gitlab.company.com/team/app.git',
credentialsId: 'gitlab-token'
}
}

2.3 Secret file​

withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) {
sh 'kubectl --kubeconfig "$KUBECONFIG" get pods'
}

3. 凭证的最佳实践​

实践说明
专用账号为 CI 创建最小权限的机器人账号,不与个人账号混用
短期令牌优先用会过期的 Token,设置轮换提醒
最小范围凭证按全局 / 文件夹分级,谁用给谁看
不在日志出现启用 Credentials Binding 的"日志打码";不要 echo 变量
定期轮换定期更换密码/Token,用 Jenkins API 或外部密钥系统驱动
审计记录凭证读取和使用日志(Audit Trail 插件)
# 审计:谁在什么时候读了什么凭证
# 开启 Manage Jenkins → Security → Audit Trail 的 Credentials 审计

4. 与外部密钥系统集成​

4.1 HashiCorp Vault​

安装 Vault Credentials Provider 插件,让 Jenkins 从 Vault 动态取凭据:

# 流水线中
withVault(configuration: [
vaultUrl: 'https://vault.company.com',
vaultNamespace: 'team/order',
authMethod: 'TOKEN',
token: 'xxx' # 或从 Jenkins 凭证引用
]) {
withVaultSecret(engineVersion: 2, path: 'secret/data/order/api', key: 'DB_PASSWORD', vaultVar: 'DB_PASSWORD') {
sh 'echo $DB_PASSWORD' # 仅在块内可用
}
}

好处:密码不在 $JENKINS_HOME 里,与 Vault 的轮换策略联动。

4.2 云密钥服务​

云对接方式
AWSSecrets Manager / Parameter Store 的 CLI + STS 临时凭证
阿里云KMS / 参数仓库 + RAM 角色
腾讯云SSM 参数 + 临时密钥(STS)

流水线通过云的 SDK 在构建时取密钥,不用把长期密钥放进 Jenkins。

4.3 从外部 Secret 的取舍​

方案优点缺点
Jenkins Credentials简单、内置凭证在 Jenkins 存储,需同步轮换
Vault动态、可轮换、集中多一套组件要运维
云密钥服务与云原生一致绑定云厂商

中小团队从 Jenkins Credentials 起步即可;多人协作、合规要求高时再上 Vault。


5. 练习与验收​

练习 A

  1. 创建 harbor-registry-auth(Username with password)和 gitlab-token(Secret text)两类凭证
  2. 用 withCredentials 在流水线中引用并登录镜像仓库(可用模拟命令验证变量注入)
  3. 确认日志中没有打印出密码明文

练习 B

  1. 创建一个 Secret file 凭证(如 kubeconfig),用 file() 绑定加载
  2. 尝试让 developer 账号只能读取文件夹级凭证、不能读取全局凭证
  3. (可选)部署 Vault 或用云密钥服务做一次动态取密钥

验收清单

  • 能创建各类凭证,理解全局与文件夹级凭证的差异
  • 会用 withCredentials 和 credentialsId 安全引用,不用明文
  • 知道 Secret text、Secret file、Username/password、SSH key 各自适用场景
  • 知道凭证存储位置与备份安全
  • 了解 Vault 或云密钥系统的集成价值

下一篇:Groovy 基础。