Argo CD 项目角色令牌管理:argocd proj role list-tokens命令全面解析
【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd
导读
argocd proj role list-tokens是 Argo CD CLI 中用于列出指定项目(Project)下某个角色(Role)所签发 JWT 令牌的核心命令。在 Argo CD 的 RBAC 体系中,项目角色令牌(Project JWT Token)是用于自动化场景(如 CI/CD 流水线、GitOps 工具链)对接 Argo CD API 的轻量级凭证,而 list-tokens 正是审计、轮换、清理这些令牌的入口。阅读本文后,你将掌握该命令的完整语法、输出字段含义、--unixtime与delete-token的管道协作技巧,以及其底层源码实现原理,能够安全高效地管理项目角色令牌生命周期。
命令概览与适用场景
命令语法
argocd proj role list-tokens PROJECT ROLE-NAME [flags]该命令由 cmd/argocd/commands/project_role.go 中的NewProjectRoleListTokensCommand函数定义,属于argocd proj role子命令族,用于展示指定项目下指定角色已签发的所有 JWT 令牌及其签发时间与过期时间。
该命令还注册了两个便捷别名(Aliases):
| 别名 | 说明 |
|---|---|
list-token | 单数形式,等价于list-tokens |
token-list | 动词前置形式,等价于list-tokens |
即argocd proj role token-list test-project test-role与标准写法完全等价。
典型适用场景
- 令牌审计:定期检查项目中各角色签发了哪些令牌、是否存在永不过期的令牌;
- 令牌轮换/清理:先列出令牌及其签发时间,再使用
delete-token删除指定令牌; - 脚本化集成:通过
--unixtime输出时间戳,将结果直接管道给delete-token实现批量清理。
使用前提
- 目标项目(PROJECT)必须已存在(如
argocd proj create test-project); - 目标角色(ROLE-NAME)必须已在项目中创建(如
argocd proj role create test-project test-role); - 执行命令的账号需要具备相应 RBAC 权限(
projects资源的读取权限)。
运行示例与输出解读
基本用法
$ argocd proj role list-tokens test-project test-role ID ISSUED AT EXPIRES AT f316c466-40bd-4cfd-8a8c-1392e92255d4 2023-10-08T15:21:40+01:00 Never fa9d3517-c52d-434c-9bff-215b38508842 2023-10-08T11:08:18+01:00 Never输出字段详解
输出使用制表符对齐的表格格式(Go 标准库text/tabwriter),包含三列:
| 列名 | 含义 | 数据来源 |
|---|---|---|
ID | 令牌的唯一标识(JWT 的jticlaim) | JWTToken.ID |
ISSUED AT | 令牌签发时间 | JWTToken.IssuedAt(JWT 的iatclaim) |
EXPIRES AT | 令牌过期时间 | JWTToken.ExpiresAt(JWT 的expclaim) |
其中时间列的格式化逻辑由 cmd/argocd/commands/project_role.go 中的tokenTimeToString函数实现:
func tokenTimeToString(t int64) string { tokenTimeToString := "Never" if t > 0 { tokenTimeToString = time.Unix(t, 0).Format(time.RFC3339) } return tokenTimeToString }即:
- 当时间戳值大于 0时,格式化为 RFC3339 标准时间(如
2023-10-08T15:21:40+01:00,包含时区偏移); - 当时间戳值为 0 或不存在时,显示为
Never(表示该令牌永不过期)。
空结果提示
如果目标角色下没有任何令牌,命令会输出提示而非空表格:
No tokens for test-project.test-role该逻辑位于源码第 420-423 行:当len(role.JWTTokens) == 0时直接打印No tokens for <project>.<role>并返回。
核心选项:--unixtime与令牌清理管道
选项说明
-u, --unixtime Print timestamps as Unix time instead of converting. Useful for piping into delete-token.默认情况下,ISSUED AT和EXPIRES AT两列会通过tokenTimeToString转换为 RFC3339 人类可读时间。而加上--unixtime(或简写-u)后,命令直接输出原始的 Unix 时间戳(自 1970-01-01 起的秒数),不做任何格式化转换。
从源码看(第 429-436 行),当useUnixTime为 true 时,token.ID、token.IssuedAt、token.ExpiresAt三个字段原样输出;否则对后两个字段调用tokenTimeToString转换。
为什么需要 Unix 时间戳?
关键在于delete-token命令使用 Unix 时间戳作为令牌的定位参数。查看 cmd/argocd/commands/project_role.go 中NewProjectRoleDeleteTokenCommand的定义:
delete-token PROJECT ROLE-NAME ISSUED-AT其实现中通过strconv.ParseInt(tokenId, 10, 64)将第三个参数解析为 int64,作为iat(签发时间)传递给projIf.DeleteToken的ProjectTokenDeleteRequest。也就是说,删除令牌需要的是签发时间的 Unix 时间戳,而不是人类可读时间。
因此--unixtime的典型用法是配合delete-token实现脚本化清理,例如先查看某角色的令牌:
$ argocd proj role list-tokens test-project test-role --unixtime ID ISSUED AT EXPIRES AT f316c466-40bd-4cfd-8a8c-1392e92255d4 1696774900 0 fa9d3517-c52d-434c-9bff-215b38508842 1696759698 0此时ISSUED AT列的1696774900可直接作为delete-token的ISSUED-AT参数使用。文档中的示例命令(第 477 行)也印证了这一协作方式:
$ argocd proj role delete-token test-project test-role 1696769937注意:使用--unixtime时,EXPIRES AT列的0表示该令牌永不过期(对应默认输出的Never),而非时间起点。
其他命令级选项(Options)
除--unixtime外,该命令还继承自父命令(argocd proj role/argocd根命令)的一系列连接与认证选项,常见的重要选项如下:
| 选项 | 默认值 | 说明 |
|---|---|---|
--server string | 无 | Argo CD server 地址 |
--argocd-context string | 无 | 要使用的 Argo CD server context 名称 |
--auth-token string | 无 | 认证令牌;设置此项或ARGOCD_AUTH_TOKEN环境变量 |
--config string | /home/user/.config/argocd/config | Argo CD 配置文件路径 |
--core | false | 若为 true,CLI 直接与 Kubernetes 通信而非 Argo CD API server |
--grpc-web | false | 启用 gRPC-web 协议,适用于 Argo CD server 位于不支持 HTTP2 的代理之后 |
--grpc-web-root-path string | 无 | 启用 gRPC-web 时设置 web 根路径 |
-H, --header strings | 无 | 为所有请求添加额外 header(可重复指定,支持逗号分隔多个) |
--insecure | false | 跳过服务器证书与域名校验 |
--kube-context string | 无 | 指定 kube-context |
--plaintext | false | 禁用 TLS |
--port-forward | false | 通过端口转发连接随机 argocd-server 端口 |
--port-forward-namespace string | 无 | 端口转发使用的命名空间 |
--loglevel string | info | 日志级别:debug、info、warn、error |
--logformat string | json | 日志格式:json或text |
--server-name string | argocd-server | Argo CD API server 名称(Helm 安装时名称 label 可能不同,可用ARGOCD_SERVER_NAME环境变量覆盖) |
--controller-name string | argocd-application-controller | Application controller 名称 |
--repo-server-name string | argocd-repo-server | Repo server 名称 |
--redis-name string | argocd-redis | Redis 部署名称 |
--redis-haproxy-name string | argocd-redis-ha-haproxy | Redis HA Proxy 名称 |
--redis-compress string | gzip | 若 controller 启用了 redis 压缩,可取值gzip、none |
--http-retry-max int | 无 | 建立 HTTP 连接的最大重试次数 |
--prompts-enabled | false(由本地配置决定) | 强制启用/禁用交互式提示 |
源码级实现原理
命令执行流程
NewProjectRoleListTokensCommand的Run回调(cmd/argocd/commands/project_role.go)完整执行链路如下:
- 参数校验:
len(args) != 2时调用c.HelpFunc()打印帮助信息并以状态码 1 退出;两个位置参数依次为projName(args[0])与roleName(args[1]); - 建立客户端:通过
headless.NewClientOrDie(clientOpts, c)创建 gRPC 客户端,并调用NewProjectClientOrDieWithContext(ctx)获取 ProjectService 客户端,连接使用defer utilio.Close(conn)确保释放; - 获取项目:调用
projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName})拉取项目对象; - 定位角色:调用
proj.GetRoleByName(roleName)从项目的Spec.Roles中按名称查找角色。该方法定义于 pkg/apis/application/v1alpha1/app_project_types.go:遍历proj.Spec.Roles,若找到同名角色则返回该角色及其索引;否则返回错误role '<name>' does not exist in project '<name>'; - 空值判断:若
len(role.JWTTokens) == 0,打印No tokens for <project>.<role>并返回; - 格式化输出:使用
tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)创建对齐宽度为 4 的制表写入器,先输出表头ID\tISSUED AT\tEXPIRES AT,再逐行输出token.ID、token.IssuedAt、token.ExpiresAt(是否经tokenTimeToString转换由--unixtime决定),最后writer.Flush()落盘。
数据结构:JWTToken
命令输出的数据来源是 pkg/apis/application/v1alpha1/types.go 中定义的JWTToken结构体:
// JWTToken holds the issuedAt and expiresAt values of a token type JWTToken struct { IssuedAt int64 `json:"iat" protobuf:"int64,1,opt,name=iat"` ExpiresAt int64 `json:"exp,omitempty" protobuf:"int64,2,opt,name=exp"` ID string `json:"id,omitempty" protobuf:"bytes,3,opt,name=id"` }三个字段与输出三列一一对应:
IssuedAt(iat):签发时间,Unix 秒级时间戳;ExpiresAt(exp):过期时间,Unix 秒级时间戳,omitempty意味着未设置过期时间的令牌该字段为 0;ID(id):令牌唯一标识,通常为创建令牌时生成的 UUID(如示例中的f316c466-40bd-4cfd-8a8c-1392e92255d4)。
该结构体嵌套于ProjectRole的JWTTokens []JWTToken字段中(同文件第 3535 行),即每个项目角色的令牌列表直接存储在项目的Spec.Roles里。
与令牌生命周期的关系
理解 list-tokens 的输出,需要了解令牌的创建与删除机制:
- 创建:
argocd proj role create-token PROJECT ROLE-NAME通过ProjectTokenCreateRequest调用 ProjectService 的CreateToken接口。创建时可通过--expires-in(如12h、7d,默认无过期)和--id(默认随机 UUID)定制令牌。创建成功后 CLI 会解析返回的 JWT,从 claims 中提取iat、exp、jti等字段回显——这与 list-tokens 展示的列完全对应; - 删除:
argocd proj role delete-token PROJECT ROLE-NAME ISSUED-AT使用签发时间定位令牌,调用DeleteToken接口,并支持交互式确认([y/n]提示)。这也是--unixtime选项被设计为“方便管道进入 delete-token”的原因。
相关命令速查
该命令归属于argocd proj role命令族,完整参考见 docs/user-guide/commands/argocd_proj_role.md。与令牌管理直接相关的配套命令:
| 命令 | 作用 |
|---|---|
argocd proj role create-token PROJECT ROLE-NAME | 为角色创建 JWT 令牌(支持--expires-in、--id、--token-only) |
argocd proj role list-tokens PROJECT ROLE-NAME | 列出角色的全部令牌(本文主角) |
argocd proj role delete-token PROJECT ROLE-NAME ISSUED-AT | 按签发时间删除指定令牌(带交互确认) |
argocd proj role get PROJECT ROLE-NAME | 查看角色详情,包括策略与 JWT 令牌列表(含相对时间提示) |
argocd proj role list PROJECT | 列出项目下所有角色 |
使用建议与注意事项
- 定期审计
Never令牌:EXPIRES AT列为Never表示令牌永不过期,这类长期凭证安全风险较高,建议结合--unixtime输出与delete-token定期轮换; - 脚本化清理的推荐姿势:先
list-tokens --unixtime获取签发时间戳,再对目标令牌执行delete-token;delete-token自带交互确认,脚本中可通过配置禁用提示或预先确认; - 权限最小化:该命令需要
projects资源的读取权限,自动化账号应遵循最小权限原则,仅授予所需项目和角色的访问范围; - 时间显示受时区影响:RFC3339 格式输出包含时区偏移,跨团队协作时建议统一时区规范,或直接使用
--unixtime消除歧义。
【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考