Skip to content

[security] A datasource write path admits callers below the capability the datasource admin door requires for create/update — detail withheld pending maintainer #21124

Description

@objectstack-fleet

Filing gate: ① a reproducible defect with a named landing site — the save admission for datasource metadata, next to the read admission PR #21119 adds (packages/rest, packages/runtime/src/domains/meta.ts). reach: the public REST API, measured once by the #21087 dev on a booted showcase; the dispatched dev re-measures first. Reader: the maintainer, who holds the request; dispatched directly at the maintainer's request. Dedupe: the write-side twin of #21087 (read side, PR #21119) and of the #9593 admin-door gate (closed); no open card covers the write side.

QA-source: #21056 · integration-system.datasource-credential-refusal-matrix · acceptance[7]

What is known publicly

Detail withheld pending maintainer (RUNNER rule 2). Ruling, verbatim (Claude Code session session_01MRdbfpy4sQT8bUjmMhxsN7, 2026-10-01): 「立脱敏卡并派发(推荐)」.

Acceptance

  • Datasource definitions are written through every write path only by holders of the admin door's capability.
  • The refusal is pinned on both sides: an author is refused with nothing persisted, and the holder is admitted.
  • What a previously admitted write could reach is measured and recorded.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3
    Session: session_01MRdbfpy4sQT8bUjmMhxsN7
    Account: os-bill
    Branch: claude/issue-21124-datasource-meta-write-gate
    Worktree: objectstack-issue-21124
    Domain: domain:services (expected; dispatched at the maintainer's direction ahead of a triage grade)
    File surface: the datasource metadata save admission at the /meta entry of both transports (packages/rest/src/meta-item-read-gate.ts or a sibling module, packages/rest/src/rest-server.ts, packages/runtime/src/domains/meta.ts) + tests + changeset; stop on breach
    Container & model: M, mode:subagent, tier default (permission-boundary fix; dispatch-gates --tier: no path-derived mandate)
    Clause-②: no
    Thread-read: none
    Serial constraints cleared: PR #21119 (#21087, in review) owns the same three files. This card measures first and edits nothing until #21119 is on origin/main (no stacked branch). #21115 and #21120 are disjoint.

    Dispatched at the maintainer's direction. Ruling, verbatim (Claude Code session session_01MRdbfpy4sQT8bUjmMhxsN7, 2026-10-01): 「立脱敏卡并派发(推荐)」. The request stays in-session. ⛔ It does not go into any GitHub text.

    Landing: permission boundary, human floor. The PR stays draft for the maintainer's review.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: grade after dispatch — bug · security · priority:p1 · domain:cli · area:access. ⛔ The claim, the assignee and the state are unchanged

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-01T08:01Z. ⛔ 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.


    Generated by Claude Code

  3. added
    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guards
    bugSomething isn't working
    priority:p1High: required for production / M2
    on Oct 1, 2026
  4. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
    "issue": 21124,
    "status": "done",
    "branch": "claude/issue-21124-datasource-meta-write-gate",
    "pr": "#21148",
    "session": "session_01MRdbfpy4sQT8bUjmMhxsN7",
    "premise_still_valid": true,
    "summary": "Datasource metadata writes through /api/v1/meta now require manage_platform_settings, the capability the datasource admin door requires for the same create/update/remove. One type-level predicate (metaTypeWriteRefusal over META_TYPE_WRITE_CAPABILITIES, beside #21119's read admission in packages/rest/src/meta-item-read-gate.ts) is asked at both transports' single /meta entry (RestServer's guarded registrar; the runtime dispatcher's handleMetadataRequest) before any write, for every write verb (save incl. draft, reset, publish, rollback). Premise re-measured on both transports before the fix and confirmed (readings in-session). Deviation from the planned change, measurement wins: external_catalog gets NO write row, because its own write door (POST /datasources/:name/external/refresh-catalog) requires FEDERATION_WRITE_CAPABILITY = manage_metadata, which the /meta write doors already ask (matched, never minted). Three every-type org-scope test fixtures were given manage_platform_settings so they keep covering datasource. Draft PR, human floor; never readied or armed.",
    "tests": "Head 583f706 (merge of origin/main c6954d6). New + landed batteries and org-scope suites: rest 4 files 122 passed; runtime 3 files 52 passed. Full suites (vitest --project local) at 7cea2ee: rest 4767 passed / 2 failed, runtime 4314 passed / 1 failed - all three the every-type org-scope fixtures (caller held only manage_metadata), fixed in c21920a and green at 583f706. Typecheck rest exit 0, runtime exit 0 (7cea2ee). Gates: dispatch-gates --commands (no paths) = 62 families, all run at 583f706 with recorded exits: 61 exit 0, check:dual-build-cjs-loads exit 3 = NOT MEASURED (needs every package built; narrowed: rest and runtime dist/index.cjs require() OK, rest exports metaTypeWriteRefusal); --ran: 62 derived, 61 run, 1 NOT MEASURED, 0 UNRUN, exit 0. Lint narrowed: eslint --no-inline-config --format json over 11 files (superset of the 9 changed .ts) 0 errors 0 warnings; eslint.config.mjs enables no type-aware linting so untouched files' verdicts cannot move. Ablation from committed 81a6449 via scripts/ablation-replace.mjs under an EXIT trap: leg A (RestServer call site) meta-type-write-capability.test.ts 9 failed / 43; leg B (dispatcher call site) meta-type-write-capability-parity.test.ts 7 failed / 13; each restored to its HEAD blob, git diff HEAD empty; direction as expected (authoring-only caller admitted, store changed).",
    "mcp_calls": "0 - no MCP GitHub tools (reads via gh api / git).",
    "api_writes": "3 - all through the scripts/pm fleet-write relay as objectstack-fleet[bot]: pr_create (#21148, draft forced), label-write assign os-bill on #21148, and this os-dev-report comment via post-stamped. git push is not counted (not a REST write).",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: measured in this worktree at 583f706 - after the dev-dependency bump merged from main, a turbo 2.11.5 invocation during the gate run appended its managed turborepo-agent-rules block (11 lines) to AGENTS.md, a governed Tier H file, as an uncommitted change whose own text asks to be committed; turbo.json carries no agentGuidance key. Restored here to the HEAD blob e9e211fc92 and not committed. An agent that commits it makes its PR governed and derives the pm-governed gate families · dedupe: turbo agentGuidance AGENTS.md managed block, turborepo-agent-rules",
    "class: a · one further finding on the /meta read surface was handed to the PM in-session for filing (detail withheld pending maintainer, as this card's own detail is) · carrier: PM seat",
    "carrier: 承接者:无 · noted, not filed - doors outside /meta that write metadata (package install, POST /packages) keep their own admission and are unchanged here; whether one can carry a datasource definition was not measured"
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    PM review — PR #21148: ACCEPT; landing awaits the maintainer (human floor: permission boundary)

    Reviewed-by: PM seat, session_01MRdbfpy4sQT8bUjmMhxsN7. Implemented-by: os-dev subagent, same session.

    • Path surface (read from the PR file list): packages/rest (meta-item-read-gate.ts, rest-server.ts, index.ts plus tests), packages/runtime/src/domains/meta.ts plus tests, and a changeset. There is no governed path. Serial constraint honoured: edits began only after fix(rest,runtime): datasource metadata reads require the same capability as the datasource admin door #21119 was on origin/main, by a merge with no stacked branch.
    • Shape: the write-side twin of fix(rest,runtime): datasource metadata reads require the same capability as the datasource admin door #21119's read admission. One type-level predicate (metaTypeWriteRefusal over META_TYPE_WRITE_CAPABILITIES) is asked at both transports' single /meta entry, before any write, for every write verb.
    • Deviation accepted: external_catalog gets no write row. Its own write door already requires the capability the /meta write doors ask for, so the matched capability is used and none is minted.
    • Test fixtures: three every-type org-scope fixtures were given manage_platform_settings so they keep covering datasource. That is legitimate, not a weakened pin.
    • CI on head 583f706fef: 31 success / 3 skipped / 0 failed.
    • Disclosure check: the PR title, body, commits and report comment are neutral.

    The PR stays draft until the maintainer decides the landing.


    Generated by Claude Code

  6. added a commit that references this issue on Oct 7, 2026
    454bbb6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingdomain:clipriority:p1High: required for production / M2security

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions