Skip to content

fix(dashboard): harden pinned MCP app authority#111679

Merged
fuller-stack-dev merged 1 commit into
mainfrom
codex/mcp-widget-authority-hardening
Jul 20, 2026
Merged

fix(dashboard): harden pinned MCP app authority#111679
fuller-stack-dev merged 1 commit into
mainfrom
codex/mcp-widget-authority-hardening

Conversation

@fuller-stack-dev

@fuller-stack-dev fuller-stack-dev commented Jul 20, 2026

Copy link
Copy Markdown
Member

Related: #111524
Follow-up to superseded #111552.

What Problem This Solves

Fixes an issue where pinned MCP App widgets could carry client-selected authority metadata and retain interactive capabilities after their originating live view, grant, revision, or widget instance was no longer authoritative.

Why This Change Was Made

MCP App pins now accept only a live viewId; the Gateway derives and persists the stable descriptor from the authenticated board session. Canonical stored rows require explicit interactive provenance and an instance id, and every app interaction path dynamically rechecks the current widget grant, revision, and instance. Reconstructed or revoked sources remain read-only.

This keeps the existing MCP_APP_VIEW_EXPIRED lifecycle and show_widget HTML behavior unchanged. The UI change is limited to sending the narrowed pin request; naming and capability UX remain unchanged.

User Impact

Pinned MCP Apps retain durable dashboard content without allowing stale, replaced, revoked, or client-forged authority to update model context or call tools. Unreleased noncanonical stored MCP rows are dropped instead of receiving a runtime compatibility path.

Evidence

  • Exact base: 401ef9770e2554b577ab86beabd49503babb414e (upstream/main at the tooling-critical sync)
  • Exact head: fd67303ab2d94f78640896b190215c3b93c1c15b
  • Tooling-sync focused proof: Blacksmith Testbox run 29721069115, provider blacksmith-testbox, lease tbx_01kxz2hp83sb11acfevmhzm22a; 74 protocol, store, reconstruction, Gateway, and MCP interaction tests passed.
  • Earlier producer-inclusive proof: Blacksmith Testbox run 29719463696, lease tbx_01kxz0aaf9zv3eczzv56t74e45; 105 tests passed including the UI producer.
  • Broad authored-surface proof: provider blacksmith-testbox, lease tbx_01kxyz2dy7kyq6bebdvze46y3j; protocol generators matched tracked Swift/Kotlin output, check-protocol-since passed, 151 focused tests passed, check:changed passed for core, coreTests, ui, and apps, and pnpm build passed in 17m45.996s.
  • The critical intervening scripts/pr trust-boundary update and all other commits were audited as non-overlapping; the rebase was conflict-free and git range-diff proved the authored patch byte-equivalent.
  • git diff --check upstream/main...HEAD passed.
  • Final autoreview: clean, no accepted/actionable findings.
  • LOC: +596/-603 across 23 files (production/generated +223/-267; tests +373/-336).

AI-assisted: yes. I reviewed the implementation and proof and understand the authority and compatibility boundaries changed here.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime agents Agent runtime and tooling size: XL maintainer Maintainer-authored PR labels Jul 20, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 20, 2026
@clawsweeper

clawsweeper Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 20, 2026, 1:43 AM ET / 05:43 UTC.

Summary
The PR changes pinned MCP App requests to submit only a live viewId, derives durable authority server-side, and rechecks widget grant, revision, and instance identity before interactive MCP App actions.

PR surface: Source -6, Tests +37, Other -38. Total -7 across 23 files.

Reproducibility: no. high-confidence current-main reproduction is available from the supplied material. The PR describes a stale or client-forged authority boundary, but does not provide a runnable before-fix exploit sequence against the current base.

Review metrics: 1 noteworthy metric.

  • Pinned MCP App request contract: 1 request shape narrowed; 1 exported pin-descriptor schema removed. This is the compatibility-sensitive surface that determines whether older clients can continue pinning widgets during an upgrade.

Stored data model
Persistent data-model change detected: unknown-data-model-change: packages/gateway-protocol/src/schema/board.test.ts, unknown-data-model-change: packages/gateway-protocol/src/schema/board.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🌊 off-meta tidepool
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Confirm the retired Gateway pinning contract was never shipped, or add a bounded additive/versioned transition path.

Risk before merge

  • [P1] The patch intentionally removes a gateway protocol descriptor and fields; merging is safe only if pinned MCP Apps and every affected client contract are confirmed unreleased, or if an additive/versioned upgrade path is supplied.

Maintainer options:

  1. Confirm the protocol was not released (recommended)
    Before merge, verify that no supported release or standalone client uses BoardMcpAppPinDescriptor or the removed descriptor fields.
  2. Add a bounded transition
    If the former request shape reached users, use an additive/versioned parser and documented deprecation rather than rejecting it immediately.

Next step before merge

  • [P2] A maintainer must confirm the release and client-compatibility contract for the removed Gateway protocol shape before merge.

Maintainer decision needed

  • Question: Can maintainers confirm that the retired pinned-MCP-App request shape has never shipped to a supported release or independently updated client, so this incompatible protocol removal needs no compatibility path?
  • Rationale: The code changes a public Gateway protocol schema and generated client model; the PR states the predecessor data is unreleased, but only release ownership can safely confirm the supported upgrade contract.
  • Likely owner: steipete — They introduced and merged the underlying durable pinned-MCP-App feature and are the strongest available owner for its release contract.
  • Options:
    • Confirm unreleased-only contract (recommended): Confirm no supported release or independently updated client uses the retired descriptor, then retain the narrower server-derived request shape.
    • Preserve an upgrade path: Keep an additive or versioned parser for the retired request shape until affected released clients have an explicit migration window.

Security
Cleared: The reviewed diff adds no dependency, workflow, secret, or supply-chain surface and moves MCP App authority derivation from client-supplied metadata into authenticated Gateway state.

Review details

Best possible solution:

Keep the server-derived viewId authority model, but establish whether any released or independently updated client can send the retired descriptor before accepting the incompatible protocol removal; preserve or version the old request contract if that upgrade path exists.

Do we have a high-confidence way to reproduce the issue?

No high-confidence current-main reproduction is available from the supplied material. The PR describes a stale or client-forged authority boundary, but does not provide a runnable before-fix exploit sequence against the current base.

Is this the best way to solve the issue?

Unclear but directionally strong: resolving authority from the authenticated live view and rechecking it at each interactive operation is the narrowest safe design, provided the removed protocol shape is confirmed unreleased or receives an explicit transition path.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against a22ede72e494.

Label changes

Label changes:

  • add P2: This is a targeted security/authority hardening follow-up with meaningful but not currently demonstrated user-facing urgency.
  • add merge-risk: 🚨 compatibility: The PR removes an exported Gateway protocol descriptor and several fields from the pinning contract, which may affect upgraded clients if the prior shape shipped.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The author is a repository MEMBER, so the external-contributor proof gate does not apply; the PR nevertheless links exact-head Testbox and successful real-behavior-proof evidence.

Label justifications:

  • P2: This is a targeted security/authority hardening follow-up with meaningful but not currently demonstrated user-facing urgency.
  • merge-risk: 🚨 compatibility: The PR removes an exported Gateway protocol descriptor and several fields from the pinning contract, which may affect upgraded clients if the prior shape shipped.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The author is a repository MEMBER, so the external-contributor proof gate does not apply; the PR nevertheless links exact-head Testbox and successful real-behavior-proof evidence.
Evidence reviewed

PR surface:

Source -6, Tests +37, Other -38. Total -7 across 23 files.

View PR surface stats
Area Files Added Removed Net
Source 13 215 221 -6
Tests 9 373 336 +37
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 8 46 -38
Total 23 596 603 -7

What I checked:

  • Authority boundary in the proposed gateway path: The PR resolves the supplied live view in the authenticated board session rather than trusting a client-supplied descriptor, then materializes canonical content for storage. (src/gateway/server-methods/board.ts:145, fcff010a6828)
  • Interactive operations are rechecked: The proposed MCP App operation helper makes read-only and missing-tool leases non-interactive and invokes the current authorization callback before model-context updates, tool listing, and tool calls. (src/gateway/mcp-app-operations.ts:67, fcff010a6828)
  • Protocol compatibility surface: The patch removes originSessionKey from BoardMcpAppDescriptor, removes BoardMcpAppPinDescriptor, and narrows the mcp-app put payload to viewId; this is an intentional incompatible protocol evolution that needs release-scope confirmation. (packages/gateway-protocol/src/schema/board.ts:120, fcff010a6828)
  • Merged feature provenance: The related merged PR introduced durable pinned MCP App widgets at commit 64c82812a5e52f4a03d2b89b8132c068a048a81b; this PR is a narrowly scoped authority follow-up rather than a duplicate implementation. (src/gateway/server-methods/board.ts:145, 64c82812a5e5)
  • Available authored proof: The PR body reports an exact-head Blacksmith Testbox focused run covering protocol, store, reconstruction, Gateway/MCP, and UI producer behavior, while GitHub’s supplied check state also includes a successful Real behavior proof check. (fcff010a6828)

Likely related people:

  • steipete: Authored the merged durable pinned-MCP-App feature that established the board-widget and lease-reconstruction paths this follow-up hardens. (role: feature introducer; confidence: high; commits: 64c82812a5e5; files: src/gateway/server-methods/board.ts, src/gateway/mcp-app-reconstruction.ts, src/boards/board-store.ts)
  • fuller-stack-dev: Authored the superseded backend-focused predecessor and the current authority-hardening follow-up, giving them direct continuity on the protocol/store boundary. (role: adjacent owner; confidence: high; commits: 7ed78c78627c, fcff010a6828; files: packages/gateway-protocol/src/schema/board.ts, src/boards/sqlite-board-store.ts, src/gateway/mcp-app-operations.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@fuller-stack-dev
fuller-stack-dev force-pushed the codex/mcp-widget-authority-hardening branch from fcff010 to d5906ad Compare July 20, 2026 06:01
@fuller-stack-dev
fuller-stack-dev force-pushed the codex/mcp-widget-authority-hardening branch from d5906ad to fd67303 Compare July 20, 2026 06:17
@fuller-stack-dev
fuller-stack-dev merged commit 6304a47 into main Jul 20, 2026
124 checks passed
@fuller-stack-dev
fuller-stack-dev deleted the codex/mcp-widget-authority-hardening branch July 20, 2026 06:32
@fuller-stack-dev

Copy link
Copy Markdown
Member Author

Merged via squash.

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

Labels

agents Agent runtime and tooling app: web-ui App: web-ui gateway Gateway runtime maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant