Skip to content

Add Azure RBAC PIM approval tools - #2722

Open
Arthur Ma (ArthurMa1978) with Copilot wants to merge 18 commits into
mainfrom
copilot/fix-issue-2130
Open

Arthur Ma (ArthurMa1978) with Copilot wants to merge 18 commits into
mainfrom
copilot/fix-issue-2130

Conversation

Copilot AI commented May 25, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #2130

Approvers need a faster way to discover and approve pending Azure RBAC PIM activation requests without relying on Azure Portal handoffs. This adds MCP coverage for listing approvals assigned to the current approver and approving a selected request stage.

  • Commands

    • Added role approval list for pending PIM role assignment approvals at a scope.
    • Added role approval approve with required approval, stage, and justification inputs.
  • Authorization service

    • Added ARM REST support for Microsoft.Authorization/roleAssignmentApprovals.
    • Resolves subscription tenant context before calling approval APIs.
    • Maps approval and stage responses into AOT-safe response models.
  • Docs and coverage

    • Registered the new command group in Authorization setup.
    • Added unit tests for list/approve success and error paths.
    • Updated command docs, E2E prompts, and changelog entry.

Example usage:

azmcp role approval list \
  --subscription <subscription> \
  --scope <scope>

azmcp role approval approve \
  --subscription <subscription> \
  --scope <scope> \
  --approval <approval> \
  --stage <stage> \
  --justification "Approved for incident response"

Copilot AI and others added 9 commits May 20, 2026 07:04
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/mcp/sessions/eff3061d-dbec-4724-b1bf-047846d6d0a8

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
@g2vinay

Copy link
Copy Markdown
Contributor

Closing this, due to no activity.
Re-open if the intent is to merge this.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI and others added 2 commits August 10, 2026 07:01
Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
@ArthurMa1978

Copy link
Copy Markdown
Member

Copilot resolve the merge conflicts in this pull request

Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>

Copilot AI commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Copilot , resolve the ci errors in this pull request

Addressed in 0f56ec8 by removing RetryPolicyOptions from the RBAC approval tool options and service contract after the merge to current main patterns. Secret scan, whitespace check, and final validation passed; local dotnet build tools/Azure.Mcp.Tools.Authorization/src is still blocked by transient Azure DevOps package download failures.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

@ArthurMa1978

Copy link
Copy Markdown
Member

Copilot , please address all ci errors

Copilot AI 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.

🟡 Changes recommended

Pending-stage filtering, pagination, and consolidated discovery remain incomplete, and the new Azure operations lack required recorded coverage.

4 open issues
What changed in this PR

Adds Azure RBAC PIM approval workflows to the Authorization toolset, helping approvers discover and approve activation requests without Azure Portal handoffs.

Changes:

  • Adds role approval list and role approval approve commands.
  • Implements ARM REST calls, tenant resolution, and AOT-safe response models.
  • Adds mocked command tests, usage documentation, test prompts, and a changelog entry.
File Description
tools/​Azure.Mcp.Tools.Authorization/​tests/​Azure.Mcp.Tools.Authorization.Tests/​RoleAssignmentApprovalListCommandTests.cs Tests list results, empty responses, and errors.
tools/​Azure.Mcp.Tools.Authorization/​tests/​Azure.Mcp.Tools.Authorization.Tests/​RoleAssignmentApprovalApproveCommandTests.cs Tests approval results and errors.
tools/​Azure.Mcp.Tools.Authorization/​src/​Services/​IAuthorizationService.cs Declares approval service operations.
tools/​Azure.Mcp.Tools.Authorization/​src/​Services/​AuthorizationService.cs Implements approval REST requests and response mapping.
tools/​Azure.Mcp.Tools.Authorization/​src/​Options/​RoleAssignmentApprovalListOptions.cs Defines scope and authentication options.
tools/​Azure.Mcp.Tools.Authorization/​src/​Options/​RoleAssignmentApprovalApproveOptions.cs Defines approval, stage, and justification inputs.
tools/​Azure.Mcp.Tools.Authorization/​src/​Models/​RoleAssignmentApprovalStage.cs Models approval-stage details.
tools/​Azure.Mcp.Tools.Authorization/​src/​Models/​RoleAssignmentApproval.cs Models approvals and their stages.
tools/​Azure.Mcp.Tools.Authorization/​src/​Commands/​RoleAssignmentApprovalListCommand.cs Exposes pending-approval discovery.
tools/​Azure.Mcp.Tools.Authorization/​src/​Commands/​RoleAssignmentApprovalApproveCommand.cs Exposes stage approval.
tools/​Azure.Mcp.Tools.Authorization/​src/​Commands/​AuthorizationJsonContext.cs Registers response types for source-generated serialization.
tools/​Azure.Mcp.Tools.Authorization/​src/​AuthorizationSetup.cs Registers both commands and their group.
servers/​Azure.Mcp.Server/​docs/​e2eTestPrompts.md Adds prompts for both tools.
servers/​Azure.Mcp.Server/​docs/​azmcp-commands.md Documents command syntax and safety metadata.
servers/​Azure.Mcp.Server/​changelog-entries/​copilot-pim-role-approvals.yaml Announces the new approval tools.

