From 1dd9559e71fa2702bb296841a29aea7f556db6d3 Mon Sep 17 00:00:00 2001 From: Daniel Languiller Date: Tue, 30 Dec 2025 14:09:48 +1100 Subject: [PATCH 1/5] feature: add filters to exclude certs from keys/screts get cmdlets --- .../KeyVault/Models/Client/KeyVaultDataServiceClient.cs | 6 ++++-- src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/KeyVault/KeyVault/Models/Client/KeyVaultDataServiceClient.cs b/src/KeyVault/KeyVault/Models/Client/KeyVaultDataServiceClient.cs index 1d35da6ec860..e5906b4916bf 100644 --- a/src/KeyVault/KeyVault/Models/Client/KeyVaultDataServiceClient.cs +++ b/src/KeyVault/KeyVault/Models/Client/KeyVaultDataServiceClient.cs @@ -719,7 +719,8 @@ public IEnumerable GetSecrets(KeyVaultObjectFilter options.NextLink = result.NextPageLink; return (result == null) ? new List() : - result.Select((secretItem) => new PSKeyVaultSecretIdentityItem(secretItem, this.vaultUriHelper)); + result.Where((secretItem) => secretItem.Managed != true) + .Select((secretItem) => new PSKeyVaultSecretIdentityItem(secretItem, this.vaultUriHelper)); } catch (Exception ex) { @@ -748,7 +749,8 @@ public IEnumerable GetSecretVersions(KeyVaultObjec result = this.keyVaultClient.GetSecretVersionsNextAsync(options.NextLink).GetAwaiter().GetResult(); options.NextLink = result.NextPageLink; - return result.Select((secretItem) => new PSKeyVaultSecretIdentityItem(secretItem, this.vaultUriHelper)); + return result.Where((secretItem) => secretItem.Managed != true) + .Select((secretItem) => new PSKeyVaultSecretIdentityItem(secretItem, this.vaultUriHelper)); } catch (Exception ex) { diff --git a/src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs b/src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs index 15815ba1f55e..02e128899aa2 100644 --- a/src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs +++ b/src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs @@ -142,6 +142,10 @@ private IEnumerable GetKeys(KeyClient client) var allKeys = client.GetPropertiesOfKeys(); foreach (var keyProperties in allKeys) { + if (keyProperties.Managed == true) + { + continue; + } results.Add(new PSKeyVaultKeyIdentityItem(keyProperties, _vaultUriHelper, false)); } return results; @@ -159,6 +163,10 @@ private IEnumerable GetKeyVersions(KeyClient client, var allKeys = client.GetPropertiesOfKeyVersions(keyName); foreach (var keyProperties in allKeys) { + if (keyProperties.Managed == true) + { + continue; + } results.Add(new PSKeyVaultKeyIdentityItem(keyProperties, _vaultUriHelper, false)); } return results; From 74a1c360387fc30845cb4fc76dd8b05e3e995293 Mon Sep 17 00:00:00 2001 From: Daniel Languiller Date: Tue, 30 Dec 2025 16:18:33 +1100 Subject: [PATCH 2/5] test: add test in RunKeyVaultTests --- .../Scripts/RunKeyVaultTests.ps1 | 1 + .../KeyVault.Test/Scripts/VaultKeyTests.ps1 | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/KeyVault/KeyVault.Test/Scripts/RunKeyVaultTests.ps1 b/src/KeyVault/KeyVault.Test/Scripts/RunKeyVaultTests.ps1 index 5cdeb6909a09..cd469342ad65 100644 --- a/src/KeyVault/KeyVault.Test/Scripts/RunKeyVaultTests.ps1 +++ b/src/KeyVault/KeyVault.Test/Scripts/RunKeyVaultTests.ps1 @@ -331,6 +331,7 @@ function Run-AllDataPlaneTests Run-TestProtected { Run-KeyTest {Test_GetNonExistKey} "Test_GetNonExistKey" } "Test_GetNonExistKey" Run-TestProtected { Run-KeyTest {Test_GetKeyInNoPermissionVault} "Test_GetKeyInNoPermissionVault" } "Test_GetKeyInNoPermissionVault" Run-TestProtected { Run-KeyTest {Test_GetAllKeys} "Test_GetAllKeys" } "Test_GetAllKeys" + Run-TestProtected { Run-KeyTest {Test_GetKeysDoesNotReturnCertificateBackedKeys} "Test_GetKeysDoesNotReturnCertificateBackedKeys" } "Test_GetKeysDoesNotReturnCertificateBackedKeys" Run-TestProtected { Run-KeyTest {Test_GetKeyVersions} "Test_GetKeyVersions" } "Test_GetKeyVersions" # Remove-AzKeyVaultKey tests. diff --git a/src/KeyVault/KeyVault.Test/Scripts/VaultKeyTests.ps1 b/src/KeyVault/KeyVault.Test/Scripts/VaultKeyTests.ps1 index 739e8cf5a22d..e8b7b8cc51ba 100644 --- a/src/KeyVault/KeyVault.Test/Scripts/VaultKeyTests.ps1 +++ b/src/KeyVault/KeyVault.Test/Scripts/VaultKeyTests.ps1 @@ -615,6 +615,56 @@ function Test_GetAllKeys Assert-True { $keys.Count -ge $total } } +<# +.SYNOPSIS +Tests that Get-AzKeyVaultKey does not return certificate-backed managed keys +#> + +function Test_GetKeysDoesNotReturnCertificateBackedKeys +{ + $keyVault = Get-KeyVault + $certName = Get-CertificateName 'filtercert' + $keyName = Get-KeyName 'standalone' + + # Create a self-signed certificate (which creates a managed key) + $policy = New-AzKeyVaultCertificatePolicy -SubjectName "CN=test.contoso.com" -IssuerName Self -ValidityInMonths 12 + $certOp = Add-AzKeyVaultCertificate -VaultName $keyVault -Name $certName -CertificatePolicy $policy + + # Wait for certificate creation to complete + $attempts = 0 + do { + Wait-Seconds 5 + $cert = Get-AzKeyVaultCertificate -VaultName $keyVault -Name $certName + $attempts++ + } while (($cert -eq $null -or $cert.Certificate -eq $null) -and $attempts -lt 12) + + Assert-NotNull $cert "Certificate creation failed" + $global:createdCertificates += $certName + + # Create a standalone key + $key = Add-AzKeyVaultKey -VaultName $keyVault -Name $keyName -Destination 'Software' + Assert-NotNull $key + $global:createdKeys += $keyName + + # Get all keys - should only return standalone key, not certificate-backed key + $keys = Get-AzKeyVaultKey -VaultName $keyVault + + # Assert standalone key is present + $standaloneKey = $keys | Where-Object { $_.Name -eq $keyName } + Assert-NotNull $standaloneKey "Standalone key should be returned by Get-AzKeyVaultKey" + + # INTENTIONAL FAILURE: + Assert-Null $standaloneKey "DELIBERATE FAILURE: This should fail to prove test execution" + + # Assert certificate-backed key is NOT present + $certBackedKey = $keys | Where-Object { $_.Name -eq $certName } + Assert-Null $certBackedKey "Certificate-backed key should NOT be returned by Get-AzKeyVaultKey" + + # Verify certificate is still accessible via Get-AzKeyVaultCertificate + $certCheck = Get-AzKeyVaultCertificate -VaultName $keyVault -Name $certName + Assert-NotNull $certCheck "Certificate should still be accessible via Get-AzKeyVaultCertificate" +} + <# .SYNOPSIS Tests get previous version of a key from key vault From 3bf26886da05b3f171baec0b84b5a7302effa840 Mon Sep 17 00:00:00 2001 From: Daniel Languiller Date: Wed, 31 Dec 2025 11:13:06 +1100 Subject: [PATCH 3/5] Revert "test: add test in RunKeyVaultTests" This reverts commit 74a1c360387fc30845cb4fc76dd8b05e3e995293. --- .../Scripts/RunKeyVaultTests.ps1 | 1 - .../KeyVault.Test/Scripts/VaultKeyTests.ps1 | 50 ------------------- 2 files changed, 51 deletions(-) diff --git a/src/KeyVault/KeyVault.Test/Scripts/RunKeyVaultTests.ps1 b/src/KeyVault/KeyVault.Test/Scripts/RunKeyVaultTests.ps1 index cd469342ad65..5cdeb6909a09 100644 --- a/src/KeyVault/KeyVault.Test/Scripts/RunKeyVaultTests.ps1 +++ b/src/KeyVault/KeyVault.Test/Scripts/RunKeyVaultTests.ps1 @@ -331,7 +331,6 @@ function Run-AllDataPlaneTests Run-TestProtected { Run-KeyTest {Test_GetNonExistKey} "Test_GetNonExistKey" } "Test_GetNonExistKey" Run-TestProtected { Run-KeyTest {Test_GetKeyInNoPermissionVault} "Test_GetKeyInNoPermissionVault" } "Test_GetKeyInNoPermissionVault" Run-TestProtected { Run-KeyTest {Test_GetAllKeys} "Test_GetAllKeys" } "Test_GetAllKeys" - Run-TestProtected { Run-KeyTest {Test_GetKeysDoesNotReturnCertificateBackedKeys} "Test_GetKeysDoesNotReturnCertificateBackedKeys" } "Test_GetKeysDoesNotReturnCertificateBackedKeys" Run-TestProtected { Run-KeyTest {Test_GetKeyVersions} "Test_GetKeyVersions" } "Test_GetKeyVersions" # Remove-AzKeyVaultKey tests. diff --git a/src/KeyVault/KeyVault.Test/Scripts/VaultKeyTests.ps1 b/src/KeyVault/KeyVault.Test/Scripts/VaultKeyTests.ps1 index e8b7b8cc51ba..739e8cf5a22d 100644 --- a/src/KeyVault/KeyVault.Test/Scripts/VaultKeyTests.ps1 +++ b/src/KeyVault/KeyVault.Test/Scripts/VaultKeyTests.ps1 @@ -615,56 +615,6 @@ function Test_GetAllKeys Assert-True { $keys.Count -ge $total } } -<# -.SYNOPSIS -Tests that Get-AzKeyVaultKey does not return certificate-backed managed keys -#> - -function Test_GetKeysDoesNotReturnCertificateBackedKeys -{ - $keyVault = Get-KeyVault - $certName = Get-CertificateName 'filtercert' - $keyName = Get-KeyName 'standalone' - - # Create a self-signed certificate (which creates a managed key) - $policy = New-AzKeyVaultCertificatePolicy -SubjectName "CN=test.contoso.com" -IssuerName Self -ValidityInMonths 12 - $certOp = Add-AzKeyVaultCertificate -VaultName $keyVault -Name $certName -CertificatePolicy $policy - - # Wait for certificate creation to complete - $attempts = 0 - do { - Wait-Seconds 5 - $cert = Get-AzKeyVaultCertificate -VaultName $keyVault -Name $certName - $attempts++ - } while (($cert -eq $null -or $cert.Certificate -eq $null) -and $attempts -lt 12) - - Assert-NotNull $cert "Certificate creation failed" - $global:createdCertificates += $certName - - # Create a standalone key - $key = Add-AzKeyVaultKey -VaultName $keyVault -Name $keyName -Destination 'Software' - Assert-NotNull $key - $global:createdKeys += $keyName - - # Get all keys - should only return standalone key, not certificate-backed key - $keys = Get-AzKeyVaultKey -VaultName $keyVault - - # Assert standalone key is present - $standaloneKey = $keys | Where-Object { $_.Name -eq $keyName } - Assert-NotNull $standaloneKey "Standalone key should be returned by Get-AzKeyVaultKey" - - # INTENTIONAL FAILURE: - Assert-Null $standaloneKey "DELIBERATE FAILURE: This should fail to prove test execution" - - # Assert certificate-backed key is NOT present - $certBackedKey = $keys | Where-Object { $_.Name -eq $certName } - Assert-Null $certBackedKey "Certificate-backed key should NOT be returned by Get-AzKeyVaultKey" - - # Verify certificate is still accessible via Get-AzKeyVaultCertificate - $certCheck = Get-AzKeyVaultCertificate -VaultName $keyVault -Name $certName - Assert-NotNull $certCheck "Certificate should still be accessible via Get-AzKeyVaultCertificate" -} - <# .SYNOPSIS Tests get previous version of a key from key vault From 357f6dc14a204d25084596824ea7c1e7ef418522 Mon Sep 17 00:00:00 2001 From: Daniel Languiller Date: Wed, 31 Dec 2025 14:47:04 +1100 Subject: [PATCH 4/5] test: add pester tests for certificate filtering --- .../CertificateBackedKeyFiltering.Tests.ps1 | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/KeyVault/KeyVault.Test/PesterTests/CertificateBackedKeyFiltering.Tests.ps1 diff --git a/src/KeyVault/KeyVault.Test/PesterTests/CertificateBackedKeyFiltering.Tests.ps1 b/src/KeyVault/KeyVault.Test/PesterTests/CertificateBackedKeyFiltering.Tests.ps1 new file mode 100644 index 000000000000..600f16317dca --- /dev/null +++ b/src/KeyVault/KeyVault.Test/PesterTests/CertificateBackedKeyFiltering.Tests.ps1 @@ -0,0 +1,57 @@ + +$debugModulePath = "$PSScriptRoot\..\..\..\..\artifacts\Debug\Az.KeyVault\Az.KeyVault.psd1" +Import-Module $debugModulePath -Force + +$vaultName = 'danielKV5816' +. "$PSScriptRoot\..\Scripts\Common.ps1" + +Describe "Get-AzKeyVaultKey filters certificate-backed keys" { + It "Should not return certificate-backed managed keys" { + $certName = Get-CertificateName + $keyName = Get-KeyName + + # Create a self-signed certificate (creates a managed key) + $policy = New-AzKeyVaultCertificatePolicy -SecretContentType "application/x-pkcs12" -SubjectName "CN=test.contoso.com" -IssuerName Self -ValidityInMonths 6 + $certOp = Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certName -CertificatePolicy $policy + + Start-Sleep -Seconds 30 + $cert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certName + $cert | Should Not BeNullOrEmpty + + $key = Add-AzKeyVaultKey -VaultName $vaultName -Name $keyName -Destination Software + $key | Should Not BeNullOrEmpty + + $keys = Get-AzKeyVaultKey -VaultName $vaultName + + $standaloneKey = $keys | Where-Object { $_.Name -eq $keyName } + $standaloneKey | Should Not BeNullOrEmpty + + $certBackedKey = $keys | Where-Object { $_.Name -eq $certName } + $certBackedKey | Should BeNullOrEmpty + } +} + +Describe "Get-AzKeyVaultSecret filters certificate-backed secrets" { + It "Should not return certificate-backed managed secrets" { + $certName = Get-CertificateName + $secretName = Get-SecretName + + # Create a certificate (creates both managed key AND managed secret) + $policy = New-AzKeyVaultCertificatePolicy -SecretContentType "application/x-pkcs12" -SubjectName "CN=test2.contoso.com" -IssuerName Self -ValidityInMonths 6 + $certOp = Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certName -CertificatePolicy $policy + + Start-Sleep -Seconds 30 + + $secretValue = ConvertTo-SecureString "MySecretValue123!" -AsPlainText -Force + $secret = Set-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -SecretValue $secretValue + $secret | Should Not BeNullOrEmpty + + $secrets = Get-AzKeyVaultSecret -VaultName $vaultName + + $standaloneSecret = $secrets | Where-Object { $_.Name -eq $secretName } + $standaloneSecret | Should Not BeNullOrEmpty + + $certBackedSecret = $secrets | Where-Object { $_.Name -eq $certName } + $certBackedSecret | Should BeNullOrEmpty + } +} From 8e4f354555dadd87e88fcefa22adc86d9ea248d6 Mon Sep 17 00:00:00 2001 From: Daniel Languiller Date: Wed, 31 Dec 2025 15:24:29 +1100 Subject: [PATCH 5/5] fix: address copilot suggestions --- .../CertificateBackedKeyFiltering.Tests.ps1 | 2 +- .../KeyVault/Track2Models/Track2VaultClient.cs | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/KeyVault/KeyVault.Test/PesterTests/CertificateBackedKeyFiltering.Tests.ps1 b/src/KeyVault/KeyVault.Test/PesterTests/CertificateBackedKeyFiltering.Tests.ps1 index 600f16317dca..e4335c06e328 100644 --- a/src/KeyVault/KeyVault.Test/PesterTests/CertificateBackedKeyFiltering.Tests.ps1 +++ b/src/KeyVault/KeyVault.Test/PesterTests/CertificateBackedKeyFiltering.Tests.ps1 @@ -2,7 +2,7 @@ $debugModulePath = "$PSScriptRoot\..\..\..\..\artifacts\Debug\Az.KeyVault\Az.KeyVault.psd1" Import-Module $debugModulePath -Force -$vaultName = 'danielKV5816' +$vaultName = 'danielKV7103' . "$PSScriptRoot\..\Scripts\Common.ps1" Describe "Get-AzKeyVaultKey filters certificate-backed keys" { diff --git a/src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs b/src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs index 02e128899aa2..c88a72fc463f 100644 --- a/src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs +++ b/src/KeyVault/KeyVault/Track2Models/Track2VaultClient.cs @@ -142,11 +142,10 @@ private IEnumerable GetKeys(KeyClient client) var allKeys = client.GetPropertiesOfKeys(); foreach (var keyProperties in allKeys) { - if (keyProperties.Managed == true) + if (keyProperties.Managed != true) { - continue; + results.Add(new PSKeyVaultKeyIdentityItem(keyProperties, _vaultUriHelper, false)); } - results.Add(new PSKeyVaultKeyIdentityItem(keyProperties, _vaultUriHelper, false)); } return results; } @@ -163,11 +162,10 @@ private IEnumerable GetKeyVersions(KeyClient client, var allKeys = client.GetPropertiesOfKeyVersions(keyName); foreach (var keyProperties in allKeys) { - if (keyProperties.Managed == true) + if (keyProperties.Managed != true) { - continue; + results.Add(new PSKeyVaultKeyIdentityItem(keyProperties, _vaultUriHelper, false)); } - results.Add(new PSKeyVaultKeyIdentityItem(keyProperties, _vaultUriHelper, false)); } return results; }