Skip to content

feat: add agent selection to MCP authorization challenge - #6066

Merged
danielkov merged 7 commits into
mainfrom
aim-196-ckXk
Sep 8, 2026
Merged

danielkov merged 7 commits into
mainfrom
aim-196-ckXk

Conversation

@danielkov

@danielkov danielkov commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a feature-gated picker for eligible existing agents in the MCP authorization challenge. Agent approval is bound to the challenged endpoint's fixed mcp:connect policy and rechecks the human authorizer, agent lifecycle and ownership, direct agent policy, and owner policy before producing the authorization handoff.

Technical details

Stacked dependency

Targets main; the prerequisite #6055 is merged.

Authorization boundary

The picker lists same-organization agents that the caller may authorize and whose direct policy permits the requested endpoint. Approval creates no agent, reusable consent, credential, or admission decision; the downstream agent-session minting path consumes the isolated authorization handoff, and token redemption fails closed until that path is available.

Agent approval uses distinct consent actions and cache namespaces so older servers cannot silently reinterpret it as human approval during a rolling deployment.


Summary by cubic

Implements AIM-196 by extending the MCP authorization challenge from human-only approval to a feature-gated choice between the human and an eligible existing same-organization agent. Agent approval uses a fixed endpoint-scoped mcp:connect handoff; it creates no agent, reusable consent, credentials, or session, and token redemption fails closed until agent-session support exists.

Authorization safeguards

  • Lists only active, unblocked agents whose owner is active and whom the caller owns or may authorize with exact agent:authorize; live direct-agent policy must allow the challenged endpoint.
  • Rechecks the authorizer, tenant, lifecycle, ownership, endpoint, direct agent policy, and owner policy at final approval; meta endpoints cannot select agents.
  • Records the human authorizer at the first IDP callback and rejects identity replacement, including legacy agent-consent states.
  • Uses separate consent actions and grant-code namespaces so mixed-version servers cannot interpret agent approval as human approval.
  • Presents actor radio cards, fixed-policy details, the selected agent name, and an Agent management link when no eligible agent exists.

Rollout

  • Keep gram-agent-management-m1 and gram-agent-mcp-authorization-m2 disabled for production cohorts until AIM-199 passes; existing human-only and in-flight challenges remain unchanged.
  • Treats Stripe checkout compare-and-swap conflicts as HTTP 409 and stabilizes concurrent server test checks.

Written for commit 0e4dd56. Summary will update on new commits.

Review in cubic

@danielkov
danielkov requested review from a team as code owners September 4, 2026 08:55
@linear-code

linear-code Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

AIM-196

@changeset-bot

changeset-bot Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 0e4dd56

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Running ultrareview automatically — This change introduces a new agent authorization path in the MCP consent flow, touching authorization logic, new SQL queries, cache namespaces, feature flags, and token redemption with security-sensitive fail-closed behavior.... I'll post findings when complete.

@danielkov

danielkov commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor Author

Demo

AIM-196 consent choice flow

What it shows:

  1. The MCP consent starts with the synthetic human authorizer selected.
  2. Choosing the eligible existing Release assistant switches the consent to agent authorization.
  3. The endpoint-scoped mcp:connect explanation appears, the summary changes to Authorizing, and the action becomes Authorize agent.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultrareview completed in 13m 20s

All reported issues were addressed across 20 files

Not reviewed (too large): server/internal/mcp/consent_assets/consent-tools.js (~2 lines) - if these are generated or fixture files, add them to ignored paths to exclude them from future reviews.

Linked issue analysis

Linked issue: AIM-196: feat: add agent selection to the existing MCP authorization challenge

Status Acceptance criteria Notes
✅ Allow an authenticated human to choose self or an eligible existing agent. The consent screen adds an agent selector for resolved human sessions, with same-organization candidate filtering and support for owners or callers with exact agent:authorize permission.
✅ Show only active, unblocked agents whose live direct policy allows endpoint-scoped mcp:connect. Candidates are filtered for lifecycle, deletion, owner membership, organization, and live agent policy using the challenged endpoint and fixed mcp:connect check.
✅ Repeat authorizer, tenant, lifecycle, ownership, endpoint, direct-policy, and owner-policy checks at final authorization. The final approve_agent path reloads the endpoint and reruns target matching, human membership/policy, agent lifecycle and ownership, direct agent policy, and owner policy checks.
✅ Fix the requested policy to endpoint-scoped mcp:connect without broadening scope, switching endpoints, mutating direct agent policy, or creating an agent. The authorization target snapshots the endpoint and mcp:connect scope, validates it against the final endpoint, and the flow only records a handoff; it does not create agents or update policy.
✅ Require explicit agent authorization, disable reusable consent for agent subjects, and fail closed until agent-session minting exists. Agent approval uses a distinct approve_agent action, skips reusable consent persistence, stores an isolated agent grant namespace, and token redemption rejects the handoff until the downstream session lane is available.
✅ Keep existing human-subject MCP authorization behavior unchanged. Agent-specific UI and processing are gated behind resolved human authorization and selected-agent state; self approval continues through the existing consent and tool-selection paths.
⚠️ Keep agent selection disabled for production cohorts until the AIM-199 safety gate passes. The PR adds independently default-off M1 and M2 feature gates and documents the safety-gate dependency, but the diff does not show an explicit AIM-199 evaluation or enforcement beyond operational flag configuration.

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread server/internal/mcp/authnchallenge_idp_callback.go Outdated
Comment thread server/internal/mcp/authnchallenge_idp_callback.go
Comment thread server/internal/mcp/consent_template.html Outdated
Comment thread server/internal/mcp/authnchallenge_consent_agent.go
Comment thread server/internal/mcp/authnchallenge_consent_agent.go Outdated
Comment thread server/internal/mcp/authnchallenge.go

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 13 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread server/internal/mcp/authnchallenge.go Outdated
Comment thread server/internal/mcp/authnchallenge_consent_agent_test.go
Comment thread server/internal/authz/load.go Outdated
Comment thread server/internal/feature/flags.go
@blacksmith-sh

This comment has been minimized.

@danielkov
danielkov force-pushed the daniel/aim-190-test-gate-m1-agent-identity-and-setup-authorization branch from ca78e45 to 972317d Compare September 8, 2026 20:51
@blacksmith-sh

This comment has been minimized.

@danielkov
danielkov force-pushed the daniel/aim-190-test-gate-m1-agent-identity-and-setup-authorization branch from 972317d to db91a5a Compare September 8, 2026 21:28
@danielkov
danielkov force-pushed the aim-196-ckXk branch 2 times, most recently from 4b3bc2b to 8e9fc1d Compare September 8, 2026 21:33
@danielkov
danielkov force-pushed the daniel/aim-190-test-gate-m1-agent-identity-and-setup-authorization branch from fec3154 to 1f0a170 Compare September 8, 2026 21:38
@blacksmith-sh

This comment has been minimized.

Base automatically changed from daniel/aim-190-test-gate-m1-agent-identity-and-setup-authorization to main September 8, 2026 22:08
@danielkov
danielkov enabled auto-merge September 8, 2026 22:11
Replace the native agent_id select with a bordered radio-card group that
names each actor and its consequence, lead the page with the actor choice
so selecting an agent no longer collapses content above the control, show
an explanatory policy panel carrying the selected agent's name, swap the
summary verb to "Authorizing" for agent grants, and render only a pointer
to Agent management when no agent is eligible instead of a one-option
picker. Preview test now covers both agent-selection states and ships the
real consent script so served previews exercise the actual interactions.
@danielkov
danielkov added this pull request to the merge queue Sep 8, 2026
Merged via the queue into main with commit 179cb60 Sep 8, 2026
45 checks passed
@danielkov
danielkov deleted the aim-196-ckXk branch September 8, 2026 23:08
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants