Skip to content

docs(specs): Spec 118 profile pin as the visibility boundary for agent tokens - #1688

Merged
Dumbris merged 5 commits into
mainfrom
118-pin-visibility-boundary
Oct 20, 2026
Merged

Dumbris merged 5 commits into
mainfrom
118-pin-visibility-boundary

Conversation

@Dumbris

@Dumbris Dumbris commented Oct 20, 2026

Copy link
Copy Markdown
Member

What this covers

Spec 118 (docs only: specs/118-pin-visibility-boundary/spec.md and its requirements checklist) records the maintainer decision on #1686, Option A: the operator-set profile pin is a visibility boundary for agent tokens on every read surface, not only on dispatch.

  • Visible set for a pinned token = allowed_servers ∩ the pinned profile's effective servers, computed in the one shared enumeration predicate every REST read door, SSE embed and derived count answers from.
  • Fail closed on a pin naming a missing, empty or non-overlapping profile, with the same response shape as an empty grant.
  • ?profile= view-as and set_profile stay ergonomic narrowings and can never widen.
  • Switchable client credentials: boundary = binding base ∪ switchable_to servers ∩ grant (REST keeps rejecting client credentials; the rule binds the MCP surface).
  • Parity requirement: REST visible set equals the MCP surface's, which already applies the pin as resolver tier 1.
  • The Follow-ups from Spec 108-e scope attribution review (#1436) #1437 /tools and fix(httpapi): hold profile-pinned agent tokens to their pin on GET /api/v1/servers #1684 /servers per-endpoint filters are replaced by the shared predicate or proven equivalent.
  • The scope_subtree.go header doctrine ("profile is ergonomic, grant is the boundary") is superseded and must be rewritten; docs/features/agent-tokens.md states the rule.

Doors covered: /status, /events (embed, status frames, server-named events), /annotations/coverage, /review, /attention (+ embed), /profiles, /profiles/{name}, every per-server subtree route.

No code in this PR. Next: /speckit.plan.

Related #1686

…t tokens

Related #1686

Records the maintainer decision (Option A, 2026-10-20): the operator-set
profile pin bounds what a pinned agent token may learn exists on every
REST and SSE read door, computed by the one shared enumeration predicate,
failing closed on a missing or empty profile, with parity to the MCP
surface which already applies the pin.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 47821ce
Status: ✅  Deploy successful!
Preview URL: https://7eb5d8ce.mcpproxy-docs.pages.dev
Branch Preview URL: https://118-pin-visibility-boundary.mcpproxy-docs.pages.dev

View logs

Related #1686

Cross-review amendments: a pinned token may select only its own pin on
?profile= and the profile doors (MCP parity); /profiles/{name}/effective-tools,
/profiles/active, the activity and tool-call grant-as-filter doors and their
usage cache key, /diagnostics, /doctor, /catalog/search and the security scan
routes join the door table; FR-005 is a same-code-path refusal rule instead of
a cost claim; FR-014 is a non-normative design note; FR-019/FR-020 and A6 added.
@Dumbris

Dumbris commented Oct 20, 2026

Copy link
Copy Markdown
Member Author

Review amendments pushed (zcode was unavailable, Z.AI login expired; findings came from a Sonnet reader checked against main): pinned tokens may select only their own pin on ?profile= and the profile doors (MCP parity, FR-009/FR-012/A6); /profiles/{name}/effective-tools, /profiles/active, activity + tool-call grant-as-filter doors and the usage cache key (L8, FR-019), /diagnostics, /doctor, /catalog/search and the security scan routes added to the door table (L7, L9, L10); FR-005 rewritten as a same-code-path refusal rule; FR-014 demoted to a design note with the profile_mode caveat; FR-020 names the config seam as a plan decision.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

📦 Build Artifacts

Workflow Run: View Run
Branch: 118-pin-visibility-boundary

Available Artifacts

  • archive-darwin-amd64 (32 MB)
  • archive-darwin-arm64 (28 MB)
  • archive-linux-amd64 (19 MB)
  • archive-linux-arm64 (17 MB)
  • archive-windows-amd64 (31 MB)
  • archive-windows-arm64 (28 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (27 MB)
  • installer-dmg-darwin-arm64 (25 MB)
  • smart-mcp-proxymcpproxy-goAQBH95.dockerbuild (0 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 39436569665 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

Related #1686

Six verified findings: /profiles/active parity (one FR-004 exception),
visible reach as the condition for every own-pin disclosure, own-pin
view-as refused without visible reach, FR-007 reconciled with the
coalesced servers.changed / attention.changed exception (hidden-only
frames dropped, timing residual recorded), /security/overview and
/security/queue reclassified as deployment-wide 403 denials, and
switchable_to cleared for a pinned caller.
Related #1686

Carry the FR-004 /profiles/active exception through Compatibility,
SC-003 and FR-018; use a disjoint profile in the active-profile example;
state the servers.changed snapshot residual in FR-007 rather than
claiming hidden-only suppression.
@Dumbris
Dumbris enabled auto-merge (squash) October 20, 2026 14:09
@Dumbris
Dumbris merged commit 35e91cc into main Oct 20, 2026
62 checks passed
@Dumbris

Dumbris commented Oct 20, 2026

Copy link
Copy Markdown
Member Author

Parallel opencode gpt-6.1-sol chunked pass (4 chunks, 17 findings, 0 high / 14 medium / 3 low) merged on top of rounds 1-3 as 3c6b4585a. New beyond those rounds: L0 (bare /servers, /tools) and L11 (/index/search) in the door table; active_profile.changed on SSE; /activity/{id} and /tool-calls/{id} detail reads; FR-002 states the empty-visible-set contract; FR-011/FR-012/FR-013 compare eligibility gates and membership, not bodies; FR-019 cache key carries a pin discriminator; FR-014 covers the empty-base switchable case; SC-006 narrowed; SC-008 + scenarios 8a/9a/US4.3 for FR-015/FR-020 traceability. Overlapping findings (/profiles/active, visible reach, /security/overview) were already resolved by rounds 1-2 and kept as-is.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants