Repository navigation
[security] Family closeout: stored metadata bodies (stored datasource credential material included) are still reachable outside the redacting doors at several further positions — detail withheld pending maintainer #21120
Description
Activity
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsClaim: PM loop round 3
Session:session_01MRdbfpy4sQT8bUjmMhxsN7
Account:os-bill
Branch:claude/issue-21120-stored-metadata-body-family
Worktree:objectstack-issue-21120
Domain:domain:services(expected; the positions spanpackages/services,packages/pluginsandpackages/metadata-protocol— dispatched at the maintainer's direction ahead of a triage grade)
File surface: the landing files of the measured positions (named to the dev in-session; the dev declares the exact files in the report) + a new enumeration pin + a data migration for existing at-rest copies + a changeset; stop on breach
Container & model:M,mode:subagent, tierdefault(security family closeout; dispatch-gates--tier: no path-derived mandate)
Clause-②: no
Thread-read: none
Serial constraints cleared: PR #21115 (#21086, in review) ownspackages/metadata-protocol/src/metadata-redaction.tsandprotocol.ts. The data-door position of this card touches the same files, so it is held until #21115 is onorigin/main(no stacked branch). The other positions are disjoint and go first. #21087 (packages/rest,packages/runtime/src/domains/meta.ts) is disjoint. 34 earlier in-flight claims were scanned for these surfaces with none found.Dispatched at the maintainer's direction. Rulings, verbatim (Claude Code session
session_01MRdbfpy4sQT8bUjmMhxsN7, 2026-10-01): 「立一张脱敏收口卡并派发(推荐)」 and, on the data-door position, 「A 拒绝(推荐)」. The reproduction stays in-session. ⛔ It does not go into any GitHub text.Landing: security boundary, human floor. The PR stays draft for the maintainer's review.
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsTriage: grade after dispatch —
bug·security·priority:p1·domain:services·area:access. ⛔ The claim, the assignee and the state are unchangedTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-01T07:53Z. ⛔ Not a claim, ⛔ not a dispatch. ⛔ It carries no detail beyond the card's own sanitized text.The card was dispatched at the maintainer's direction ahead of a grade. This act adds the grade only.
- Why p1: the write-only contract for stored metadata bodies, on a P0 checklist item's surface (
integration-system.datasource-credential-refusal-matrix, QA run · priority:P0 (19/19) · ef1ed17f · 2026-10-01 · 13 PASS / 0 PARTIAL / 6 FAIL / 0 BLOCKED / 0 NOT-RUN #21056). Every position measured so far is admin-reachable only, so it is not p0. - Routing:
domain:services, as the claim expected. The claim declares themetadata-protocolfiles (domain:engine) as its cross-lane surface, held behind PR fix(metadata-protocol)!: stored metadata bodies on the generic data door are served as their type's read projection (#21086) #21115 as it states.
Generated by Claude Code
- Why p1: the write-only contract for stored metadata bodies, on a P0 checklist item's surface (
- addedarea:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingSomething isn't workingpriority:p1High: required for production / M2High: required for production / M2
on Oct 1, 2026 objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 21120, "status": "done", "branch": "claude/issue-21120-stored-metadata-body-family", "pr": "https://github.com/objectstack-ai/objectstack/pull/21144", "session": "session_01MRdbfpy4sQT8bUjmMhxsN7", "premise_still_valid": true, "clause_2": "no (narrowing)", "summary": "Family closeout. One shared seam added to @objectstack/spec/kernel (object set, predicate, column names, body redactor) and every further surface that can serve, copy or evaluate a stored metadata body now routes through it or refuses: plugin-audit projects the write-time audit/activity copy and a new `os migrate audit-metadata-bodies` command rewrites the copies already at rest; service-analytics refuses the body column as a query member (INVALID_FIELD/400); objectql projects the data.record.* realtime event body; and, on the merged #21086 seam, the generic data door refuses a filter or sort on the body column (maintainer ruling A). An enumeration pin fails a future surface instead of letting it join the family silently. #21115 was merged mid-run; origin/main was merged in (no stacked branch) and F3 built on its seam. PR stays draft (security boundary, human floor).", "tests": "Per-package vitest (all pass): spec metadata-type-redaction.test.ts (seam, 19); metadata-protocol stored-metadata-body-family.pin.test.ts + merged protocol.data-door-stored-metadata-redaction.test.ts (24, green on the reconciled seam); plugin-audit audit-writers.test.ts (78, incl. create/update-rotation/clean writer redaction) + stored-metadata-body-migration.test.ts (12, planners + driven runner dry/apply/idempotent); service-analytics stored-metadata-body-refusal.test.ts (5); objectql engine-realtime-stored-metadata-body.test.ts (4) + engine-data-events.test.ts green. typecheck green for spec/metadata-protocol/objectql/service-analytics/plugin-audit/cli. Local gates run (exit 0): check:nul-bytes, check:adr-0087-registration --base origin/main, check:changeset-no-major, check:empty-changeset, check:undeclared-dep-imports, check:issue-citations, spec check:generated/api-surface/export-origins, check:doc-authoring, check:cross-package-test-inputs, check:test-source-alias, check:engine-double-contract, check:durability-log-level, check:merge-driver, check:published-files, check:tier-file-adoption. Full turbo build (72/72) green after the merge. Reconciliation: 16 gate families run locally, 89 derived families deferred to CI (the lint/i18n/temporal/dogfood farm is CI's). No ablation needed (this is additive redaction + refusal, not a new gate).", "mcp_calls": "0 — no MCP GitHub tools used; reads were gh CLI (gh api) reads of the card, its comments and the PR.", "api_writes": "3 REST writes via the fleet relay: pr_create (POST /repos/objectstack-ai/objectstack/pulls -> #21144, draft forced), assign (POST /repos/.../issues/21144/assignees os-bill), and this comment (POST /repos/.../issues/21120/comments). git push is separate (branch pushes, not REST).", "open_questions": [], "pm_questions_answered": "Answered in the session-only file (reachability by persona, the F1 refuse-vs-exclude choice justified from the analytics posture, and the migration-framework choice). Pointer below.", "session_only_pointer": "/tmp/claude-0/-home-user/4f67a396-f4bd-55f0-a625-6a7c371668ad/scratchpad/issue-21120/session-only-21120-dev.txt", "analytics_files_touched": "service-analytics/src/analytics-service.ts (callCtx + a new assertStoredMetadataBodyNotQueried method) and the new src/stored-metadata-body-refusal.ts + its test. NONE of #21117's files (read-scope-sql.ts, native-sql-strategy.ts, contains-membership-sql.ts) were edited.", "out_of_scope_findings": [ "class: a (reproducible defect) · reach: public door POST /api/v1/analytics/dataset/query, measured non-admin reachable, serves a stored metadata body (credential material) to a persona who is refused it on every /data and /analytics/query door · a broader analytics evaluation surface (an inline-dataset expression dimension is compiled verbatim and bypasses object- and field-level admission) OUTSIDE the stored-metadata-body family · its fix lands in the analytics native-SQL files owned by in-flight PR #21117 (card #20987), so blocked on #21117 and needs its own card · exploit detail is session-only (pointer above) · carrier: #21117 · dedupe words: analytics dataset expression dimension raw-sql admission bypass" ] }objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsPM review — PR #21144: ACCEPT; landing on the maintainer's pre-authorization
Reviewed-by: PM seat,
session_01MRdbfpy4sQT8bUjmMhxsN7. Implemented-by: os-dev subagent, same session.- Shape: one shared seam in
@objectstack/spec/kernel. Every further exit routes through it or refuses:- the write-time audit/activity copy is projected, and
os migrate audit-metadata-bodiesrewrites the copies already at rest (the established operator-runnableos migrateshape, dry-run by default and idempotent); - analytics refuses the body column as a query member;
- the realtime record-event body is projected;
- the generic data door refuses a filter or sort on the body column, per the maintainer's ruling A, built on fix(metadata-protocol)!: stored metadata bodies on the generic data door are served as their type's read projection (#21086) #21115's merged seam with no stacked branch.
An enumeration pin fails any future exit that does not route through the seam.
- the write-time audit/activity copy is projected, and
- Path surface (read from the PR file list): spec/kernel, metadata-protocol, objectql, plugin-audit, service-analytics (none of fix(service-analytics)!: the analytics read scope and the native where answer $contains on a JSON-stored field by membership (#20987) #21117's files), cli, two changesets, the engine-double ledger row, and two gate-demanded census figure updates (
content/docs/permissions/tenant-audit-census.mdx,docs/audits/…counts.md). There is no governed path, and the changed lines are under the 5,000 human-merge threshold. - CI: the first push was red on
Lint & Repo Gates(ESLint: a service lookup erased toany). It was fixed at the root, and 127/127 derived gates were then run locally with exit codes recorded. CI on head5397aa8ba8is 33 success / 2 skipped / 0 failed; mergeableclean. - Clause-②:
no (narrowing). The data-door and analytics refusals narrow the accept set; the changesets carry the disposition. - Disclosure check: the PR title, body, commits and changesets carry no reproduction.
- Landing: maintainer pre-authorization, selected verbatim 「绿了就转 ready + 进队列(推荐)」 in Claude Code session
session_01MRdbfpy4sQT8bUjmMhxsN7, 2026-10-01. - Out of scope: a broader analytics evaluation position, outside this family, goes to its own sanitized card per the maintainer's ruling in the same session.
Generated by Claude Code
- Shape: one shared seam in
- added 4 commits that reference this issue
on Oct 7, 2026
Filing gate: ① reproducible defects with named landing sites, folded into ONE family closeout card as the same-family rule requires (no single-point cards).
reach:exception — could leak data. Measured in-session on fresh showcase boots by the #21086 dev, after that fix. Reader: the maintainer, who holds the positions and recipes; dispatched directly at the maintainer's request. Dedupe: this is the closeout of the #7990 / #20590 / #13405 / #21086 family (all closed except #21086, whose PR #21115 is in review); a family-level search (open + closed) finds no open card covering these positions.QA-source: #21056 · integration-system.datasource-credential-refusal-matrix · negative[0]
What is known publicly
/metaand datasource doors and, once PR fix(metadata-protocol)!: stored metadata bodies on the generic data door are served as their type's read projection (#21086) #21115 lands, on the generic data door's reads of the stored metadata tables.session_01MRdbfpy4sQT8bUjmMhxsN7, 2026-10-01): 「A 拒绝(推荐)」. Decision to file and dispatch this card, verbatim from the same session: 「立一张脱敏收口卡并派发(推荐)」.Detail withheld pending maintainer (RUNNER rule 2).
Acceptance (family level)
Generated by Claude Code