Related PR: #3737 — MSRC 31000000666371: MCP describe_entities info-disclosure fix + single-role alignment
Proposed fix
Add a single choke point on McpAuthorizationHelper that every MCP tool calls to obtain the caller's role:
public static bool TryResolveValidatedRole(
HttpContext httpContext,
IAuthorizationResolver authResolver,
out string? role);
Behavior:
- Delegates validation to
IAuthorizationResolver.IsValidRoleContext (exactly-one non-empty header value + HttpContext.User.IsInRole(header)).
- Returns the validated
X-MS-API-ROLE header value verbatim as the single role for the request.
- Is the only place any MCP code reads
AuthorizationResolver.CLIENT_ROLE_HEADER.
Then refactor every MCP tool to call it: DescribeEntitiesTool, AggregateRecordsTool, CreateRecordTool, DeleteRecordTool, ExecuteEntityTool, ReadRecordsTool, UpdateRecordTool, DynamicCustomTool.
Design
- Single-role model.
X-MS-API-ROLE is one atomic role. No splitting, no unioning. Matches REST, GraphQL, and DAB's existing ClientRoleHeaderAuthorizationMiddleware.
- Resolver-owned inheritance. Per-entity authorization goes through
IAuthorizationResolver.AreRoleAndOperationDefinedForEntity / GetAllowedExposedColumns, so anonymous → authenticated → named inheritance and wildcard All expansion are consistent with REST/GraphQL.
- One header read.
AuthorizationResolver.CLIENT_ROLE_HEADER appears in exactly one MCP file after this change.
Acceptance
grep AuthorizationResolver.CLIENT_ROLE_HEADER src/Azure.DataApiBuilder.Mcp/** returns one match, in McpAuthorizationHelper.
- No
.Split(',') on the role header anywhere in the MCP project.
- All MCP tools use
TryResolveValidatedRole; existing tests still pass.
Non-goals
- No resolver behavior changes.
- No config schema changes.
- No new live-database tests.
Reference
See PR #3737 for the single-role model, the MSRC fix in DescribeEntitiesTool, and the McpAuthorizationHelper.TryResolveAuthorizedRole alignment this issue builds on.
Related PR: #3737 — MSRC 31000000666371: MCP
describe_entitiesinfo-disclosure fix + single-role alignmentProposed fix
Add a single choke point on
McpAuthorizationHelperthat every MCP tool calls to obtain the caller's role:Behavior:
IAuthorizationResolver.IsValidRoleContext(exactly-one non-empty header value +HttpContext.User.IsInRole(header)).X-MS-API-ROLEheader value verbatim as the single role for the request.AuthorizationResolver.CLIENT_ROLE_HEADER.Then refactor every MCP tool to call it:
DescribeEntitiesTool,AggregateRecordsTool,CreateRecordTool,DeleteRecordTool,ExecuteEntityTool,ReadRecordsTool,UpdateRecordTool,DynamicCustomTool.Design
X-MS-API-ROLEis one atomic role. No splitting, no unioning. Matches REST, GraphQL, and DAB's existingClientRoleHeaderAuthorizationMiddleware.IAuthorizationResolver.AreRoleAndOperationDefinedForEntity/GetAllowedExposedColumns, soanonymous → authenticated → namedinheritance and wildcardAllexpansion are consistent with REST/GraphQL.AuthorizationResolver.CLIENT_ROLE_HEADERappears in exactly one MCP file after this change.Acceptance
grep AuthorizationResolver.CLIENT_ROLE_HEADER src/Azure.DataApiBuilder.Mcp/**returns one match, inMcpAuthorizationHelper..Split(',')on the role header anywhere in the MCP project.TryResolveValidatedRole; existing tests still pass.Non-goals
Reference
See PR #3737 for the single-role model, the MSRC fix in
DescribeEntitiesTool, and theMcpAuthorizationHelper.TryResolveAuthorizedRolealignment this issue builds on.