news 2026/9/13 5:44:01

Backstage v1.36.0-next.0 深度解读:auditor 审计服务、PermissionsRegistry 与原生 ESM 支持

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Backstage v1.36.0-next.0 深度解读:auditor 审计服务、PermissionsRegistry 与原生 ESM 支持

Backstage v1.36.0-next.0 深度解读:auditor 审计服务、PermissionsRegistry 与原生 ESM 支持

【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage

本篇技术解读以 docs/releases/v1.36.0-next.0-changelog.md 为骨架,围绕 Backstage 1.36.0 首个预发布版本(next.0)的核心变更展开:全新的auditor核心服务与PermissionsRegistryService如何重塑后端插件的能力边界,CLI 原生 ESM 支持带来的破坏性变更应如何迁移,以及 Canon、TechDocs 自定义首页等前端增强的实战用法。读完本文,你将掌握本版本中每个破坏性变更的迁移要点,并能直接落地 auditor 事件埋点与权限规则注册的完整代码。

版本总览:一次面向新后端系统的能力升级

v1.36.0-next.0 是一轮覆盖后端服务、CLI 工具链与前端组件体系的预发布迭代,其中几个关键包的版本变化直接决定了升级工作的规模:

新版本变更级别核心内容
@backstage/backend-plugin-api1.2.0-next.0Minor新增auditor服务定义与PermissionsRegistryService
@backstage/backend-defaults0.8.0-next.0Minor提供auditor服务的默认实现
@backstage/backend-test-utils1.3.0-next.0Minor为两个新服务提供测试 mock
@backstage/cli0.30.0-next.0BREAKINGNode.js 代码原生 ESM 支持
@backstage/canon0.1.0-next.0首个 alphaCanon 组件库首次发布
@backstage/plugin-catalog-backend1.31.0-next.0Minor接入PermissionsRegistryServiceauditor
@backstage/plugin-scaffolder-backend1.30.0-next.0Minor接入auditor服务
@backstage/plugin-techdocs-node1.13.0-next.0MinorAWS S3 发布器支持可配置重试

此外,@backstage/plugin-catalog-node@1.15.2-next.0正式弃用了 alpha 状态的catalogPermissionExtensionPoint及相关类型,其功能已由新的PermissionsRegistryService完全取代。

auditor 服务:为后端插件引入统一审计能力

本版本最核心的架构级变更,是在 packages/backend-plugin-api/src/services/definitions/AuditorService.ts 中新增的AuditorService接口,并通过coreServices.auditor(id 为core.auditor,见 coreServices.ts)暴露给所有后端插件。

服务接口与事件模型

从源码定义看,AuditorService只暴露一个方法:

export interface AuditorService { createEvent( options: AuditorServiceCreateEventOptions, ): Promise<AuditorServiceEvent>; }

createEvent接收的事件选项包含四个字段:

  • eventId(必填):采用 kebab-case 命名(如user-loginfile-downloadfetch),表示一组相似事件或操作的逻辑聚合。例如fetch可作为事件 ID,涵盖by-idby-location等多种具体取数方式。由于pluginId已提供插件/模块上下文,eventId中应避免冗余的前缀。
  • severityLevel(可选):事件严重级别,取值与含义在源码注释中明确给出:
    • low(默认):常规使用
    • medium:访问写端点
    • high:非 root 权限变更
    • critical:root 权限变更
  • request(可选):关联的 HTTP 请求对象(expressRequest)。
  • meta(可选):附加元数据,结构化 JSON 对象。其中可含queryType字段(同样使用 kebab-case),用于表达主事件内的变体,例如eventIdfetch时,meta.queryType可为by-idby-location

createEvent返回一个AuditorServiceEvent,它提供了显式的成功/失败回调:

export type AuditorServiceEvent = { success(options?: { meta?: JsonObject }): Promise<void>; fail(options: { meta?: JsonObject; error: Error }): Promise<void>; };

这种"先创建、后标记成败"的模型,让插件可以在操作的整个生命周期内携带审计上下文,最终以成功或失败两种状态落盘。

默认实现与日志输出

默认实现位于 packages/backend-defaults/src/entrypoints/auditor/auditorServiceFactory.ts。从源码可以确认其依赖与行为:

  • 服务工厂依赖rootConfigloggerauthhttpAuthpluginMetadata五个核心服务;
  • 它基于logger.child({ isAuditEvent: true })派生专用审计日志器,审计事件会统一打上isAuditEvent: true标记,便于日志采集系统区分;
  • 日志记录键为`${event.plugin}.${event.eventId}`,即插件 ID 与事件 ID 拼接;
  • 事件失败时('error' in event),错误对象会被单独作为第二个参数传给日志方法;
  • 严重级别到日志级别的映射由getSeverityLogLevelMappings(config)从配置中解析,意味着审计日志的落盘级别可随配置调整。

插件集成现状

从变更日志看,auditor服务已在本版本中完成首批落地:

  • plugins/catalog-backend:Catalog 插件接入auditor服务(变更 a4aa244);
  • plugins/scaffolder-backend:Scaffolder 插件接入auditor服务(变更 a4aa244)。

对于插件开发者,接入审计服务的方式是在插件或模块中通过依赖注入获取coreServices.auditor,例如:

