Backstage Kubernetes 插件审计事件(Audit Events)完全指南:追踪集群与资源访问
【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage
Kubernetes 后端插件(@backstage/plugin-kubernetes-backend)内置了审计(Audit)能力,会对集群信息获取、资源查询以及 Kubernetes API 代理请求等操作产生结构化审计事件,帮助开发者追踪"谁在何时访问了哪些集群与资源"。本文将基于 docs/features/kubernetes/audit-events.md 展开,结合仓库源码与测试用例,完整梳理 Kubernetes 插件的cluster-fetch与resource-fetch两类事件、它们对应的 REST 端点、元数据字段、严重级别映射,以及如何通过配置让低级别事件进入日志,供安全审计与合规追踪使用。
审计事件机制概览:eventId + queryType 两级分组
Kubernetes 后端插件通过 Backstage 核心服务Auditor Service(docs/backend-system/core-services/auditor.md)发出审计事件。事件采用"两级分类"设计:
eventId:逻辑分组标识,代表一类操作集合。Kubernetes 插件目前使用cluster-fetch(集群信息获取)与resource-fetch(资源查询)两个eventId。meta.queryType:在某个eventId分组内部进一步区分具体操作类型,例如list、proxy、workloads、custom、services。
这种命名方式与 Auditor Service 官方约定一致(kebab-case 的eventId+meta字段细分动作),便于对审计日志按事件类型聚合、按查询类型过滤。从源码看,事件创建统一通过auditor.createEvent({ eventId, request, meta })完成,随后根据请求结果调用auditorEvent.success()或auditorEvent.fail({ error })收尾。
集群事件(Cluster Events):cluster-fetch
cluster-fetch用于记录与集群信息相关的操作,按queryType分为两类。
queryType: list— 获取已配置集群列表
- 触发端点:
GET /api/kubernetes/clusters - 默认严重级别:
low - 元数据:
queryType: 'list'
该事件在 KubernetesRouter.ts 的/clusters路由处理器中创建。处理流程为:先以kubernetesClustersReadPermission做权限校验,再通过clusterSupplier.getClusters()拉取集群明细并返回名称、标题、Dashboard URL、认证提供方等字段,最终调用auditorEvent.success();若权限校验或数据获取抛错,则调用auditorEvent.fail({ error })并向上抛出。
queryType: proxy— 代理请求 Kubernetes API
- 触发端点:
/api/kubernetes/proxy/* - 严重级别:
medium - 附加元数据:
clusterName(集群名)、method(HTTP 方法)、path(请求路径)
代理事件是唯一以medium级别记录的事件,其实现集中在 ProxyAuditSession.ts:每次代理请求进入 KubernetesProxy.ts 的请求处理器时,都会启动一个ProxyAuditSession,通过auditor.createEvent创建eventId: 'cluster-fetch'、severityLevel: 'medium'的事件,并携带clusterName、method、path三个元数据字段。
值得注意的实现细节:
- URL 脱敏:创建事件前会先剥离请求 URL 中的查询字符串(
split('?')[0]),避免 token 等敏感参数进入审计元数据(见 ProxyAuditSession.ts)。 - HTTP 与 WebSocket 双路径终结:普通 HTTP 代理请求通过监听响应对象的
finish/close事件自动终结审计会话,响应状态码 ≥ 400 或客户端提前断开时记为失败;WebSocket 升级请求则通过onProxyReqWs钩子(ProxyAuditSession.handleWebSocketProxyReq)在upgrade、response、error、socketclose等事件上挂接终结逻辑(见 KubernetesProxy.ts 与 ProxyAuditSession.ts)。代理中间件显式设置ws: false,正是为了让升级事件走 Express 路由、保证 WebSocket 请求也能被审计。 - 集群名修正:若请求头
Backstage-Kubernetes-Cluster指定的集群与实际解析目标不一致,终结时会用解析后的真实集群名覆盖clusterName元数据(见 ProxyAuditSession.ts)。
在 KubernetesRouter.test.ts 中,可以找到对上述事件的断言:list事件断言createEvent携带eventId: 'cluster-fetch'与meta: { queryType: 'list' },并验证success/fail的调用;proxy事件则断言severityLevel: 'medium'及queryType: 'proxy'元数据。
资源事件(Resource Events):resource-fetch
resource-fetch用于记录针对 Catalog 实体的 Kubernetes 资源查询,按queryType分为三种,默认严重级别均为low。除queryType外,还可以通过meta.entityRef元数据识别被查询的 Catalog 实体(格式为[kind]:[namespace]/[name],例如component:default/my-app)。
queryType: workloads— 查询实体的工作负载对象
- 触发端点:
POST /api/kubernetes/resources/workloads/query - 元数据:
queryType: 'workloads'、entityRef
实现在 resourcesRoutes.ts:路由处理器先从请求体取entityRef,随后通过kubernetesResourcesReadPermission鉴权,用catalog.getEntityByRef()解析实体,再调用objectsProvider.getKubernetesObjectsByEntity()获取对象并返回;成功调用auditorEvent.success(),任何异常(包括请求体缺少entityRef、实体不存在等InputError)都会走auditorEvent.fail({ error })。
queryType: custom— 查询实体的自定义资源
- 触发端点:
POST /api/kubernetes/resources/custom/query - 元数据:
queryType: 'custom'、entityRef
同样实现在 resourcesRoutes.ts。相比 workloads,它还校验请求体中的customResources字段:必须是数组且至少包含 1 项,否则抛出InputError("customResources is a required field" / "must be an array" / "at least 1 customResource is required")。校验通过后调用objectsProvider.getCustomResourcesByEntity()获取自定义资源。
queryType: services— 按服务查询对象(已废弃)
- 触发端点:
POST /api/kubernetes/services/:serviceId(标记@deprecated) - 元数据:
queryType: 'services'、entityRef、serviceId
该端点在 KubernetesRouter.ts 中实现,创建事件时除了entityRef还附带serviceId。其行为已被resource-fetch下的 workloads/custom 端点取代,新代码不应再依赖此端点。
在 resourceRoutes.test.ts 中,workloads 与 custom 两种queryType的事件创建、成功/失败收尾、以及请求体缺失时仍先创建审计事件再失败等行为均有完整测试覆盖。
严重级别与默认日志映射:为什么默认看不到低级别事件
Auditor Service 定义了四个严重级别(见 docs/backend-system/core-services/auditor.md):
| 严重级别 | 含义 | 默认映射日志级别 |
|---|---|---|
low | 低重要性事件,通常为信息或调试级别 | debug |
medium | 中等重要性事件,需要一定关注 | info |
high | 高重要性事件,可能暗示问题或安全事件 | info |
critical | 关键事件,需要立即关注 | info |
关键结论:默认情况下,Backstage 后端日志级别为info,而low级别事件(如cluster-fetch的list、全部resource-fetch事件)被映射为debug级别,因此默认不会出现在日志中。只有medium级别的cluster-fetch(proxy)事件会默认被记录。
配置:开启低级别审计事件日志
若希望看到list与resource-fetch事件,需要在app-config.yaml中将low严重级别映射到info日志级别:
backend: auditor: severityLogLevelMappings: low: info配置项位于backend.auditor.severityLogLevelMappings下,支持只覆盖单个级别而不改动其余映射。完整的四级配置示例如下:
backend: auditor: severityLogLevelMappings: low: debug medium: info high: warn critical: error需要注意该配置的作用范围是全局的:它会同时影响所有通过 Auditor Service 记录low级别事件的插件(例如软件目录插件的entity-fetch等低级别事件也会一并进入日志),因此在实际部署中应结合日志量与合规需求权衡。
审计事件的完整生命周期:create → success / fail
理解 Kubernetes 插件的审计事件,还需把握 Auditor Service 的使用模式(同样适用于任何接入审计的插件):
const auditorEvent = await auditor.createEvent({ eventId: 'resource-fetch', request: req, meta: { queryType: 'workloads', entityRef }, }); try { // ...鉴权与业务处理 await auditorEvent.success(); } catch (error) { await auditorEvent.fail({ error }); throw error; }从 Kubernetes 插件的源码与测试可以归纳出几个一致的工程实践:
- 先创建事件,再执行业务逻辑:即使后续鉴权失败或请求体缺失,事件也必须存在,以便完整记录失败的访问尝试(测试用例中专门验证了"请求体缺失时仍先创建事件再 fail")。
- success/fail 二选一:成功路径调用
success(),任何异常路径调用fail({ error }),二者互斥。 - 审计失败不影响业务:
success()或fail()的日志发出失败仅记录 error 日志,不会改变 HTTP 响应结果;测试中也有audit success emission rejects时仍返回 200 的用例。 - 代理类长连接事件异步终结:代理请求的事件在响应完成或 WebSocket 连接终结时才被 finalize,避免长连接期间阻塞。
实践建议与排查指引
- 快速验证事件是否生效:完成上述
severityLogLevelMappings配置并重启后端后,访问/api/kubernetes/clusters或任一资源查询端点,观察后端日志中是否出现包含eventId与queryType的审计记录。 - 区分事件来源:想单独观察代理流量审计,可直接查看
medium级别的cluster-fetch(queryType: proxy)事件,其clusterName、method、path元数据可还原一次完整的 Kubernetes API 代理调用。 - 按实体追踪资源访问:审计日志中的
entityRef字段(格式[kind]:[namespace]/[name])可用于按 Catalog 实体聚合资源访问记录,定位特定组件被查询的时间与频率。 - 版本注意:
POST /api/kubernetes/services/:serviceId已标记@deprecated,请以 workloads/custom 端点为准进行监控与告警配置。
通过上述机制,Backstage Kubernetes 插件能够为集群访问提供一条结构清晰、可按eventId/queryType过滤、包含实体与集群上下文的审计链路;结合 Auditor Service 的严重级别映射,运维与安全团队可以按需控制审计日志的粒度,实现集群与资源访问的可观测与可追溯。
【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考