Review effort: Balanced

Comment thread tools/Azure.Mcp.Tools.Authorization/src/AuthorizationSetup.cs
Comment thread tools/Azure.Mcp.Tools.Authorization/src/Services/AuthorizationService.cs Outdated
Comment on lines +149 to +153
using var responseDocument = await SendArmRequestAsync(
HttpMethod.Patch,
requestUri,
resolvedTenantId,
content,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Partially addressed in da57dd3; leaving this thread open because genuine recording validation is still blocked. Added AuthorizationApprovalCommandTests.Should_discover_and_approve_controlled_role_request on RecordedCommandTestsBase, with recorded deployment variables for the exact controlled approval/stage. It verifies discovery IDs, assigned approver, pending state, then approval status/result/justification/timestamp. It is explicitly opt-in because it grants Azure access. Setup and the exact Record/Playback invocation are documented in docs/recorded-tests.md. Existing IAzureService.GetClient uses the shared factory/recording transport. HTTP contract tests also exposed and fixed an incorrect PATCH properties wrapper: ARM expects top-level reviewResult and justification. These tests pass, but they are not genuine recordings. No Authorization test settings, controlled pending request, or requester/approver test identities are provisioned here, so no unrelated request was approved and no recording/assets tag was fabricated. A maintainer needs to provision the documented test-only request, run Record then Playback, sanitize/publish assets, and commit the updated assets.json before this thread can be closed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Added and pushed genuine recordings in 6e19dce, captured against the user-selected subscription:

  • Should_list_pending_role_approvals: actual ARM GET, HTTP 200 (the subscription currently returns no approvals assigned to the signed-in approver).
  • Should_reject_missing_role_approval_stage: actual ARM PATCH of verified nonexistent approval/stage IDs, HTTP 404. This exercises the approval command without granting anyone access.

The published asset tag is Azure.Mcp.Tools.Authorization.Tests_dbcf027633 in Azure/azure-sdk-assets, and assets.json now references it. Added an ARM diagnostic-header sanitizer to remove tenant/principal identifiers, checked token/subscription/identity sanitization, and passed the test-proxy secret scan before publishing. The published tag restores cleanly and contains exactly the two new recording files.

Validation:

  • dotnet build tools\Azure.Mcp.Tools.Authorization\tests\Azure.Mcp.Tools.Authorization.Tests --nologo -v quiet: passed, zero warnings/errors.
  • Record mode: dotnet test --project tools\Azure.Mcp.Tools.Authorization\tests\Azure.Mcp.Tools.Authorization.Tests --no-build -- --filter-class '*AuthorizationApprovalCommandTests': 2 passed; the opt-in successful lifecycle was skipped.
  • Published-tag playback with AZURE_TOKEN_CREDENTIALS=PlaybackTokenCredential, MCP_TEST_TRANSPORT=stdio, and no local test settings: dotnet test --project tools\Azure.Mcp.Tools.Authorization\tests\Azure.Mcp.Tools.Authorization.Tests --no-build: 46 passed, 1 intentional lifecycle skip.
  • Published-tag playback with AZURE_TOKEN_CREDENTIALS=PlaybackTokenCredential and MCP_TEST_TRANSPORT=http: the approval-class command above passed 2 tests, with 1 intentional lifecycle skip.
  • Scoped formatting verification, spelling, and git diff --check: passed.

Leaving this thread open: these recordings cover discovery and the approval error path, not a successful access grant. The existing opt-in lifecycle test still needs a controlled pending request from a separate requester, its approval/stage IDs assigned to the signed-in approver, and authorization to approve that request. No pending request is currently available in the supplied subscription; no successful recording was fabricated or arbitrary approval performed.

Copilot AI commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Copilot , please address all ci errors

I checked the latest PR run: the platform build jobs are failing (Linux/Windows/macOS and container variants), while both npm-wrapper checks passed. Their details point to Azure DevOps; the logs endpoint is inaccessible from this environment (DNS failure), and local dotnet build is likewise blocked restoring packages from the Azure DevOps feed. I can’t identify a source error from the available status alone, so I made no speculative code changes. Please share the failing job’s first error from the Azure DevOps logs and I can address it.

Register approval tools in consolidated discovery, accept NotReviewed stages, follow and validate ARM continuation links, and correct the approval PATCH body. Add transport regressions and an opt-in recorded lifecycle test with controlled-request setup instructions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b235fdb-584f-444d-89af-754cc29a6bb1
@ArthurMa1978
Arthur Ma (ArthurMa1978) requested a review from a team as a code owner October 27, 2026 03:04
@ArthurMa1978

Arthur Ma (ArthurMa1978) commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Pushed da57dd3 with the review/CI fixes: - Fixed the missing Microsoft.Mcp.Core.Commands imports causing CS0246 in every failed platform build, and declared the new operations as control-plane commands. - Added separate consolidated mappings with correct safety metadata and read-only discovery coverage. - Accepted ARM NotReviewed pending stages and followed all continuation pages, validating each raw ARM URL against the configured cloud before client/token acquisition. - Corrected the approval PATCH body to the documented top-level reviewResult/justification contract and added real-service HTTP transport regressions. - Added a controlled, explicit RecordedCommandTestsBase lifecycle test and documented its Record/Playback setup. Actual cloud recording/playback remains blocked pending a dedicated request and requester/approver identities. The recording review thread remains open; assets.json was not fabricated or updated without a genuine recording. Validation | Command | Result | | --- | --- | | dotnet build tools\Azure.Mcp.Tools.Authorization\src --nologo -v minimal | Passed, zero warnings/errors | | dotnet build tools\Azure.Mcp.Tools.Authorization\src --configuration Release --nologo -v minimal | Passed, zero warnings/errors | | dotnet test --project tools\Azure.Mcp.Tools.Authorization\tests\Azure.Mcp.Tools.Authorization.Tests -- --filter-not-trait TestType=Live | Passed, 43 tests | | dotnet test --project servers\Azure.Mcp.Server\tests\Azure.Mcp.Server.Tests -- --filter-class '*MetadataSyncTests' --filter-class '*ConsolidatedToolMetadataTests' | Passed, 4 tests | | dotnet publish servers\Azure.Mcp.Server\src\Azure.Mcp.Server.csproj --configuration Release --runtime win-x64 --self-contained -p:PublishTrimmed=true -p:PublishSingleFile=true --output <session-artifact-directory> --nologo -v minimal | Passed; published executable startup also verified | | Scoped dotnet format ... --no-restore --include <changed C# files> | Passed | | Changed files piped to .\eng\common\spelling\Invoke-Cspell.ps1 | Passed, 10 files, zero spelling issues | | git diff --check | Passed | The new access-granting lifecycle test is intentionally opt-in and was not executed against Azure; discovery confirms it is skipped by default. GitHub event checks and CLA pass for the pushed commit. Azure Pipelines rejected both standard PR rerun commands with "the pull request was updated after the run command was issued", despite the verified unchanged head da57dd3. No new Azure validation build was queued. Hosted platform validation remains blocked by that service-side freshness gate; the previous build was 6988331. A maintainer needs to investigate the rejected trigger and queue standard PR validation after reviewing the current head.

@ArthurMa1978

Copy link
Copy Markdown
Member

/azp run mcp - pullrequest

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@ArthurMa1978

Copy link
Copy Markdown
Member

/azp run mcp - pullrequest

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

Resolve the shared insertion conflict in ConsolidatedToolMetadataTests by retaining both the PIM role discovery regressions and main's resilience goal assignment metadata coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b235fdb-584f-444d-89af-754cc29a6bb1
Add genuine Azure HTTP recordings for approval discovery and safe missing-stage rejection, sanitize ARM diagnostic identity metadata, and publish the verified asset tag. Both recordings replay in stdio and HTTP modes. Successful approval remains opt-in pending a controlled request from a separate requester.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b235fdb-584f-444d-89af-754cc29a6bb1
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.

[Feature Request] MCP support tracking PIM requests

4 participants