摘要
- JSON Type Definition 判断实例是否符合一份刻意受限的结构契约;通过校验是关于形状的证据,不是关于事实或权力的证据。
- 八种互斥形式、逐层生效的未知字段政策和双指针错误格式,通过拒绝诱人的歧义来换取可移植代码生成。
- 生产治理从模式校验结束处开始:发送者身份、行为授权、领域不变量、重放、持久化与结果必须分别核验。
一条删除账户的事件到达系统。事件类型是字符串,账户编号存在,时间戳格式正确,没有多余字段。校验器返回空错误列表。此时最危险的一句话是:“这条消息有效,所以账户已经删除。”
RFC 8927 给“有效”划了一条精确边界。JSON Type Definition(JTD)能证明一个 JSON 实例与某份模式之间的结构关系:字段是否存在、整数是否落在范围内、标签是否选择了允许的分支。它不能证明账户真的存在,时钟可信,发送者有权删除,命令没有被重放,更不能证明存储层已经执行。
这种有限性不是缺陷,而是可移植性的来源。
小语言给出较清楚的承诺
RFC 8927 属于 Independent Stream,状态是 Experimental;它没有 IETF 共识,也不是 Standards Track。实验的问题很具体:如果模式语言的表达力不超过主流编程语言类型系统,独立实现是否更容易生成代码并给出一致的校验结果。
JTD 只有八种彼此互斥的形式。empty 接受任意实例;ref 引用根部定义;type 处理基础类型与时间戳;enum 限定非空且无重复的字符串集合;elements 约束数组元素;properties 描述记录;values 描述键值映射;discriminator 用字符串标签选择记录分支。
互斥消除了优先级争议。一个模式不能一半像记录、一半像标签联合,再让不同校验器自行决定先算哪条。分支也不能重新定义 discriminator 字段的类型。definitions 只允许出现在根模式,ref 因而不会随着嵌套位置变化而悄悄换义。
这正是“最小初始规范”的工程版本。共享层只承载各方能一致执行的部分;更丰富的政策可以存在,却不会因为写在旁边就自动成为共同规则。
空门也会亮绿灯
empty 形式是防止夸大校验意义的最好例子。它接受任何 JSON 值,而且永远不产生错误。于是,同样的“通过”既可能表示对象满足了几十项结构约束,也可能表示根本没有内容约束。没有模式哈希、版本与运行模式,绿色结果几乎无法复现。
metadata 的边界同样重要。JTD 允许元数据承载文档、代码生成提示或本地工具信息,但其他参与者不应被假定理解它。若某个元数据字段改变校验行为,只有各方在带外明确约定扩展后,它才具有共同语义。一个名叫 approvalRequired 的提示看起来很正式,也可能被合规校验器完全忽略。
因此,审计凭证必须把原始消息哈希、模式哈希、校验器版本与扩展配置绑在一起。只写“JTD 通过”没有说明究竟通过了哪一道门。
未知字段政策逐层作出
properties 形式把必填成员与可选成员分开,同一个名字不能同时属于两组。默认情况下,未声明成员会被拒绝;additionalProperties:true 可以开放这一层。
关键在“这一层”。根对象允许额外成员,并不会让嵌套对象自动继承。内层模式必须独立决定。这样,外部信封可以为未来路由信息保留扩展空间,而内部授权请求仍保持封闭。
若平台把未知字段当作一个全局开关,就会抹去这条风险边界。记录不应只写“宽松模式”,而应指出额外字段出现在哪个对象层级、由哪条规则接受或拒绝。
位置不是优先级
JTD 的标准错误对象包含两个 JSON Pointer。instancePath 指向输入中被拒绝的位置,schemaPath 指向作出拒绝的模式位置。这对复现很有价值:运营者能看到哪个值撞上了哪条规则。
但错误数组的顺序没有规定。第一项不一定是根因、最严重问题,也不代表时间上的第一次失败。若自动修复系统按数组位置排序处置,它就在规范之外创造了新的权力。JSON Pointer 只给出文档坐标,不给出业务归属,更不授权修改。
精确地址容易被误读为裁决。它只是证据的位置。
类型减少歧义,却不会消除现实歧义
JTD 提供有符号与无符号的 8、16、32 位整数,float32、float64、布尔、字符串和时间戳。对于整数,只要数学值在范围内,JSON 中的 10、10.0 或 1.0e1 都可被接受。时间戳则需符合 RFC 3339,并采用 RFC 4287 的收紧规则。
这能阻止明显的结构错误,却不能证明浮点测量准确、字符串对应真实客户,或时间来自可信时钟。一个格式完美的未来时间仍可通过;一条旧的、曾经获授权的命令被重放时,也可能完全符合模式。
JTD 没有提供 int64 和 uint64,反而体现了诚实。JSON 生态并不能一致保留完整 64 位整数精度。I-JSON 给出的可互操作整数范围更小。与其提供一个看似保证全范围的类型名称,规范选择不承诺。
扩展也应遵守同一原则:某个生成器能够输出,不等于所有接收者能够无损解释。
标签选择分支,不会让事件发生
discriminator 形式描述标签联合。对象必须含有指定标签;标签值必须是映射中的字符串;被选中的 properties 分支也必须通过。它可以阻止一条自称 account_deleted 的消息漏掉账户编号。
它无法证明删除确实发生。标签来自生产者。认证只能说明谁发送;授权决定他能否提出请求;审计记录证明系统是否接受;持久化与回读才接近结果。若把这些凭证压成一次模式通过,语法完整的声明就获得了制造现实的权力。
校验器本身也是攻击面
模式可以引用根定义,粗心的引用图可能形成循环。RFC 8927 建议处理用户输入模式的实现发现并中止循环,否则朴素校验器可能无限运行,成为拒绝服务目标。RFC 8259 还允许解析器限制输入长度、嵌套深度与数值精度。
所以,校验不是零成本谓词。运营策略需要字节、深度、引用展开、错误数量和执行时间预算;还要说明模式是受信构件、租户输入,还是远程依赖。一份语法正确的模式仍可能是一份恶意工作量。
实验要由运行证据回答
RFC 8927 对参与写得很清楚:节点只要校验 JTD 消息、依赖另一节点校验,或运行由 JTD 生成的代码,就在参与实验。成功标准是多个独立实现实际交换信息。RFC 的出版日期并不能替代这些事实。
这符合“运行代码优先”。RFC 编号、仓库徽章和模式文件只是符号潜力;模式哈希、独立校验结果、实际交换的消息与一致的错误位置才是运行证据。采用是自愿的,没有实现的节点不会因文档存在而自动执行规则。
来源
- RFC 8927:JSON Type Definition
- RFC 8259:JSON 数据交换格式
- RFC 7493:I-JSON 消息格式
- RFC 6901:JSON Pointer
- RFC 3339:互联网日期与时间
- RFC 4287:Atom Syndication Format
- RFC 8610:Concise Data Definition Language
- Heng Lu:Running-Code Primacy
- Heng Lu:Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption
- Heng Lu:On Reality Layers, Symbolic Power, and Why Clarity Feels So Hostile
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
