fix(rest,runtime): make api-exposure metadata fail-open observable (#3545) - #3567
Merged
Merged
Conversation
…3545) #3545 evaluated the residual risk of the API-exposure gate failing OPEN when object metadata can't be resolved. Conclusion: acceptable — the gate is a surface-area control, not the authz boundary (auth + CRUD/FLS/RLS enforce on the data call regardless), and failing closed would 405 every request during the cold-start window for no security gain. The one gap was that the fail-open was SILENT. - rest: loadObjectItems logs a THROWN metadata read (a real fault) while leaving a legitimately-empty registry silent — so a persistent outage, during which the gate allows every op unchecked, is diagnosable without cold-start false alarms. Behavior unchanged (still returns [] → gate abstains). - runtime: api-exposure.ts records the #3545 tiered decision in its contract doc (keep fail-open when the whole metadata service is unavailable; defer the narrow present-but-unreadable-policy widen — unreachable via Zod-validated registration — to the exposure-semantics window #3543). Tests: rest gate suite gains three #3545 cases (thrown read → fail-open + logged; empty registry → fail-open + silent; enforceApiAccess does not block on throw). Full rest.test.ts 171 pass; rest + runtime build (CJS/ESM/DTS) clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012L8EfEa157Pe6C73qRnaJH
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 22 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
#3391 的独立 follow-up ②(见 #3545)。API 曝露 gate(
apiEnabled/apiMethods)在元数据不可解析时故意 fail-open,以免元数据短暂不可用时阻断流量。本 PR 是该 issue「评估 + 决策」的落地。评估结论
残余安全风险 = 低,现行 fail-open 可接受。 关键框架:这个 gate 是曝露面(surface-area)控制,不是授权边界——每个请求无论 gate 结果如何,都仍要过 auth + ObjectQL 安全中间件(CRUD / FLS / RLS)。所以元数据缺失时 fail-open 无法绕过数据授权;最坏情况只是「作者想从 API 隐藏的某操作」短暂可达(且仍受完整访问控制)。
唯一的缺口是 fail-open 静默:持续性的元数据故障(存储宕机 / schema 文档损坏)期间 gate 无声放行一切,与健康状态无法区分。
分级决策
enable/apiMethods存在却不可读(非数组)→ 现在静默当 unrestricted改动
loadObjectItems:对抛出的元数据读记 warn(真实故障),而对合法空 registry(冷启动[])保持静默——把「真故障」与「空 registry」区分开(issue checkbox ①)。行为不变(仍返回[]→ gate 放行 → 数据层 + 安全层裁决)。api-exposure.ts:把上面的分级决策写进契约 doc(为什么!def → allow是刻意的,以及 Shape-B 推迟到 P2:ApiMethod 枚举收缩至 6 原语(breaking,独立版本) #3543)。契约 / 兼容
对 gate 行为零变更——纯可观测性 + 决策记录。
测试
rest.test.ts新增 3 例(元数据不可解析时的 fail-open 残余风险评估(api-exposure / rest-server) #3545):抛错读 → fail-open + 记日志;空 registry → fail-open + 静默;enforceApiAccess抛错时不 block。rest.test.ts171 通过;rest + runtime 构建(CJS/ESM/DTS)全绿。关联
🤖 Generated with Claude Code
https://claude.ai/code/session_012L8EfEa157Pe6C73qRnaJH
Generated by Claude Code