import { coreServices, createBackendModule } from '@backstage/backend-plugin-api'; createBackendModule({ pluginId: 'my-plugin', moduleId: 'audit-demo', register(env) { env.registerInit({ deps: { auditor: coreServices.auditor }, async init({ auditor }) { const event = await auditor.createEvent({ eventId: 'fetch', severityLevel: 'low', meta: { queryType: 'by-id' }, }); try { // 执行业务操作... await event.success(); } catch (error) { await event.fail({ error }); } }, }); }, });

测试支撑

packages/backend-test-utils 为auditor服务提供了现成的 mock(变更 a4aa244),相关单元测试(如DefaultAuditorService.test.tsWinstonRootAuditorService.test.tsauditorServiceFactory.test.ts,均位于 packages/backend-defaults/src/entrypoints/auditor)也随实现一同落地,可在测试中直接验证事件的成功/失败路径。

PermissionsRegistryService:权限注册的新标准入口

第二个关键架构变更是PermissionsRegistryService,其接口定义在 packages/backend-plugin-api/src/services/definitions/PermissionsRegistryService.ts,通过coreServices.permissionsRegistry(id 为core.permissionsRegistry)暴露。它取代了原先通过createPermissionIntegrationRouter(来自@backstage/plugin-permission-node)注册权限的模式。

四个核心方法

从源码看,该服务提供四个方法:

  1. addPermissions(permissions: Permission[]):为插件向权限系统注册权限。
  2. addPermissionRules(rules: PermissionRule<any, any, string>[]):为插件拥有的资源类型注册一组权限规则。规则应使用各插件导出的create*PermissionRule函数创建(这些函数本身由makeCreatePermissionRule派生),插件自身或其模块均可添加规则。
  3. addResourceType(options):注册一个新的资源类型,其选项包括:
    • resourceRef:标识资源类型的PermissionResourceRef
    • permissions:该资源类型可用的权限列表;
    • rules:该资源类型可用的权限规则数组,描述如何过滤资源列表(如 Catalog 的isEntityOwnerhasAnnotation),并支持以特定参数构造条件;
    • getResources:根据引用标识符加载关联资源的函数。若未提供,权限系统将无法解析条件化授权决策(除非直接从插件请求资源)。
  4. getPermissionRuleset(resourceRef):返回已注册的规则集,主要用于配合createConditionAuthorizercreateConditionTransformer使用。

源码注释以 Catalog 为例说明了addResourceType的语义:Catalog 围绕对具体实体的访问有条件规则,resourceType是像catalog-entity这样的字符串标识,它只是用于校验授权策略中条件构造正确性的"类型",而非对具体资源的引用。

集成与弃用

  • plugins/catalog-backend 已支持通过新的PermissionsRegistryService添加自定义权限规则(变更 8805f93);
  • plugins/catalog-backend-module-unprocessed 改用新服务替代已弃用的catalogPermissionExtensionPoint(变更 4e073c7);
  • plugins/catalog-node 弃用了 alpha 状态的catalogPermissionExtensionPoint及相关类型(变更 4a941e7);
  • 默认实现与工厂测试位于 packages/backend-defaults/src/entrypoints/permissionsRegistry;
  • 配套地,@backstage/plugin-permission-node@0.8.8-next.0createPermissionIntegrationRouter返回的路由器变为可变对象,允许在创建之后继续添加权限与资源(变更 049d5d4),为过渡期提供兼容空间。

@backstage/backend-test-utils同样为本服务提供了 mock(变更 dd05a97)。

破坏性变更:CLI 原生 ESM 支持

@backstage/cli@0.30.0-next.0引入了 Node.js 代码的原生 ESM 支持(变更 cb76663),这是本轮升级中最需要关注的手工迁移点。

行为变化

原生 ESM 支持改变了 Node.js 代码中动态导入表达式的行为:动态import(...)将不再被转译为require(...),而是原样保留。这带来的能力提升包括:

  • 允许从 CommonJS 代码中通过动态导入加载 ESM 模块;
  • .mjs/.mts作为显式 ESM 文件,.cjs/.cts作为显式 CommonJS 文件;
  • 支持在package.json中声明"type": "module"将包标记为 ESM 包。

上述能力在类型检查、包构建、运行时转换与 Jest 测试中全部生效。

迁移要点

对于大多数插件/应用代码,修复方式是把import(...)替换为require(...),需要类型时再配合as typeof import(...)断言:

// 之前(会被转译为 require) const mod = await import('./some-module'); // 之后(原生动态导入) const mod = require('./some-module') as typeof import('./some-module');

四个重要注意事项

根据变更日志,以下 caveat 需要特别注意:

  1. 测试启用原生 ESM 需要--experimental-vm-modules:通常在运行测试时通过NODE_OPTIONS='--experimental-vm-modules'注入。
  2. "type": "module"的传染效应:在package.json中声明"type": "module"是受支持的,但在测试环境中,它会将所有本地传递依赖也视为 ESM——无论这些依赖自身是否声明了"type": "module"
  3. ESM 互操作层的启用条件:Node.js 的 ESM/CommonJS 互操作层仅在导入带.cts.cjs扩展名的包时启用。原因是该互操作层与 NPM 生态并不完全兼容,若对.js文件启用会破坏包。
  4. 避免动态导入 CommonJS 包:动态导入 CommonJS 包的结果形状会随运行环境(测试 vs 本地开发等)变化。因此建议改用require,或使用上述显式 CommonJS 扩展名;如果确实需要动态导入 CommonJS 包,应避免使用default导出,因为其形状在不同环境间不一致,否则需要根据模块对象的形状手动解包。

此外,@backstage/cli-node@0.2.13-next.0同步在BackstagePackageJson类型中增加了type字段,@backstage/config-loader@backstage/backend-defaults等包也进行了显式require的懒加载重构(变更 f866b86)。

Canon:全新组件库的首个 alpha

@backstage/canon@0.1.0-next.0是 Canon 的首次 alpha 发布(变更 65f4acc),本次引入:

  • 5 个布局(layout)组件
  • 7 个通用组件
  • 所有主题化均通过CSS 变量完成。

这意味着开发者可以在不引入 Material UI 主题上下文的前提下,通过 CSS 变量对 Canon 组件进行风格定制,适合对样式控制粒度有更高要求的场景。

TechDocs 自定义首页能力增强

plugins/techdocs 在本次迭代中大幅增强了文档首页的自定义能力(变更 1f40e6b):

TechDocsCustomHome 新增可选 props

TechDocsCustomHome现在支持通过tabsConfig配置多标签页的文档聚合页,并通过filter精确筛选实体。一个完整的配置示例(来自变更日志):

import { TechDocsCustomHome } from '@backstage/plugin-techdocs'; //... const options = { emptyRowsWhenPaging: false }; const linkDestination = (entity: Entity): string | undefined => { return entity.metadata.annotations?.['external-docs']; }; const techDocsTabsConfig = [ { label: 'Recommended Documentation', panels: [ { title: 'Golden Path', description: 'Documentation about standards to follow', panelType: 'DocsCardGrid', panelProps: { CustomHeader: () => <ContentHeader title='Golden Path'/> }, filterPredicate: entity => entity?.metadata?.tags?.includes('golden-path') ?? false, }, { title: 'Recommended', description: 'Useful documentation', panelType: 'InfoCardGrid', panelProps: { CustomHeader: () => <ContentHeader title='Recommended' /> linkDestination: linkDestination, }, filterPredicate: entity => entity?.metadata?.tags?.includes('recommended') ?? false, }, ], }, { label: 'Browse All', panels: [ { description: 'Browse all docs', filterPredicate: filterEntity, panelType: 'TechDocsIndexPage', title: 'All', panelProps: { PageWrapper: React.Fragment, CustomHeader: React.Fragment, options: options }, }, ], }, ]; const AppRoutes = () => { <FlatRoutes> <Route path="/docs" element={ <TechDocsCustomHome tabsConfig={techDocsTabsConfig} filter={{ kind: ['Location', 'Resource', 'Component'], 'metadata.annotations.featured-docs': CATALOG_FILTER_EXISTS, }} CustomPageWrapper={({ children }: React.PropsWithChildren<{}>) => (<PageWithHeader title="Docs" themeId="documentation">{children}</PageWithHeader>)} /> } /> </FlatRoutes>; };

新增 InfoCardGrid 与独立 CustomDocsPanel

  • 新增网格选项InfoCardGrid:更可定制的文档卡片网格,支持自定义linkContentlinkDestination
<InfoCardGrid entities={entities} linkContent="Learn more" linkDestination={entity => entity.metadata['external-docs']} />
  • 原有的CustomDocsPanel被导出,可独立使用。借助PanelConfig数组,开发者可以灵活拼装不同 panel 类型:
const panels: PanelConfig[] = [ { description: '', filterPredicate: entity => {}, panelType: 'InfoCardGrid', title: 'Standards', panelProps: { CustomHeader: () => <ContentHeader title='Recommended' /> linkDestination: linkDestination, }, }, { description: '', filterPredicate: entity => {}, panelType: 'DocsCardGrid', title: 'Contribute', }, ]; { panels.map((config, index) => ( <CustomDocsPanel key={index} config={config} entities={!!entities ? entities : []} index={index} /> )); }

其他 TechDocs 修复

  • addLinkClickListener的基础 URL 从window.location.origin改为app.baseUrl(变更 f4be934),修复了 Backstage 运行在子路径(subpath)时无法正确处理同源非 Backstage URL 的问题;
  • plugins/techdocs-node 与@techdocs/cli@1.9.0-next.0支持为 AWS S3 发布操作配置可选重试(变更 8de3d2d)。

其余值得关注的变更

本轮还包含一系列影响面较小但值得留意的更新:

  • Scaffolder 任务上下文新增taskId:plugins/scaffolder-node 的TaskContext增加可选taskId属性(变更 a4aa244),相关类型定义可见 plugins/scaffolder-node/src/alpha/index.ts,为任务级操作(如按taskId清理工作区)提供依据。
  • 通知系统主题过滤@backstage/plugin-notifications@backstage/plugin-notifications-backend新增 topic 过滤器(变更 438c36c)。
  • 搜索过滤扩展点@backstage/plugin-search@backstage/plugin-search-react新增SearchFilterBlueprintSearchFilterResultTypeBlueprint,可扩展搜索过滤与结果类型(变更 63e1012)。
  • Kubernetes 额外对象抓取@backstage/plugin-kubernetes-backend支持指定默认对象之外的其他 Kubernetes 对象,以补充secrets等资源的获取(变更 ac0e1ac)。
  • Catalog 稳定性修复
    • stitching 期间良性数据库冲突错误降级为 debug 级日志(变更 c9139e1);
    • 清理不再控制某refresh_state行的 processor/provider 对应的refresh_state_references(变更 f178b12);
    • 搜索索引的 location URL 生成改用encodeURIComponent编码实体属性值,提升 URL 安全性与可靠性(变更 eee8d76)。
  • 前端应用树 APIfrontend-app-apifrontend-plugin-apiAppTreeApi新增getNodesByRoutePath方法(变更 3e21b8d)。
  • Scaffolder 组件修复:修复BitbucketRepoBranchPicker导致页面崩溃的问题(变更 3107f1f);makeFieldSchema返回值新增 schema 输出返回类型(变更 3edf7e7)。
  • repo-toolsapi-reports命令新增--sql-reports标志,可生成 SQL 报告(变更 98ddf05)。
  • 后端动态特性服务:packages/backend-dynamic-feature-service 确保变更被成功跟踪后再启动扫描器(变更 96c20cd)。

升级路径建议

基于以上变更,从 v1.35.x 升级到 v1.36.0 正式版前,建议按以下顺序自查:

  1. 优先处理 CLI ESM 迁移:全局搜索仓库中的动态import(...)调用,评估是否涉及 ESM 模块加载;按照"用require替代 +as typeof import保类型"的模式逐一替换;若测试需要原生 ESM,为 Jest 配置NODE_OPTIONS='--experimental-vm-modules',并注意"type": "module"在测试中的传递性影响。
  2. 评估权限注册迁移:若插件使用了catalogPermissionExtensionPoint,迁移到coreServices.permissionsRegistry;若使用了createPermissionIntegrationRouter,注意其返回路由器已变为可变对象,可按需渐进迁移。
  3. 关注服务版本对齐backend-plugin-apibackend-defaultsbackend-test-utils三个包必须同步升级到 1.2.0 / 0.8.0 / 1.3.0 的 next 版本线,否则新服务引用无法解析。
  4. 验证 TechDocs 行为变化:若运行在子路径部署,升级后验证文档内链接跳转行为符合预期。

完整变更条目可随时查阅仓库内的 docs/releases/v1.36.0-next.0-changelog.md;升级前建议结合 docs/releases/v1.35.0-changelog.md 确认上一版本的已知问题。

【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 5:43:23

基于PSO算法的配电网无功优化与工程实践

1. 配电网无功优化问题背景与挑战配电网作为电力系统的末端环节&#xff0c;其运行效率直接影响着供电质量和能源损耗。在传统配电网中&#xff0c;无功功率的不平衡会导致电压波动、线路损耗增加等问题。以IEEE 33节点系统为例&#xff0c;当无功补偿不足时&#xff0c;线路末…

作者头像 李华
网站建设 2026/9/13 5:42:35

论文AI率超标怎么办?2026年5个免费降AI工具保姆级指南

每到毕业答辩、论文提交的关键节点&#xff0c;我的消息框就被刷爆——“有没有靠谱的降AI率工具&#xff1f;哪款降AI效果最稳&#xff1f;”太懂这种崩溃感了&#xff01;熬了好几个大夜写出来的论文&#xff0c;一查AI率直接飙到90%&#xff0c;导师一句“重新修改”&#x…

作者头像 李华
网站建设 2026/9/13 5:41:43

ADHD生存操作系统:神经多样性适配的工程化实践

1. 项目概述&#xff1a;这不是一句玩笑话&#xff0c;而是一份真实存在的生活操作系统说明书“i-have-adhd”——当它作为一句短语出现在社交平台、评论区、甚至简历备注栏里&#xff0c;很多人第一反应是&#xff1a;“又一个网络梗&#xff1f;”但如果你真把它当成梗来刷&a…

作者头像 李华