Skip to content

TS 作者写不出「省略 authRequired」这个安全形状:ApiEndpoint 是输出类型,authRequired 在上面是必填 #5227

Description

@os-zhuang

观察类发现(finding,不进分发池),来自 #5112(#5040 E8 收官验收)写 fixture 时被 tsc 拦下。

事实

升级指南 declarative-apis-endpoints-live 的核心安全论断是:

Its schema default is true, so an omission is SAFE and needs no review; an EXPLICIT authRequired: false is the only thing that opens anonymous access.

这在运行时完全成立(#5112 的 e2e 实测:省略键的端点对匿名调用返回 401)。但一个用 TypeScript 写 stack 的作者无法表达那个省略:

test/fixtures/endpoint-policy-fixture.ts(66,14): error TS2741:
  Property 'authRequired' is missing in type '{ name: ...; method: "GET"; ... }'
  but required in type '{ ...; authRequired: boolean; ... }'.

因为 export type ApiEndpoint = z.infer<typeof ApiEndpointSchema>(packages/spec/src/api/endpoint.zod.ts:83)是输出类型 —— .default(true) 已被物化,该键是必填。省略只能通过 ApiEndpointInput(第 84 行,z.input<...>)表达。

为什么值得记一笔

指南教人「不写就是安全的」,而最常见的写法(const X: ApiEndpoint = { … })会强迫作者把 authRequired 显式写出来。显式写 true 无害;但一旦作者被迫开始考虑这个键,写错成 false 的概率就不再是零 —— 而 false 是这条线上唯一不可挽回的错误。对 AI 作者尤其如此:它会照着类型报错补上缺的键,而不是去换类型。

今天没有用户被这个坑到(showcase 的两条都显式 true),所以按观察类归档。可能的方向,不预设结论:

  • apis: 的作者面统一暴露 ApiEndpointInput(与 ApiEndpointSchema.create 已经用 z.input 的做法一致);
  • 或在指南里点名这一点,让「省略」的建议附上可用的类型注解写法。

关联:#5112、packages/spec/src/api/endpoint.zod.ts:80-84、ADR-0121 D6。

Activity

  1. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    发现分诊轮:晋级 pm:queue(摘 finding,domain:spec 沿用)。理由:这是 authRequired 安全线上的主动诱错面 —— 指南教「省略即安全」,而最常见类型注解(ApiEndpoint)强迫作者显式写出该键,AI 作者照类型报错补键的行为模式使写错成 false 的概率非零,而 false 是这条线上唯一不可挽回的错误。修向按正文两条并做:作者面暴露/指向 ApiEndpointInput(与 ApiEndpointSchema.create 用 z.input 的既有做法一致,类型面加法不动 schema)+ 升级指南补一句可用的类型注解写法。落点 packages/spec/src/api/endpoint.zod.ts 导出面 + 指南;spec 车道按 #5441-1 串行接力消化。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    分诊轮判级(spec 车道 PM,session_018fxLGQdatPbBUvCgiVxg6D,2026-08-05):持有(finding 留)。理由:ApiEndpoint 面即将被 #5309(信封/正文分离,pm:on-hold,GA 后 #4001 批次)整体重做 —— 现在单修「输出类型占裸名」会与其撞同一文件面;届时 X/XParsed 惯例修正并入该批次一次做完。重启条件:#5309 动工时并批。


    Generated by Claude Code

  3. hotlong commented on Aug 7, 2026

    @hotlong
    Contributor

    Release-board audit (maintainer-directed re-audit of non-board domain:spec items, 2026-08-07): adding target:v17 — metadata-protocol change, size S, low-risk: additive type-export fix exposing ApiEndpointInput (z.input) on the author surface, with the z.input precedent already in place; the spec seat's 08-05 note to batch it with the #5309 same-surface redo stands. Maintainer directive: protocol changes land in v17 unless large/risky. Triage seat may veto.


    Generated by Claude Code

  4. self-assigned this
    on Aug 8, 2026
  5. os-zhuang commented on Aug 8, 2026

    @os-zhuang
    ContributorAuthor

    Claim: PM loop round 1 (domain:spec seat, #6017) — batched into #5384's dispatch (maintainer-batched, same surface packages/spec/src/api/endpoint.zod.ts; v17 window ruling 2026-08-07 + release-board audit comment above).
    Session: session_011sGk4SKHqGRgmmqUok1P8M
    Branch: claude/issue-5384-api-endpoint-strict (shared with #5384; one PR carries Fixes #5384 and Fixes #5227)
    Worktree: objectstack-issue-5384
    Domain: domain:spec
    File surface for this card's half: packages/spec/src/api/endpoint.zod.ts export face (expose/point the author surface at ApiEndpointInput, z.input precedent) + the upgrade-guide note (declarative-apis-endpoints-live) landed at its correct source (registry guidance vs hand-written page — implementer verifies which is the source, never hand-edits generated output).
    Serial constraints cleared: see the #5384 claim comment (same dispatch).


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions