Argo CD 全局 RBAC 配置完全指南:argocd-rbac-cm.yaml 实战详解
【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd
在 Argo CD 中,基于角色的访问控制(RBAC)决定了谁能在你的集群与应用上执行何种操作。argocd-rbac-cm是承载全局 RBAC 策略的核心 ConfigMap,本文以 docs/operator-manual/argocd-rbac-cm.yaml 官方示例为主线,逐字段讲解policy.csv、policy.default、scopes、policy.matchMode以及多策略拼接policy.*.csv的完整用法,并结合util/rbac/rbac.go源码与内置策略 assets/builtin-policy.csv 揭示其底层实现原理。读完本文,你将能够编写、组合、校验并排查一套生产可用的 Argo CD RBAC 策略。
一、认识 argocd-rbac-cm
Argo CD 本身不维护用户体系,仅内置一个admin超级用户。要细分权限,需要先配置 SSO 或本地用户,随后通过 RBAC 把 SSO 用户组或本地用户映射到不同角色。RBAC 策略可以在两个层面定义:
- 全局 RBAC ConfigMap:
argocd-rbac-cm(本文主题); - 单个 AppProject 的角色:项目级策略,与全局策略叠加生效。
argocd-rbac-cm是一个普通的 Kubernetes ConfigMap,通常部署在argocd命名空间(参见 manifests/base/config/argocd-rbac-cm.yaml 中的最小化定义)。策略内容全部存放在data字段中,Argo CD 各组件通过 informer 监听该 ConfigMap 的变化,无需重启即可热加载新策略。
二、官方示例配置全貌
以下是 docs/operator-manual/argocd-rbac-cm.yaml 提供的完整示例,它涵盖了本文将要讲解的全部配置项:
apiVersion: v1 kind: ConfigMap metadata: name: argocd-rbac-cm namespace: argocd labels: app.kubernetes.io/name: argocd-rbac-cm app.kubernetes.io/part-of: argocd data: # policy.csv 是用户自定义 RBAC 策略和角色定义的载体(可选)。 # 策略规则形式: # p, subject, resource, action, object, effect # 角色定义与绑定形式: # g, subject, inherited-subject policy.csv: | # 授权 'my-org:team-alpha' 组所有成员同步 'my-project' 中的应用 p, my-org:team-alpha, applications, sync, my-project/*, allow # 将 'my-org:team-beta' 组所有成员提升为管理员 g, my-org:team-beta, role:admin # 可通过向该 ConfigMap 添加额外条目来拼接最终的策略 csv。 # 此时 key 必须遵循 'policy.<任意字符串>.csv' 模式。Argo CD 会将所有 # 符合该模式的附加策略拼接在主策略('policy.csv')之后。这对于在 # Kustomize、Helm 等配置管理工具中组合策略非常有用。 policy.overlay.csv: | p, role:tester, applications, *, */*, allow p, role:tester, projects, *, *, allow g, my-org:team-qa, role:tester # policy.default 是默认角色的名称。当授权 API 请求时,Argo CD 会回退到 # 该角色(可选)。如果省略或为空,用户仍可登录,但看不到任何应用、 # 项目等资源。 policy.default: role:readonly # scopes 控制 RBAC 执行时(除 'sub' scope 之外)需要检查的 OIDC scopes。 # 如果省略,默认为 '[groups]'。scope 的值可以是字符串或字符串列表。 scopes: '[cognito:groups, email]' # matchMode 配置 casbin 的匹配函数。 # 有两个选项:'glob'(glob 匹配器)或 'regex'(正则匹配器)。 # 如果省略或配置错误,将默认设置为 'glob'。 policy.matchMode: 'glob'注意:虽然策略文件是 CSV 格式,但 Argo CD 解析时会忽略以
#开头的行,因此可以使用#写行注释,如上例所示。
三、policy.csv:策略与角色定义
policy.csv是全局 RBAC 配置的核心字段,采用基于 Casbin 的语法,包含两种语句类型。
3.1 策略语句(p)
格式为:
p, <role/user/group>, <resource>, <action>, <object>, <effect><role/user/group>:被授权的主体,可以是本地用户、SSO 用户或组、内部角色;<resource>:被操作的资源类型(applications、clusters、projects、repositories等);<action>:对资源执行的操作(get、create、update、delete、sync等);<object>:目标对象的标识符,随资源类型而变,如项目限定格式<app-project>/<app-name>;<effect>:allow或deny,决定授权还是拒绝。
例如示例中的策略:
p, my-org:team-alpha, applications, sync, my-project/*, allow表示my-org:team-alpha组可以同步my-project项目下的所有应用(*是通配符)。
3.2 角色绑定语句(g)
格式为:
g, <user/group>, <role>将用户或组绑定到内部角色。例如:
g, my-org:team-beta, role:admin把my-org:team-beta组绑定到内置的role:admin,从而获得管理员权限。
重要:如果要对组直接编写
p策略,必须先通过g, <group>, <role>为组绑定角色,否则针对组的p策略不会被考虑。
3.3 内置角色与内置策略
Argo CD 预置了两个角色,定义见 assets/builtin-policy.csv:
role:readonly:对所有资源的只读访问(get);role:admin:对所有资源的无限制访问。
内置策略还包含两条角色继承规则:
g, role:admin, role:readonly g, admin, role:admin即role:admin自动继承role:readonly的全部权限,且内置admin用户被绑定到role:admin。这些内置策略会与用户自定义的policy.csv合并加载(见 util/rbac/rbac.go 中argocdAdapter.LoadPolicy依次加载builtinPolicy、userDefinedPolicy与运行时策略的逻辑)。
3.4 资源与动作矩阵
在 util/rbac/rbac.go 中,Resources与Actions常量定义了全部合法取值,以下矩阵汇总了各资源支持的动作:
| 资源\动作 | get | create | update | delete | sync | rollback | action | override | invoke |
|---|---|---|---|---|---|---|---|---|---|
| applications | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| applicationsets | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| clusters | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| projects | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| repositories | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| accounts | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| certificates | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| gpgkeys | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| logs | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| exec | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| extensions | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
其中applications、applicationsets、logs、exec属于“应用特定”资源,其<object>使用<app-project>/<app-name>格式;若启用了任意命名空间中的应用,则格式扩展为<app-project>/<app-ns>/<app-name>。
四、policy.overlay.csv:策略拼接机制
在配置管理工具(Kustomize、Helm 等)中,直接修改主policy.csv往往不便。Argo CD 支持以policy.<任意字符串>.csv为 key 提供额外策略条目,所有匹配该模式的条目会被拼接在policy.csv之后,最终组合成完整的策略文件。
示例中的policy.overlay.csv:
policy.overlay.csv: | p, role:tester, applications, *, */*, allow p, role:tester, projects, *, *, allow g, my-org:team-qa, role:tester它定义了一个role:tester角色(对应用和项目拥有全部权限),并把my-org:team-qa组绑定到该角色。
从源码看,拼接逻辑位于 util/rbac/rbac.go 的PolicyCSV函数:它先把主policy.csv写入,然后对所有 data key 排序(sort.Strings),依次追加符合policy.前缀与.csv后缀、且不等于policy.csv本身的条目。因此拼接顺序由 key 的字典序决定:例如policy.A.csv会先于policy.B.csv被拼接。这种机制非常适合用 Kustomize overlay 增量叠加权限(参考 docs/operator-manual/rbac.md 中的完整 Kustomize 示例)。
五、policy.default:默认角色
policy.default指定所有已认证用户默认获得的角色。如果省略或为空,用户仍然可以登录,但看不到任何应用、项目等资源。
示例中的配置:
policy.default: role:readonly这意味着所有通过认证的用户至少拥有只读权限。
⚠️ 安全警告:所有认证用户都会获得默认策略授予的至少这些权限,且该访问权无法通过
deny规则阻断。官方建议创建一个权限最小的role:authenticated(或类似角色)作为默认角色,再按需为具体角色授权。同理,启用匿名访问(argocd-cm中的users.anonymous.enabled)时,未认证用户也会获得默认角色权限,建议为此场景单独设置policy.default: role:unauthenticated。
从源码看,默认角色在 util/rbac/rbac.go 的enforce函数中实现:SetDefaultRole设置默认角色后,每次执行授权检查时,会先用默认角色作为主体进行一次Enforce,若命中allow则直接放行——这正是"默认角色权限无法被 deny 阻断"的原因。
六、scopes:OIDC Scope 控制
scopes字段控制 RBAC 执行时(除subscope 之外)需要检查哪些 OIDC scopes。省略时默认为[groups],即从 OIDC 令牌的groups声明中提取用户所属组。取值可以是字符串或字符串列表。
示例:
scopes: '[cognito:groups, email]'指定同时读取cognito:groups(AWS Cognito 的自定义组声明)和email两个 scope。当 SSO 用户通过认证后,其组信息来源于这些 scope 返回的值,并用于匹配g语句中的组名。一个典型的结合用法:
data: policy.csv: | p, my-org:team-alpha, applications, sync, my-project/*, allow g, my-org:team-beta, role:admin g, user@example.org, role:admin g, admin, role:admin g, role:admin, role:readonly policy.default: role:readonly scopes: '[groups, email]'这里同时展示了角色继承(g, role:admin, role:readonly,授予role:admin的实体自动获得role:readonly全部权限)和基于 email 的显式绑定。更多细节参见 用户管理文档。
七、policy.matchMode:匹配模式
policy.matchMode配置 Casbin 使用的匹配函数,可选值为:
glob:基于 glob 通配符匹配(默认值,缺失或配置错误时自动回退到 glob);regex:基于正则表达式匹配。
示例:
policy.matchMode: 'glob'两种模式的底层实现见 util/rbac/rbac.go:glob模式使用globMatchFunc(基于gobwas/glob包),regex模式使用 Casbin 的util.RegexMatchFunc。ConfigMap 中该字段通过SetMatchMode动态切换。
glob 模式的关键行为是:策略 token 被当作单一术语,/不作为分隔符。例如策略p, example-user, applications, action/extensions/*, default/*, allow中:
- 主体
example-user匹配 tokenexample-user; - 资源
applications匹配applications; - 动作
action/extensions/DaemonSet/test匹配action/extensions/*(无需**); - 对象
default/my-app匹配default/*。
同理,模式delete/*/kind/*既会匹配delete/<group>/kind/<namespace>/<name>,也会匹配delete/<group>/<kind>/kind/<name>。虽然因资源 kind 通常含大写字母而问题不大,但官方建议始终在模式中写全资源路径的四个部分(四个/)以避免歧义。
八、策略求值规则与 deny 优先级
访问检查分两个阶段:先按默认策略(policy.default)校验,再按当前用户的策略校验。若默认策略已返回allow或deny,则直接生效,不再继续求值;只有当效果未定时,才继续按用户、再到其所属各组依次求值。
当多个策略同时命中时:
deny效果优先于allow:即使存在更具体的allow策略,只要命中了deny策略即拒绝;- 策略在文件中的先后顺序不影响结果,求值结果是确定性的;
- 全部策略求值完毕后,若至少有一个
allow且没有deny,访问被授予。
这套语义正是 Casbin 模型配置的体现,见 assets/model.conf:
[policy_effect] e = some(where (p.eft == allow)) && !some(where (p.eft == deny)) [matchers] m = g(r.sub, p.sub) && globOrRegexMatch(r.res, p.res) && globOrRegexMatch(r.act, p.act) && globOrRegexMatch(r.obj, p.obj)其中globOrRegexMatch即由policy.matchMode决定实现的匹配函数,在 util/rbac/rbac.go 中注册到 Casbin enforcer。
九、重要资源的行为要点
9.1 applications 的细粒度 update/delete 权限
授予应用本身update/delete权限时,不自动授予对应用子资源的操作权。若需操作子资源,动作需写作<action>/<group>/<kind>/<ns>/<name>:
# 只允许 example-user 删除 default 项目中 prod-app 应用里的 Pod p, example-user, applications, delete/*/Pod/*/*, default/prod-app, allow # 允许更新应用所有资源,但不更新应用本身 p, example-user, applications, update/*, default/prod-app, allow # 拒绝删除应用,但允许删除其 Pod p, example-user, applications, delete, default/prod-app, deny p, example-user, applications, delete/*/Pod/*/*, default/prod-app, allow # 允许更新应用,但拒绝更新其任何子资源 p, example-user, applications, update, default/prod-app, allow p, example-user, applications, update/*, default/prod-app, deny自 v3.0.0 起,不带
/*的update/delete不再作用于子资源。如需保留旧行为,可在argocd-cm中设置server.rbac.disableApplicationFineGrainedRBACInheritance: 'false';但关闭后无法在显式允许应用本身动作的情况下再对子资源 deny。
9.2 action 动作与自定义资源操作
action动作对应资源自定义操作(内置或自定义的 resource actions),格式为action/<group>/<kind>/<action-name>,无 group 的资源(如 Pod、ConfigMap)写作action//Pod/<action-name>:
# 允许对 DaemonSet 执行任意操作,以及对 Pod 执行 maintenance-off 操作 p, example-user, applications, action//Pod/maintenance-off, default/*, allow p, example-user, applications, action/extensions/DaemonSet/*, default/*, allow9.3 rollback、override 与 exec
rollback:回滚到历史修订版本,默认关闭(兼容旧行为),需在argocd-cm中设置server.rbac.rollback.enforce.enable: 'true'后单独授权;override:允许在同步时传入任意 manifest 或不同修订版本(v3.2 起可通过application.sync.requireOverridePrivilegeForRevisionSync: 'true'将指定修订版本同步也视为 override),授权时务必谨慎,因为用户可借此彻底改变或删除应用已部署资源;exec:授予create动作后,用户可在 UI 中进入应用 Pod 执行命令(类似kubectl exec),详见 Web 终端文档。
9.4 clusters 资源对象格式
clusters策略的<object>取自集群 Secret 的server字段(API URL),可选前缀项目名:
# 授予默认角色查看集群内建集群条目的权限 p, role:defaultrole, clusters, get, https://kubernetes.default.svc, allow # 授予角色对项目级外部集群的全部权限 p, role:my-role, clusters, *, my-project/https://api.example.com:6443, allow注意:集群的逻辑名称(name)不能作为 RBAC object,object 必须是集群 server URL(可带项目前缀)。
十、本地用户与 SSO 共存的歧义风险
g语句同样适用于本地用户。但如果同时启用了 SSO,任何 SSO 用户只要其 scope 值与某个本地用户名相同,就会被加入该本地用户所在的所有角色。例如本地用户sally被绑定到role:admin,那么任何 scope 名为sally的 SSO 用户也会成为管理员。当 SSO 提供商是 SCM 时,用户可能通过创建/加入同名组织来获得他人权限。因此,同时使用本地用户与 SSO 时,官方建议直接为本地用户编写p策略,而非使用g绑定角色,例如:
p, my-local-user, *, *, *, allow十一、策略热加载与运行时校验
11.1 无需重启的热加载
从源码看,util/rbac/rbac.go 通过newInformer创建针对argocd-rbac-cm的SharedIndexInformer(默认同步周期 10 分钟),并注册 Add/Update 事件处理器:每当 ConfigMap 发生变化,syncUpdate会依次设置默认角色、匹配模式,重新拼接策略 CSV 并调用SetUserPolicy重建 Casbin enforcer(同时清空 enforcer 缓存)。这意味着修改 RBAC ConfigMap 后策略会较快生效,无需重启任何组件。
11.2 用 CLI 校验与测试策略
在把策略应用到线上环境之前,可以使用argocd admin settings rbac命令族(实现见 cmd/argocd/commands/admin/settings_rbac.go,命令参考见 argocd_admin_settings_rbac)进行离线验证:
校验策略语法是否合法:
# 校验本地 policy.csv argocd admin settings rbac validate --policy-file policy.csv # 也可以直接校验 argocd-rbac-cm 形式的 ConfigMap 文件 argocd admin settings rbac validate --policy-file argocd-rbac-cm.yaml # 或者校验集群中已存在的 argocd-rbac-cm argocd admin settings rbac validate --namespace argocd测试某个角色/主体能否执行指定操作:
# 使用本地策略文件,检查 some:role 是否能在 default 项目创建应用 argocd admin settings rbac can some:role create application 'default/app' --policy-file policy.csv # 使用集群中的 argocd-rbac-cm argocd admin settings rbac can some:role create application 'default/app' --namespace argocdcan命令还支持--default-role覆盖默认角色、--strict(严格校验资源/动作名,默认开启)与--quiet等参数;资源名支持简写(如app、proj、repo)。该命令会提示"组直接拥有p策略但缺少g绑定"的告警——这类授权在运行时会被 API 服务器忽略。
十二、最佳实践小结
- 默认角色最小化:将
policy.default设为最小权限角色,避免所有认证用户获得额外能力;启用匿名访问时单独设置role:unauthenticated; - 优先使用角色中间层:通过
g把用户/组绑定到角色,通过p为角色授权,利用角色继承(如g, role:admin, role:readonly)降低重复; - 善用策略拼接:用
policy.<name>.csv在 Kustomize/Helm 中增量叠加权限,保持基线与 overlay 清晰分离; - 上线前离线验证:使用
argocd admin settings rbac validate/can对本地文件或线上 ConfigMap 进行语法与权限预检; - 注意 glob 的
/语义:应用细粒度资源策略时始终写全四段路径,必要时改用regex匹配模式。
通过以上配置项的组合使用与源码级理解,你就能把 Argo CD 的全局访问控制打磨到既灵活又安全的状态。更多细节可进一步阅读 RBAC 配置官方文档 与 AppProject 项目角色。
【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考