Fix KV Functional Issues.#2671
Conversation
…tingsClient factory, and KeyType description - KV-01: Fix includeManagedKeys filter to be additive (include all keys when true) instead of exclusive; previously true returned only managed keys with no way to list all keys - KV-05/KV-04: Extract CreateSettingsClient factory method so GetVaultSettings uses IHttpClientFactory, applies retry policy, and wires HttpClientTransport for test recording/playback (retryPolicy parameter was previously silently ignored) - KV-10: Expand KeyType option description to list all 6 valid types (RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM) instead of only RSA and EC - KV-11: Re-throw FormatException as ArgumentException in ImportCertificate so the base handler maps it to HTTP 400 instead of HTTP 500
- Fix ArgumentException message in ImportCertificate to restore 'file path' as a tried option (message previously said 'neither raw PEM nor base64' but the code still tries File.Exists first) - Add test: CertificateImportCommand returns HTTP 400 when service throws ArgumentException for invalid certificate data (KV-11 coverage) - Add test: KeyGetCommand includes Managed=null keys when includeManagedKeys is false, documenting the != true vs == false distinction (KV-01 coverage) - Fix AdminSettingsGetCommandTests env var leak: wrap SetAzureSubscriptionId in try/finally with ClearAzureSubscriptionId to prevent AZURE_SUBSCRIPTION_ID from persisting across tests - Extract subscription-dependent RejectsInvalidArguments case into separate Fact that calls SkipIfDefaultSubscriptionConfigured (fixes pre-existing test failure when az login is active) - Add TestEnvironment.SkipIfDefaultSubscriptionConfigured() helper method for tests that validate missing --subscription but need to skip when a default subscription is available via env var or Azure CLI profile - Add changelog entry for the four KeyVault bug fixes
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Fixes several functional bugs in the Key Vault tool: incorrect key listing filter, missing retry/transport wiring on the HSM settings client, an incomplete key-type description, and improper HTTP status mapping for invalid certificate import data. Tests are updated/added to cover the new behaviors.
Changes:
- Corrected
ListKeysfilter soincludeManagedKeys=truereturns all keys and=falsereturns non-managed (including nullManaged). - Wired retry policy and
HttpClientTransportinto theKeyVaultSettingsClientused byGetVaultSettings, and changed invalid certificate-data error to throwArgumentException(→ HTTP 400) with an updated message. - Expanded the
--key-typeoption description to enumerate all valid key types, plus test updates and a changelog entry.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/Azure.Mcp.Tools.KeyVault/src/Services/KeyVaultService.cs | Fixed managed-key filter, switched invalid-cert exception to ArgumentException, added CreateSettingsClient with retry/transport. |
| tools/Azure.Mcp.Tools.KeyVault/src/Options/KeyVaultOptionDefinitions.cs | Expanded KeyType description to list all valid values. |
| tools/Azure.Mcp.Tools.KeyVault/tests/.../Key/KeyGetCommandTests.cs | Added test documenting null-Managed keys included when includeManagedKeys=false. |
| tools/Azure.Mcp.Tools.KeyVault/tests/.../Certificate/CertificateImportCommandTests.cs | Split subscription-missing scenario, updated invalid-data test to expect HTTP 400 / ArgumentException. |
| tools/Azure.Mcp.Tools.KeyVault/tests/.../Admin/AdminSettingsGetCommandTests.cs | Wrapped env-var setup in try/finally to clear AZURE_SUBSCRIPTION_ID. |
| servers/Azure.Mcp.Server/changelog-entries/1778609827495.yaml | New changelog entry describing the fixes. |
| private KeyVaultSettingsClient CreateSettingsClient(Uri hsmUri, Azure.Core.TokenCredential credential, RetryPolicyOptions? retry) | ||
| { | ||
| var httpClient = _httpClientFactory.CreateClient(); | ||
| httpClient.BaseAddress = hsmUri; | ||
| var options = new KeyVaultAdministrationClientOptions(); | ||
| options = ConfigureRetryPolicy(AddDefaultPolicies(options), retry); | ||
| options.Transport = new Azure.Core.Pipeline.HttpClientTransport(httpClient); | ||
| return new(hsmUri, credential, options); | ||
| } |
| changes: | ||
| - section: "Bugs Fixed" | ||
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy and wires the HTTP transport for test recording; KeyType option now lists all 6 valid types (RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" |
| ) | ||
| { | ||
| Description = "The type of key to create (RSA, EC).", | ||
| Description = "The type of key to create. Valid values: RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM.", |
| var keys = new List<string>(); | ||
|
|
||
| await foreach (var key in client.GetPropertiesOfKeysAsync(cancellationToken).Where(x => x.Managed == includeManagedKeys)) | ||
| await foreach (var key in client.GetPropertiesOfKeysAsync(cancellationToken).Where(x => includeManagedKeys || x.Managed != true)) |
| @@ -0,0 +1,3 @@ | |||
| changes: | |||
| - section: "Bugs Fixed" | |||
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy and wires the HTTP transport for test recording; KeyType option now lists all 6 valid types (RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" | |||
There was a problem hiding this comment.
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy and wires the HTTP transport for test recording; KeyType option now lists all 6 valid types (RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" | |
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy; KeyType option now lists all 6 valid types (RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" |
Don't need to talk about testing details in release notes
There was a problem hiding this comment.
On top of Alan's suggestion, we actually don't support creating oct and oct-HSM keys (they're exclusive to Managed HSM).
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy and wires the HTTP transport for test recording; KeyType option now lists all 6 valid types (RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" | |
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy; KeyType option now lists all 4 valid types (RSA, RSA-HSM, EC, EC-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" |
| @@ -0,0 +1,3 @@ | |||
| changes: | |||
| - section: "Bugs Fixed" | |||
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy and wires the HTTP transport for test recording; KeyType option now lists all 6 valid types (RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" | |||
There was a problem hiding this comment.
On top of Alan's suggestion, we actually don't support creating oct and oct-HSM keys (they're exclusive to Managed HSM).
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy and wires the HTTP transport for test recording; KeyType option now lists all 6 valid types (RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" | |
| description: "Fixed four Key Vault bugs: ListKeys now correctly includes all keys (managed and non-managed) when --include-managed is true instead of returning only managed keys; AdminSettingsGetCommand now applies retry policy; KeyType option now lists all 4 valid types (RSA, RSA-HSM, EC, EC-HSM); ImportCertificate now returns HTTP 400 for invalid certificate data instead of HTTP 500" |
| ) | ||
| { | ||
| Description = "The type of key to create (RSA, EC).", | ||
| Description = "The type of key to create. Valid values: RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM.", |
There was a problem hiding this comment.
Currently, we only support creating keys for Azure Key Vault, not Managed HSM (so no oct and oct-HSM). We can add support for those in a future PR, but right now this description would not match reality.
That said, EC-HSM and RSA-HSM keys can only be created on premium SKU vaults. So maybe we should add a clarification on the keyvault create key tool description. What do you think?
| Description = "The type of key to create. Valid values: RSA, RSA-HSM, EC, EC-HSM, oct, oct-HSM.", | |
| Description = "The type of key to create. Valid values: RSA, RSA-HSM, EC, EC-HSM", |
There was a problem hiding this comment.
We should also make sure the tool description matches whatever we decide. It mentions all 6 types currently.
| var keys = new List<string>(); | ||
|
|
||
| await foreach (var key in client.GetPropertiesOfKeysAsync(cancellationToken).Where(x => x.Managed == includeManagedKeys)) | ||
| await foreach (var key in client.GetPropertiesOfKeysAsync(cancellationToken).Where(x => includeManagedKeys || x.Managed != true)) |
Resolves https://github.com/microsoft/mcp-pr/issues/413, https://github.com/microsoft/mcp-pr/issues/412, https://github.com/microsoft/mcp-pr/issues/410, https://github.com/microsoft/mcp-pr/issues/409, https://github.com/microsoft/mcp-pr/issues/408