
Argo CD 在 Web UI 中隐藏敏感 Secret 注解提案设计与源码落地解析【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd本技术指南围绕 Argo CD 官方 Feature Bounty 提案《Allow Hiding Certain Annotations in the Argo CD Web UI》对应 hide-annotations.md源自 GitHub issue #15693展开讲解如何通过在argocd-cmConfigMap 中增加配置项让用户自定义在 Web UI 中被隐藏打码的 Secret 资源注解同时对照 gitops-engine 中last-applied-configuration注解的既有隐藏机制与仓库内实际落地的源码实现帮助你完整理解该功能的配置方式、解析逻辑与渲染原理。一、功能背景为什么要隐藏 Secret 上的注解Kubernetes 资源的metadata.annotations是键值对形式的自由文本元数据各种控制器与生态组件都会往里写入内容。其中不少注解携带的是敏感信息——例如 OpenShift 集群中由openshift.io/token-secret.value这类注解直接存放的 ServiceAccount token 明文。问题在于Argo CD 的 Web UI 在展示应用资源详情尤其是 Secret 资源时会把这些注解原样渲染出来。凡是有权查看该应用的团队成员都可能直接在浏览器里看到 token 明文而 Secret 本身的data字段在 Argo CD 中默认就会被以***形式打码显示注解区域却长期处于裸奔状态。原提案作者在评审了既有 issue 后给出了明确的功能边界见 hide-annotations.md只需要支持隐藏注解这一种对象类型、且只作用于 Secret 资源即可暂不考虑扩展到 Label 或其他资源类型——having reviewed existing issues, I think this narrow feature is sufficient。二、提案方案在 argocd-cm 中新增配置项提案给出的核心方案非常轻量在argocd-cmConfigMap 中新增一个配置项值为需要隐藏的注解键列表配置语法如下摘自原文档原文hide.secret.annotations: | - openshift.io/token-secret.value该配置一旦生效openshift.io/token-secret.value这个注解便不会在 UI 中显示真实值。提案同时明确了两点设计取向隐藏方式复用既有机制背后很可能以与last-applied-configuration注解隐藏相同的方式工作即复用 gitops-engine 在 diff 阶段对注解做替换/剥离的处理管线。刻意保持窄范围不引入隐藏其他资源类型注解、隐藏非注解元数据等广义能力降低实现与评审成本。[!NOTE] 原文档为提案性质明确标注 This is the proposed solution. The accepted PR may differ from this proposal.被接受的 PR 可能与提案不同。实际合并进仓库的实现如下文第三、四节所示配置键名与提案略有差异——这正是提案与实现存在迭代空间的典型例证。三、源码落地实际配置键resource.sensitive.mask.annotations对比当前仓库代码可以发现该功能已经落地但配置键从提案的hide.secret.annotations演进为resource.sensitive.mask.annotations语义更明确资源敏感的、需要打码的注解。键名定义位于 util/settings/settings.go// resourceSensitiveAnnotationsKey is the key to list of annotations to mask in secret resource resourceSensitiveAnnotationsKey resource.sensitive.mask.annotations因此实际生效的argocd-cm配置写法为data: resource.sensitive.mask.annotations: | openshift.io/token-secret.value example.com/token-secret.value example.com/api-key3.1 配置解析逻辑GetSensitiveAnnotations设置管理器通过GetSensitiveAnnotations()方法读取该键并解析为集合实现在 util/settings/settings.gofunc (mgr *SettingsManager) GetSensitiveAnnotations() map[string]bool { annotationKeys : make(map[string]bool) argoCDCM, err : mgr.getConfigMap() if err ! nil { log.Error(fmt.Errorf(failed getting configmap: %w, err)) return annotationKeys } value, ok : argoCDCM.Data[resourceSensitiveAnnotationsKey] if !ok || value { return annotationKeys } value strings.ReplaceAll(value, , ) for k : range strings.SplitSeq(value, ,) { annotationKeys[k] true } return annotationKeys }从源码可以提炼出三点行为细节按逗号分隔配置值是一个以逗号分隔的注解键列表最终被解析为map[string]boolSet 语义用于后续 O(1) 查找自动去除空格解析前会执行strings.ReplaceAll(value, , )因此example.com/a, example.com/b与example.com/a,example.com/b等价写配置时不必拘泥于逗号后是否有空格空值与缺省安全键不存在或值为空时直接返回空集合不会报错、不会 panic功能处于未启用的默认状态。3.2 单元测试印证上述解析行为有完整的单元测试支撑见 util/settings/settings_test.go 中的TestSettingsManager_GetHideSecretAnnotations覆盖三类用例用例输入期望输出空输入map[string]bool{}空集合逗号分隔example.com/token-secret.value,token,key三个键均命中值为true带空格的逗号分隔example.com/token-secret.value, token, key与上例完全相同空格被剔除测试对空格容忍度做了显式断言印证了 3.1 节配置书写可带空格的结论使用者在配置时无需担心多余空格导致匹配失败。四、底层机制与last-applied-configuration同源的注解隐藏管线提案明确要求复用kubectl.kubernetes.io/last-applied-configuration注解的隐藏机制。该机制位于仓库 vendored 的 gitops-engine 中核心实现是 gitops-engine/pkg/diff/diff.go 的Diff函数末尾两段逻辑target, live, targetLastAppliedAnnotation, liveLastAppliedAnnotation, err hide(target, live, targetLastAppliedAnnotation, liveLastAppliedAnnotation, hideAnnotations, metadata, annotations)即通过hide()函数对 target 与 live 两侧对象的metadata.annotations路径执行掩蔽。hide()的实现在 gitops-engine/pkg/diff/diff.go核心步骤包括遍历待隐藏的注解键集合keys对 target、live 以及两边的 last-applied 快照依次处理用unstructured.NestedMap定位到metadata.annotations这一嵌套路径命中键后以**替换符replacement**覆盖其值实现 UI 层面的打码。而last-applied-configuration自身也有特殊处理分支diff.go若它出现在隐藏集合中或快照无效则直接把该注解值替换为 replacement避免把完整的历史 manifest 明文暴露在差异视图里。由此可以推断resource.sensitive.mask.annotations中列出的注解键会进入hideAnnotations集合经由同一条管线在应用资源树与 diff 计算时被统一替换从而同时作用于 UI 的资源树/资源详情视图与差异对比视图。五、调用链从配置到 UI 渲染的完整路径结合上文敏感注解隐藏功能的完整调用链可以归纳为管理员在argocd-cmConfigMap 的data中写入resource.sensitive.mask.annotationsSettingsManager.GetSensitiveAnnotations()util/settings/settings.go解析出map[string]bool集合Application Server 在返回资源对象给 UI 前调用diff.HideSecretData(obj, nil, s.settingsMgr.GetSensitiveAnnotations())见 server/application/application.go、server/application/application.go、server/application/application.go 与 server/application/application.go 共四处调用点分别覆盖资源清单、差异对比等不同返回路径HideSecretData内部复刻 3.1 的空值安全逻辑并委托 gitops-engine 的hide()管线对命中的注解执行替换UI 收到的是已被 replacement 替换后的注解值敏感明文不再出现。从源码结构看该功能是一个典型的配置驱动 Server 端掩蔽设计敏感数据在离开 Argo CD Server 之前就被替换而不是依赖前端过滤因此即便是通过 API 直接拉取资源详情的客户端也无法看到原始值安全性更有保障。六、使用与验证清单6.1 配置步骤编辑argocd-cmConfigMapkubectl edit configmap argocd-cm -n argocd在data段加入需要隐藏的注解键逗号分隔可带空格data: resource.sensitive.mask.annotations: | openshift.io/token-secret.value, example.com/token-secret.value, example.com/api-key保存后Argo CD 会通过 ConfigMap 的 Watch 机制热加载配置无需重启 ServerSettingsManager 每次调用getConfigMap()读取最新值见 util/settings/settings.go。在 Web UI 打开对应 Secret 资源详情确认被配置的注解值已被***形式替换。6.2 行为边界说明作用对象以 Secret 资源中的敏感注解为主要目标提案原意但底层hide()作用于metadata.annotations路径对资源类型没有硬编码限制匹配方式精确匹配整个注解键名不支持通配符或前缀模糊匹配源码直接以键为 map key 进行精确命中只影响展示该配置只改变 Server 返回给 UI/API 的渲染内容不会修改集群中资源对象的真实注解也不影响应用同步与 diff 判定的底层数据配置键差异请以当前仓库实际实现的resource.sensitive.mask.annotations为准提案阶段的hide.secret.annotations键名并未在仓库代码中出现。七、总结从一份仅数行的 Feature Bounty 提案出发Argo CD 完成了Web UI 隐藏敏感 Secret 注解这一小而实用的安全增强管理员通过 argocd-cm 中的resource.sensitive.mask.annotations声明注解黑名单SettingsManager解析为集合Application Server 在资源返回前经 gitops-engine 的hide()管线统一打码最终让 token 一类的敏感注解在 UI、API 层双双隐身。整个过程配置轻量一段 YAML、机制成熟复用 last-applied-configuration 管线、测试完备settings_test.go适合作为在受管集群中暴露敏感元数据场景下的即时缓解手段。【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考