18.2.5 访问控制与授权策略(Matrix、Folder)
在 Jenkins 中,访问控制与授权策略决定了“谁能做什么”。常见做法是基于 Matrix 权限模型进行精细化授权,并结合 Folder 进行资源隔离与权限继承,满足多团队与多项目的隔离需求。
原理草图(权限与隔离关系)#
Matrix 权限模型要点#
- 全局权限与项目权限分离:全局用于系统级操作,项目级用于作业与流水线。
- 细粒度授权:按用户/组授予 Job、Run、View、Credentials、Agent、Overall 等权限。
- 最小权限原则:仅授予完成职责所需权限,避免 Admin 过度泛化。
- 权限继承策略明确:全局权限不等于项目权限,需单独配置。
Folder 隔离与授权策略#
- 通过 Folder 进行组织结构隔离:按团队、业务线、环境(dev/test/prod)划分。
- Folder 权限继承:父级授权可继承到子项目,减少重复配置。
- 结合 Folder-based Authorization Strategy 插件,实现按目录授权与审计。
- 避免跨 Folder 引用:限制对外部 Job、凭据和节点的访问。
授权设计建议#
- 角色设计:管理员、平台维护、项目负责人、开发、测试、访客。
- 资源分区:环境级 Folder + 项目级 Folder 双层隔离。
- 权限矩阵模板化:统一权限基线,避免人工差异。
- 高风险权限控制:Overall/Job/Run/Credentials/Agent 相关权限需严格审批。
安装与启用(示例)#
以 Jenkins CLI 安装必要插件(Matrix 与 Folder 授权均为常用插件)
1)下载 CLI 并验证连通:
JENKINS_URL=http://jenkins.example.com
curl -sO $JENKINS_URL/jnlpJars/jenkins-cli.jar
java -jar jenkins-cli.jar -s $JENKINS_URL -auth admin:AdminPass who-am-i
预期输出包含当前用户与权限列表。
2)安装插件(若未内置):
java -jar jenkins-cli.jar -s $JENKINS_URL -auth admin:AdminPass install-plugin matrix-auth
java -jar jenkins-cli.jar -s $JENKINS_URL -auth admin:AdminPass install-plugin folder-auth
java -jar jenkins-cli.jar -s $JENKINS_URL -auth admin:AdminPass restart
全局 Matrix 权限示例(基线配置)#
用脚本方式可复现,适合环境快速初始化
// 文件: /var/lib/jenkins/init.groovy.d/01-global-matrix.groovy
import jenkins.model.*
import hudson.security.*
def instance = Jenkins.getInstance()
def strategy = new GlobalMatrixAuthorizationStrategy()
// 管理员
strategy.add(Jenkins.ADMINISTER, "admin")
// 运维:系统管理、节点、凭据只读等(示例)
strategy.add(Jenkins.MANAGE, "ops")
strategy.add(Computer.READ, "ops")
strategy.add(CredentialsProvider.VIEW, "ops")
// 开发:仅可读与查看作业列表
strategy.add(Jenkins.READ, "dev")
strategy.add(Item.READ, "dev")
strategy.add(View.READ, "dev")
instance.setAuthorizationStrategy(strategy)
instance.save()
生效方式:
sudo systemctl restart jenkins
Folder 级授权示例(Folder-based Strategy)#
使用脚本创建 Folder 并设置权限(示例角色:team-a)
// 文件: /var/lib/jenkins/init.groovy.d/02-folder-auth.groovy
import jenkins.model.*
import com.cloudbees.hudson.plugins.folder.*
import com.cloudbees.hudson.plugins.folder.properties.AuthorizationMatrixProperty
import hudson.security.*
def jenkins = Jenkins.getInstance()
def folder = jenkins.getItem("team-a")
if (folder == null) {
folder = jenkins.createProject(Folder.class, "team-a")
}
// Folder 权限矩阵
def props = folder.getProperties()
def auth = new AuthorizationMatrixProperty()
auth.add(Item.READ, "team-a-dev")
auth.add(Item.BUILD, "team-a-dev")
auth.add(Item.CONFIGURE, "team-a-lead")
auth.add(Run.REPLAY, "team-a-lead")
auth.add(CredentialsProvider.VIEW, "team-a-lead")
props.replace(auth)
folder.save()
jenkins.save()
验证访问:
java -jar jenkins-cli.jar -s $JENKINS_URL -auth team-a-dev:DevPass list-jobs
预期:可看到 team-a 下作业,不能访问 team-b。
典型授权矩阵模板(表述示例)#
- 管理员:admin → Overall/Administer
- 运维:ops → Jenkins/Manage + Agent/Read
- 项目负责人:team-a-lead → Job/Configure + Run/Replay + Credentials/View
- 开发:team-a-dev → Job/Build + Job/Read
- 测试:team-a-qa → Job/Read + Job/Build
- 访客:anonymous → 无(禁止匿名访问)
常见配置示例(思路)#
- 全局:仅管理员拥有 Overall/Administer;运维拥有 Manage。
- Folder:项目负责人拥有 Job/Build、Job/Configure、Run/Replay;开发仅 Build;测试仅 Read/Build。
- 凭据:使用 Folder 级凭据并限制访问权限。
排错与验证#
1)权限不生效(脚本已执行但 UI 未变化):
grep -n "AuthorizationStrategy" /var/log/jenkins/jenkins.log | tail -n 20
确认日志是否加载 groovy 初始化脚本。
2)Folder 权限继承异常:
- 检查 Folder 是否启用 folder-auth 插件策略
- 在 UI 中核对:Manage Jenkins → Configure Global Security → Authorization
3)匿名访问仍可见作业:
# 检查是否意外授予 anonymous 用户 READ 权限
java -jar jenkins-cli.jar -s $JENKINS_URL -auth admin:AdminPass who-am-i
在全局矩阵中移除 anonymous 的任何 READ 权限。
练习#
1)创建 team-b Folder,给 team-b-dev 仅 Job/Read + Job/Build 权限,并验证无法访问 team-a。
2)新增 “release” 凭据,仅 team-a-lead 可见并在 pipeline 中使用,验证 team-a-dev 无法读取。
3)将 dev 环境 Folder 设置为继承权限,prod Folder 取消继承并单独授权。
风险与治理#
- 避免匿名访问:关闭匿名读/写权限。
- 防止权限漂移:定期审计权限矩阵与 Folder 继承关系。
- 统一用户来源:结合 LDAP/AD 组映射,减少手工维护。
- 变更可追溯:权限变更需记录审批与审计日志。