摘要

  • RFC 9682 允许一个 CDDL 文件不含规则,但要求在全部指令处理完毕后,仍有规则提供模型入口。放宽的是输入文件的语法,不是最终结果的完整性。
  • 模块化把依赖来源、查找环境和入口选择带入验收范围。管理者应问清楚验证针对哪个组装结果,而不只索取一份“文件检查通过”的记录。

一份检查表最容易获得的权威,是它已经用了很久。后来系统允许把一个整体拆成多个组件,检查表却仍要求每个组件都具备完整系统的属性。执行得越严格,越可能逼出一些只为通过检查而存在的多余内容。

CDDL 的一处语法调整,为这种组织问题提供了一个很小、也很准确的观察窗口。描述数据结构的文件,可以只是组装的起点;它未必需要在自身内部写出最后会用到的全部规则。若仍按独立文件的标准审查每一份输入,就把整体责任错误地分摊到了零件上。

然而,反方向的误读同样危险:既然文件可以是空的,是否就不必再检查完整模型有没有入口?不是。真正发生的是检查后移,不是要求撤销。

一位数字的去留,改变的是检查时点

ABNF 用重复次数表示一个元素至少或至多出现几次。最低次数不写,默认可以为零;写出最低一次,则不能没有。这里讨论的是语法能否接收输入,不是业务意义上的“没有内容也算完成”。RFC 5234 第 3.6 节

2024 年 11 月发布的 RFC 9682 在第 3.1 节放宽了 CDDL 顶层规则数量,因为模块指令可能提供最终需要的全部规则。它明确把“至少有规则提供入口”的条件保留为全部指令处理之后的语义约束。附录 B.2 对带限定符的字节串也采用分阶段处理,先解析外部语法,再处理内容意义。RFC 9682

这与“数据格式正确,却未必真实”不是同一个问题。这里尚未走到判断数据是否匹配模型的阶段,而是在确定一个可用的模型是否已经形成。不能把空 CDDL 文件当成无条件接受所有数据的完整模型,也不能随手补一条无关规则,假装入口问题已经解决。

基础 CDDL 以最先定义的规则作为根,该规则必须是类型,不能是组;规则名称并不必须叫 start。应用决定对数据描述执行多深的检查,又是另一层选择。RFC 8610 第 2.2.4、4.2 与 5 节

因此,“已经有一条规则”仍然只是必要信息,而不是充分的验收结论。选中的是否是预期类型?改变排列或组装方式后,入口有没有变化?这些问题应该针对最终模型回答,不能由某一份文件的非空状态代答。

模块名称背后还有一个工作环境

截至 2026 年 9 月 7 日,本次研究查到的模块方案是 9 月 2 日的 draft-ietf-cbor-cddl-modules-07。它仍是工作草案,不是已经发布的 RFC;RFC 9682 当时引用的是较早版本。

草案把指令放进基础工具可视作注释的文本中,并提供规则导入、包含与命名空间处理。它没有统一规定所有环境的来源目录及优先顺序。文中的一个工具示例先查当前目录,再查自身集合;另一个示例通过命令行指定根,即使不提供输入文件,也能产生带合成首条规则的模型。这些是文档示例,不是本文执行过的测试。CDDL 模块结构草案,第 07 版

这使得验收对象不能仅是一张写着模块名称的清单。同名文件在不同环境中可能指向不同内容;同一组规则也可能因为入口选择而承担不同作用。命名空间减少名称碰撞,但不自动说明内容由谁提供,更不自动证明选中的入口适用于当前用途。

设想一个没有对应真实事故的采购场景:供应商交出顶层文件,客户在自己的环境中补齐依赖。供应商证明的是自己环境里的一次组装,客户实际运行的却是另一套来源。即使附件本身没有被改过,两边也未必在检验同一个对象。

这不必从恶意攻击开始。一个本地目录里留下的新版定义,一次工具升级带来的内置集合变化,一项无人记录的搜索顺序,都可能让“还是那个文件”成为误导。问题在于,影响模型的选择已经超出文件边界,审查证据却没有同步扩展。

不要用多余规则消灭报警

面对旧检查表造成的阻碍,最省事的办法可能是在每个组件里添一条默认规则。这样做的成本未必立即显现:它会让后来的人误以为组件确有一个经过设计的独立入口,也可能掩盖真正的组合入口根本未被审查。

更合理的做法,是把证据绑到它实际说明的阶段。输入解析成功,说明输入语法被接收;依赖解析完成,说明组装所需的来源得到处理;形成预期入口的完整模型,才回答后移的那道问题。这些工作可以由同一套工具完成,不必拆成三个部门,但结果不能合并成一个含义模糊的“通过”。

本文建议保存一份可复核的组装记录,包括来源内容、查找配置、处理器版本、根选择和最终模型。它不是 RFC 新增的行政要求,而是减少重建成本的方法。只保存顶层文件,会把未来复核的费用转嫁给还记得当时环境的人。

证据也有边界。这里没有某家厂商的故障统计、已验证的漏洞或普及率调查,也没有对生产系统进行实验。标准说明了为什么检查可以后移;管理上的推论是,后移之后必须仍能找到那个检查、它针对的对象和负责解释结果的人。