Backstage TechDocs 生成流程中的 MkDocs 配置校验机制从变更集到源码实现【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage本文以 Backstage 仓库中的变更集 .changeset/tidy-maps-smile.md 为切入点解析backstage/plugin-techdocs-node在 TechDocs 文档生成阶段对 MkDocs 配置文件实施的校验逻辑。读完后你将能够理解 TechDocs 生成流水线在拉取文档源码后、执行mkdocs build之前所经过的三道安全校验YAML 标签过滤、docs_dir路径约束、配置键白名单并知道如何编写一份合规的mkdocs.yml以避免文档生成被安全规则拦截。变更集背景一次针对 TechDocs 的 patch 级改进该变更集全文如下--- backstage/plugin-techdocs-node: patch --- Improved validation of MkDocs configuration values during TechDocs generation.它声明了backstage/plugin-techdocs-node包的一次patch级别变更改进 TechDocs 生成过程中对 MkDocs 配置值的校验。Backstage 使用 changesets 管理版本发布.changeset/目录下的每个 Markdown 文件对应一个待发布的功能改进或修复发布时由 scripts/create-release-changelog.js 等脚本聚合生成 plugins/techdocs-node/CHANGELOG.md 中的版本记录。TechDocs 是 Backstage 的文档系统它从实体标注的backstage.io/techdocs-ref指向的源码位置拉取文档在 Docker 容器内运行 MkDocs 构建静态站点再发布到配置的存储后端。正因为构建输入来自外部仓库、且 MkDocs 本身支持插件、主题、Markdown 扩展等可定制能力MkDocs 配置文件的校验就成为生成链路中不可跳过的一环。校验发生的位置generate 阶段的安全前置检查TechDocs 的生成阶段由 plugins/techdocs-node/src/stages/generate/techdocs.ts 驱动。从源码结构看容器内构建前的关键顺序是确定配置文件路径优先mkdocs.yaml其次mkdocs.yml两者同时存在时会记录告警并使用其一读取文件内容后第一时间执行docs_dir校验执行sanitizeMkdocsYml按白名单剥离不支持的配置键根据techdocs-ref标注打补丁如注入repo_url、edit_uri再运行 MkDocs 构建命令。对应源码片段techdocs.ts// validate the docs_dir first const docsDir await validateMkdocsYaml(inputDir, content); // Remove unsupported configuration keys await sanitizeMkdocsYml( mkdocsYmlPath, childLogger, this.options.dangerouslyAllowAdditionalKeys, );可以看到校验validateMkdocsYaml先于净化sanitizeMkdocsYml执行路径越界这类安全问题直接抛错终止构建而未知配置键则被降级处理、剥离后继续构建。这种“硬性拦截 柔性净化”的分层策略正是本次改进的核心。第一道闸门YAML 解析与 Python 标签过滤MkDocs 生态尤其是 mkdocs-material 主题大量使用 PyYAML 特有的标签语法例如theme: name: material palette: - media: (prefers-color-scheme: light) scheme: default primary: indigo icon: repo: fontawesome/brands/githubBackstage 在 helpers.ts 中定义了MKDOCS_SCHEMA——在 js-yaml 的DEFAULT_SCHEMA基础上扩展了自定义标量、mapping、sequence 的tag:处理。解析时任何以tag:yaml.org,2002:python/开头的标签都会进入UnknownTag构造函数并被与白名单比对const ALLOWED_PYTHON_YAML_TAGS new Set([ tag:yaml.org,2002:python/name:materialx.emoji.twemoji, tag:yaml.org,2002:python/object.apply:materialx.emoji.to_svg, tag:yaml.org,2002:python/object/apply:pymdownx.slugs.slugify, ]);白名单只放行 material 主题的 emoji 转换与 pymdownx 锚点 slug 生成这两个在 TechDocs 场景中确有其用的标签其余python/标签一律抛出Unsupported Python YAML tag错误。这一设计的意义在于如果直接交给 Python 端的 PyYAML 解析恶意构造的!!python/object/apply:os.system之类标签可能触发任意代码执行在 Node 侧提前用白名单收窄从源头切断了这条攻击面。第二道闸门docs_dir路径越界校验validateMkdocsYamlhelpers.ts#L357-L381负责检查docs_dir的值export const validateMkdocsYaml async ( inputDir: string, mkdocsYmlFileString: string, ): Promisestring | undefined { const mkdocsYml yaml.load(mkdocsYmlFileString, { schema: MKDOCS_SCHEMA }); if (mkdocsYml null || typeof mkdocsYml ! object) { return undefined; } const parsedMkdocsYml: Recordstring, any mkdocsYml; if ( parsedMkdocsYml.docs_dir !isChildPath(inputDir, resolvePath(inputDir, parsedMkdocsYml.docs_dir)) ) { throw new Error( docs_dir configuration value in mkdocs cant be an absolute directory or start with ../ for security reasons. Use relative paths instead which are resolved relative to your mkdocs.yml file location., ); } return parsedMkdocsYml.docs_dir; };规则很直接docs_dir解析后必须仍位于文档输入目录inputDir之内借助backstage/backend-plugin-api的isChildPath判定。这会把两类危险写法直接拦截绝对路径如docs_dir: /etc——试图让构建读取容器内任意目录相对路径回退出输入目录如docs_dir: ../../etc/——典型的目录穿越。校验通过后返回的docs_dir未配置时为undefined下游按 MkDocs 默认值docs处理还会被用于后续推导源码仓库的edit_uri。仓库内配套的测试夹具直观展示了这三类场景合规mkdocs_valid_doc_dir.yml 中docs_dir: docs/违规一mkdocs_invalid_doc_dir.yml 中docs_dir: /etc违规二mkdocs_invalid_doc_dir2.yml 中docs_dir: ../../etc/。单元测试 helpers.test.ts 中对两份违规夹具分别断言抛出上述错误信息同时验证合法配置能正确返回docs_dir值构成了这条校验路径的回归保障。第三道闸门配置键白名单净化校验之外TechDocs 还通过白名单机制收敛 MkDocs 配置的“自由度”。helpers.ts 中定义了三组关键集合ALLOWED_MKDOCS_KEYS顶层允许的 21 个键涵盖站点信息site_name、site_url、site_description、site_author、仓库链接repo_url、repo_name、edit_uri、edit_uri_template、构建目录docs_dir、site_dir、文档结构nav、exclude_docs、not_in_nav、构建设置theme、plugins、markdown_extensions、extra、extra_css、预览控制use_directory_urls、strict、dev_addr、watch、元数据copyright、remote_branch、remote_name、validation以及保留的弃用键google_analyticsALLOWED_THEME_KEYStheme下允许的键如name、font、icon、logo、favicon、language、direction、palette、featuresDANGEROUS_EXTENSION_CONFIG_KEYS嵌套在markdown_extensions配置中必须剥离的键当前为plantuml_cmd——该选项允许 Markdown 扩展在构建时执行外部 PlantUML 命令属于典型的“配置即命令执行”入口被明确列为危险项。sanitizeMkdocsYml实现于 mkdocsPatchers.ts依据这些集合改写配置白名单之外的键会被移除并记录日志而不是直接失败同时 techdocs.ts 中透传的dangerouslyAllowAdditionalKeys选项表明确有特殊需求的部署方可通过显式开关放宽这一限制——默认路径上则保持最严格姿态。另外techdocs-node的输入目录校验validateInputDirectoryhelpers.ts#L393 起会递归检查输入目录中是否存在指向外部目录的符号链接源码注释说明其覆盖整个输入目录而非仅docs目录原因是“MkDocs 扩展可以读取输入目录内的任意文件”。它与上述三道闸门共同构成了容器构建前的输入面收敛。配置文件发现与默认生成规则校验作用的对象是getMkdocsYmlhelpers.ts#L224-L280定位到的配置文件其查找顺序为显式指定的mkdocsConfigFileName不存在时直接报错The specified file ... does not exist输入目录下的mkdocs.yaml输入目录下的mkdocs.yml均不存在时调用generateMkdocsYml现场生成一份最小配置configIsTemporary标记为true。自动生成的默认配置非常精简helpers.ts#L188-L213site_name: Documentation Site # 可被 siteOptions.name 覆盖 docs_dir: docs plugins: - techdocs-coretechdocs-core是 TechDocs 注入的核心插件负责渲染 Backstage 特有的页面如文档首页与导航。因此对于大多数仓库只需在docs/下放置 Markdown 即可被构建要启用主题、扩展或自定义导航则必须提供自己的mkdocs.yml/mkdocs.yaml且配置键需落在白名单之内。对文档维护者的实操指引结合本次“改进 MkDocs 配置值校验”的变更文档维护者在编写mkdocs.yml时建议遵循以下约束这些都能在源码中找到一一对应的拦截/净化逻辑写法结果对应源码依据docs_dir: docs/输入目录内相对路径通过validateMkdocsYaml的isChildPath判定docs_dir: /etc或docs_dir: ../../x/抛错终止构建错误信息“cant be an absolute directory or start with ../”theme:中使用python/object/apply:...等 PyYAML 标签白名单外标签抛Unsupported Python YAML tagALLOWED_PYTHON_YAML_TAGS配置markdown_extensions中的plantuml_cmd被sanitizeMkdocsYml剥离DANGEROUS_EXTENSION_CONFIG_KEYS使用extra_javascript、search等未列入白名单的顶层键被剥离并记录日志非报错ALLOWED_MKDOCS_KEYS输入目录中放了指向目录外的符号链接被validateInputDirectory拦截helpers.ts#L383-L397需要说明的前提是以上校验在 Docker 容器内构建之前、由techdocs-node的 generate 阶段执行若你的部署启用了dangerouslyAllowAdditionalKeys未知配置键的剥离行为会相应放宽但docs_dir路径校验与危险键剥离仍是强制项。小结这个仅有一句话描述的 patch 变更集背后对应的是 TechDocs 生成链路上一组分层清晰的安全机制YAML 解析层的 Python 标签白名单、docs_dir的路径越界硬性拦截、配置键与危险扩展选项的白名单净化以及输入目录的符号链接检查。理解这套机制不仅能帮助开发者快速定位“我的 mkdocs 配置为什么没生效”多半是被静默剥离也能在定制 TechDocs 生成流程时明确哪些边界是不可突破的。所有关键实现集中在 plugins/techdocs-node/src/stages/generate/ 目录下配合 helpers.test.ts 与__fixtures__/中的 MkDocs 配置夹具可以完整追溯校验逻辑的行为与边界。【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考