fix(safety): scope private table file byte transports

This commit is contained in:
Alex Dunmow 2026-09-06 18:56:53 +08:00
parent ce81cce76c
commit fd26aa76dc
2 changed files with 30 additions and 0 deletions

View File

@ -0,0 +1,27 @@
# Allow private table-file byte transports
CMS WO-TF-009 adds administrator file management through generated ConnectRPC
hooks. Binary upload, content download and bounded preview streams use the
private HTTP serving boundary because unary metadata hooks cannot express
resumable chunks, download bodies or preview derivatives.
Allow exactly three literal fetch targets in `lib/table-file-transport.ts`:
`/api/table-file-uploads/${sessionId}`,
`/api/table-files/${attachmentId}/content?version=${versionId}` and
`/api/table-files/${attachmentId}/preview?version=${versionId}`. Preserve ADR 0002's
file-and-target matching. Admission, status, cancellation, finalization and
lifecycle controls remain generated RPC calls.
An entire-file exception or route-prefix allowance was rejected because either
would permit unrelated future controls to bypass generated hooks. Ordinary
media routes were rejected because table files have separate authority.
Consequences:
- `frontend.go` documents each exact target's binary transport reason.
- Moving the bridge or changing a target requires another reviewed allowance.
- Existing narrow-allowance tests cover sibling routes and other callers; the
complete checker test suite passes.
- These allowances change no runtime authority or admission gate.
Keywords: WO-TF-009, table files, allowedNonProtoFetches, frontend.go, frontend_test.go, lib/table-file-transport.ts, /api/table-file-uploads, /api/table-files, content, preview, versionId, ConnectRPC, resumable chunks

View File

@ -82,6 +82,9 @@ type nonProtoFetchAllowance struct {
// generated-hook rule. Add an entry only after confirming that no generated // generated-hook rule. Add an entry only after confirming that no generated
// ConnectRPC hook can carry the endpoint's transport contract. // ConnectRPC hook can carry the endpoint's transport contract.
var allowedNonProtoFetches = []nonProtoFetchAllowance{ var allowedNonProtoFetches = []nonProtoFetchAllowance{
{file: "lib/table-file-transport.ts", target: "/api/table-file-uploads/${sessionId}", reason: "bounded resumable binary chunks with durable offsets; controls use generated RPC hooks"},
{file: "lib/table-file-transport.ts", target: "/api/table-files/${attachmentId}/content?version=${versionId}", reason: "authenticated exact-version binary download; access is rechecked at open"},
{file: "lib/table-file-transport.ts", target: "/api/table-files/${attachmentId}/preview?version=${versionId}", reason: "bounded safe binary/text preview; no raw document embedding"},
{ {
file: "components/admin/backups/restore-new-instance-dialog.tsx", file: "components/admin/backups/restore-new-instance-dialog.tsx",
target: "/api/push/upload?account_id=${encodeURIComponent(accountId)}", target: "/api/push/upload?account_id=${encodeURIComponent(accountId)}",