Skip to content

Commit 0481a4f

Browse files
authored
[Az.KeyVault] User mi support for backup/restore hsm (#23916)
* user mi support for backup/restore hsm * user mi support for backup/restore hsm * user mi support for backup/restore hsm help * user mi support for backup/restore hsm polish * user mi support for backup/restore hsm polish * user mi support for backup/restore hsm polish * Update ChangeLog.md * edge case * edge case
1 parent cd7697b commit 0481a4f

File tree

10 files changed

+165
-26
lines changed

10 files changed

+165
-26
lines changed

src/KeyVault/KeyVault.Test/PesterTests/ManagedHsmDataPlaneTests.Tests.ps1

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
66
# ImportModules
77
$hsmName = 'yeminghsm112901'
88
$signInName = '[email protected]'
9+
$subscriptionId = '0b1f6471-1bf0-4dda-aec3-cb9272f09590'
910
$storageAccount = 'bezstorageaccount'
1011
$containerName = 'backup'
1112
$keyName = 'test'
13+
$userManagedIdentityName = 'nori-identity'
14+
$resourceGroupName = 'nori-testhsm'
1215
# $sasToken = ConvertTo-SecureString -AsPlainText -Force 'insert sas token'
1316
$certs = "D:\sd1.cer", "D:\sd2.cer", "D:\sd3.cer" # for security domain
1417
$certsKeys = @{PublicKey = "D:\sd1.cer"; PrivateKey = "D:\sd1.key" }, @{PublicKey = "D:\sd2.cer"; PrivateKey = "D:\sd2.key" }, @{PublicKey = "D:\sd3.cer"; PrivateKey = "D:\sd3.key" }
@@ -176,6 +179,12 @@ Describe "BackupAndRestoreAzManagedHsm" {
176179
$script:backupUri | Should -Not -Be $null
177180
}
178181

182+
It "Backup a managed Hsm via User Assigned Managed Identity"{
183+
Update-AzKeyVaultManagedHsm -UserAssignedIdentity "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$userManagedIdentityName"
184+
$script:backupUri = Backup-AzKeyVault -HsmName $hsmName -StorageContainerUri $containerUri -UseUserManagedIdentity
185+
$script:backupUri | Should -Not -Be $null
186+
}
187+
179188
It "Selective restore a key to managed HSM" {
180189
$script:backupUri = [System.Uri]::new($script:backupUri)
181190
$backupFolder = $script:backupUri.Segments[$script:backupUri.Segments.Length - 1]
@@ -192,6 +201,11 @@ Describe "BackupAndRestoreAzManagedHsm" {
192201
$restoreResult = Restore-AzKeyVault -HsmName $hsmName -StorageContainerUri $containerUri -BackupFolder $backupFolder -SasToken $sasToken -PassThru
193202
$restoreResult | Should -Be $True
194203
}
204+
205+
It "Restore a managed Hsm via User Assigned Managed Identity"{
206+
$restoreResult = Restore-AzKeyVault -HsmName $hsmName -StorageContainerUri $containerUri -BackupFolder $backupFolder -UseUserManagedIdentity
207+
$restoreResult | Should -Be $True
208+
}
195209
}
196210

197211
Describe "GetAzManagedHsmRoleDefinition" {

src/KeyVault/KeyVault/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- Additional information about change #1
1919
-->
2020
## Upcoming Release
21+
* Supported authentication via User Managed Identity by adding parameter `UseUserManagedIdentity` and making `SasToken` optional.
2122

2223
## Version 5.1.0
2324
* Added parameter `ByteArrayValue` in `Invoke-AzKeyVaultKeyOperation` to support operating byte array without conversion to secure string.

src/KeyVault/KeyVault/Commands/FullBackupRestore/BackupAzureManagedHsm.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public override void DoExecuteCmdlet()
2020
{
2121
try
2222
{
23-
WriteObject(Track2DataClient.BackupHsm(HsmName, StorageContainerUri, SasToken.ConvertToString()).AbsoluteUri);
23+
WriteObject(Track2DataClient.BackupHsm(HsmName, StorageContainerUri, SasToken?.ConvertToString()).AbsoluteUri);
2424
}
2525
catch (Exception ex)
2626
{

src/KeyVault/KeyVault/Commands/FullBackupRestore/FullBackupRestoreCmdletBase.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
using Microsoft.Azure.Commands.Common.Authentication;
1+
using Microsoft.Azure.Commands.KeyVault.Properties;
2+
using Microsoft.Azure.Commands.Common;
3+
using Microsoft.Azure.Commands.Common.Authentication;
24
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
5+
using Microsoft.Azure.Commands.Common.Exceptions;
36
using Microsoft.Azure.Commands.KeyVault.Models;
47
using Microsoft.WindowsAzure.Commands.Utilities.Common;
58
using System;
@@ -39,9 +42,12 @@ public abstract class FullBackupRestoreCmdletBase : KeyVaultCmdletBase
3942
HelpMessage = "Name of the blob container where the backup is going to be stored.")]
4043
public string StorageContainerName { get; set; }
4144

42-
[Parameter(Mandatory = true, HelpMessage = "The shared access signature (SAS) token to authenticate the storage account.")]
45+
[Parameter(Mandatory = false, HelpMessage = "The shared access signature (SAS) token to authenticate the storage account.")]
4346
public SecureString SasToken { get; set; }
4447

48+
[Parameter(Mandatory = false, HelpMessage = "Specified to use User Managed Identity to authenticate the storage account. Only valid when SasToken is not set.")]
49+
public SwitchParameter UseUserManagedIdentity { get; set; }
50+
4551
[Parameter(ParameterSetName = InputObjectStorageUri, Mandatory = true, ValueFromPipeline = true, HelpMessage = "Managed HSM object")]
4652
[Parameter(ParameterSetName = InputObjectStorageName, Mandatory = true, ValueFromPipeline = true, HelpMessage = "Managed HSM object")]
4753
public PSManagedHsm HsmObject { get; set; }
@@ -64,7 +70,22 @@ private void PreprocessParameterSet()
6470

6571
if (this.IsParameterBound(c => c.StorageAccountName))
6672
{
67-
StorageContainerUri = new Uri($"https://{StorageAccountName}.{DefaultContext.Environment.GetEndpoint(AzureEnvironment.Endpoint.StorageEndpointSuffix)}/{StorageContainerName}");
73+
StorageContainerUri = new Uri($"https://{StorageAccountName}.blob.{DefaultContext.Environment.GetEndpoint(AzureEnvironment.Endpoint.StorageEndpointSuffix)}/{StorageContainerName}");
74+
}
75+
76+
if (this.IsParameterBound(c => c.SasToken) && SasToken == null)
77+
{
78+
throw new AzPSArgumentException(Resources.SasTokenNotNull, ErrorKind.UserError);
79+
}
80+
81+
if (this.IsParameterBound(c => c.SasToken) && this.UseUserManagedIdentity.IsPresent)
82+
{
83+
throw new AzPSArgumentException(Resources.UseManagedIdentityAndSasTokenBothExist, ErrorKind.UserError);
84+
}
85+
86+
if (!this.IsParameterBound(c => c.SasToken) && !this.UseUserManagedIdentity.IsPresent)
87+
{
88+
throw new AzPSArgumentException(Resources.UseManagedIdentityAndSasTokenNeitherExist, ErrorKind.UserError);
6889
}
6990
}
7091

src/KeyVault/KeyVault/Commands/FullBackupRestore/RestoreAzureManagedHsm.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ public override void DoExecuteCmdlet()
3131
{
3232
if(KeyName == null)
3333
{
34-
Track2DataClient.RestoreHsm(HsmName, StorageContainerUri, SasToken.ConvertToString(), BackupFolder);
34+
Track2DataClient.RestoreHsm(HsmName, StorageContainerUri, SasToken?.ConvertToString(), BackupFolder);
3535
}
3636
else
3737
{
38-
Track2DataClient.SelectiveRestoreHsm(HsmName, KeyName,StorageContainerUri, SasToken.ConvertToString(), BackupFolder);
38+
Track2DataClient.SelectiveRestoreHsm(HsmName, KeyName,StorageContainerUri, SasToken?.ConvertToString(), BackupFolder);
3939
errorMsg = string.Format(Resources.SelectiveRestoreFailed, KeyName, HsmName);
4040
}
4141
}

src/KeyVault/KeyVault/KeyVault.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</PropertyGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="Azure.Security.KeyVault.Administration" Version="4.3.0" />
15+
<PackageReference Include="Azure.Security.KeyVault.Administration" Version="4.4.0-beta.1" />
1616
<PackageReference Include="Azure.Security.KeyVault.Keys" Version="4.3.0" />
1717
<PackageReference Include="Azure.Security.KeyVault.Certificates" Version="4.3.0" />
1818
<PackageReference Include="Portable.BouncyCastle" Version="1.8.8" />

src/KeyVault/KeyVault/Properties/Resources.Designer.cs

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/KeyVault/KeyVault/Properties/Resources.resx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,4 +618,13 @@ You can find the object ID using Azure Active Directory Module for Windows Power
618618
<data name="UpdateKeyVaultSetting" xml:space="preserve">
619619
<value>Update vault setting</value>
620620
</data>
621+
<data name="SasTokenNotNull" xml:space="preserve">
622+
<value>Please provide a valid SasToken or use Managed Identity for authentication.</value>
623+
</data>
624+
<data name="UseManagedIdentityAndSasTokenBothExist" xml:space="preserve">
625+
<value>Parameter SasToken and UseUserManagedIdentity can not exist at the same time. Please choose either one as authentication method.</value>
626+
</data>
627+
<data name="UseManagedIdentityAndSasTokenNeitherExist" xml:space="preserve">
628+
<value>Please choose either SasToken or UseUserManagedIdentity as authentication method.</value>
629+
</data>
621630
</root>

src/KeyVault/KeyVault/help/Backup-AzKeyVault.md

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,27 @@ Fully backup a managed HSM.
1515
### InteractiveStorageName (Default)
1616
```
1717
Backup-AzKeyVault [-HsmName] <String> -StorageAccountName <String> -StorageContainerName <String>
18-
-SasToken <SecureString> [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
18+
[-SasToken <SecureString>] [-UseUserManagedIdentity] [-DefaultProfile <IAzureContextContainer>] [-WhatIf]
19+
[-Confirm] [<CommonParameters>]
1920
```
2021

2122
### InteractiveStorageUri
2223
```
23-
Backup-AzKeyVault [-HsmName] <String> -StorageContainerUri <Uri> -SasToken <SecureString>
24-
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
24+
Backup-AzKeyVault [-HsmName] <String> -StorageContainerUri <Uri> [-SasToken <SecureString>]
25+
[-UseUserManagedIdentity] [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
2526
```
2627

2728
### InputObjectStorageUri
2829
```
29-
Backup-AzKeyVault -StorageContainerUri <Uri> -SasToken <SecureString> -HsmObject <PSManagedHsm>
30-
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
30+
Backup-AzKeyVault -StorageContainerUri <Uri> [-SasToken <SecureString>] [-UseUserManagedIdentity]
31+
-HsmObject <PSManagedHsm> [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
3132
```
3233

3334
### InputObjectStorageName
3435
```
35-
Backup-AzKeyVault -StorageAccountName <String> -StorageContainerName <String> -SasToken <SecureString>
36-
-HsmObject <PSManagedHsm> [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
36+
Backup-AzKeyVault -StorageAccountName <String> -StorageContainerName <String> [-SasToken <SecureString>]
37+
[-UseUserManagedIdentity] -HsmObject <PSManagedHsm> [-DefaultProfile <IAzureContextContainer>] [-WhatIf]
38+
[-Confirm] [<CommonParameters>]
3739
```
3840

3941
## DESCRIPTION
@@ -42,7 +44,7 @@ Use `Restore-AzKeyVault` to restore the backup.
4244

4345
## EXAMPLES
4446

45-
### Example 1
47+
### Example 1 Backup an HSM to Storage Container using SAS token
4648
```powershell
4749
$sasToken = ConvertTo-SecureString -AsPlainText -Force "?sv=2019-12-12&ss=bfqt&srt=sco&sp=rwdlacupx&se=2020-10-12T14:42:19Z&st=2020-10-12T06:42:19Z&spr=https&sig=******"
4850
@@ -55,6 +57,31 @@ https://{accountName}.blob.core.windows.net/{containerName}/{backupFolder}
5557

5658
The cmdlet will create a folder (typically named `mhsm-{name}-{timestamp}`) in the storage container, store the backup in that folder and output the folder URI.
5759

60+
### Example 2 Backup an HSM to Storage Container via User Assigned Managed Identity Authentication
61+
```powershell
62+
# Make sure an identity is assigend to the Hsm
63+
Update-AzKeyVaultManagedHsm -UserAssignedIdentity "/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity-name}"
64+
Backup-AzKeyVault -HsmName myHsm -StorageContainerUri "https://{accountName}.blob.core.windows.net/{containerName}" -UseUserManagedIdentity
65+
```
66+
67+
```output
68+
https://{accountName}.blob.core.windows.net/{containerName}/{backupFolder}
69+
```
70+
71+
The cmdlet will backup the hsm in specific Storage Container and output the folder URI via User Assigned Managed Identity Authentication. The Managed Identity should be assigned access permission to the storage container.
72+
73+
### Example 3 Backup an HSM to Storage Container using Storage Account Name and Storage Container
74+
```powershell
75+
Backup-AzKeyVault -HsmName myHsm -StorageAccountName "{accountName}" -StorageContainerName "{containerName}" -UseUserManagedIdentity
76+
```
77+
78+
```output
79+
https://{accountName}.blob.core.windows.net/{containerName}/{backupFolder}
80+
```
81+
82+
The cmdlet will create a folder (typically named `mhsm-{name}-{timestamp}`) in the storage container, store the backup in that folder and output the folder URI.
83+
84+
5885
## PARAMETERS
5986

6087
### -DefaultProfile
@@ -110,7 +137,7 @@ Type: System.Security.SecureString
110137
Parameter Sets: (All)
111138
Aliases:
112139

113-
Required: True
140+
Required: False
114141
Position: Named
115142
Default value: None
116143
Accept pipeline input: False
@@ -162,6 +189,21 @@ Accept pipeline input: False
162189
Accept wildcard characters: False
163190
```
164191
192+
### -UseUserManagedIdentity
193+
Specified to use User Managed Identity to authenticate the storage account. Only valid when SasToken is not set.
194+
195+
```yaml
196+
Type: System.Management.Automation.SwitchParameter
197+
Parameter Sets: (All)
198+
Aliases:
199+
200+
Required: False
201+
Position: Named
202+
Default value: None
203+
Accept pipeline input: False
204+
Accept wildcard characters: False
205+
```
206+
165207
### -Confirm
166208
Prompts you for confirmation before running the cmdlet.
167209

src/KeyVault/KeyVault/help/Restore-AzKeyVault.md

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,28 @@ Fully restores a managed HSM from backup.
1515
### InteractiveStorageName (Default)
1616
```
1717
Restore-AzKeyVault -BackupFolder <String> [-KeyName <String>] [-PassThru] [-HsmName] <String>
18-
-StorageAccountName <String> -StorageContainerName <String> -SasToken <SecureString>
19-
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
18+
-StorageAccountName <String> -StorageContainerName <String> [-SasToken <SecureString>]
19+
[-UseUserManagedIdentity] [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
2020
```
2121

2222
### InteractiveStorageUri
2323
```
2424
Restore-AzKeyVault -BackupFolder <String> [-KeyName <String>] [-PassThru] [-HsmName] <String>
25-
-StorageContainerUri <Uri> -SasToken <SecureString> [-DefaultProfile <IAzureContextContainer>] [-WhatIf]
26-
[-Confirm] [<CommonParameters>]
25+
-StorageContainerUri <Uri> [-SasToken <SecureString>] [-UseUserManagedIdentity]
26+
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
2727
```
2828

2929
### InputObjectStorageUri
3030
```
3131
Restore-AzKeyVault -BackupFolder <String> [-KeyName <String>] [-PassThru] -StorageContainerUri <Uri>
32-
-SasToken <SecureString> -HsmObject <PSManagedHsm> [-DefaultProfile <IAzureContextContainer>] [-WhatIf]
33-
[-Confirm] [<CommonParameters>]
32+
[-SasToken <SecureString>] [-UseUserManagedIdentity] -HsmObject <PSManagedHsm>
33+
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
3434
```
3535

3636
### InputObjectStorageName
3737
```
3838
Restore-AzKeyVault -BackupFolder <String> [-KeyName <String>] [-PassThru] -StorageAccountName <String>
39-
-StorageContainerName <String> -SasToken <SecureString> -HsmObject <PSManagedHsm>
39+
-StorageContainerName <String> [-SasToken <SecureString>] [-UseUserManagedIdentity] -HsmObject <PSManagedHsm>
4040
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
4141
```
4242

@@ -46,14 +46,24 @@ Use `Backup-AzKeyVault` to backup.
4646

4747
## EXAMPLES
4848

49-
### Example 1
49+
### Example 1 Restore a Key Vault
5050
```powershell
5151
$sasToken = ConvertTo-SecureString -AsPlainText -Force "?sv=2019-12-12&ss=bfqt&srt=sco&sp=rwdlacupx&se=2020-10-12T14:42:19Z&st=2020-10-12T06:42:19Z&spr=https&sig=******"
5252
Restore-AzKeyVault -HsmName myHsm -StorageContainerUri "https://{accountName}.blob.core.windows.net/{containerName}" -BackupFolder "mhsm-myHsm-2020101308504935" -SasToken $sasToken
5353
```
5454

5555
The example restores a backup stored in a folder named "mhsm-myHsm-2020101308504935" of a storage container "https://{accountName}.blob.core.windows.net/{containerName}".
5656

57+
### Example 2 Restore a Key Vault via User Assigned Managed Identity Authentication
58+
```powershell
59+
# Make sure an identity is assigend to the Hsm
60+
Update-AzKeyVaultManagedHsm -UserAssignedIdentity "/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity-name}"
61+
Restore-AzKeyVault -HsmName myHsm -StorageContainerUri "https://{accountName}.blob.core.windows.net/{containerName}" -BackupFolder "mhsm-myHsm-2020101308504935" -UseUserManagedIdentity
62+
```
63+
64+
The example restores an HSM via User Assigned Managed Identity Authentication.
65+
66+
5767
## PARAMETERS
5868

5969
### -BackupFolder
@@ -156,7 +166,7 @@ Type: System.Security.SecureString
156166
Parameter Sets: (All)
157167
Aliases:
158168

159-
Required: True
169+
Required: False
160170
Position: Named
161171
Default value: None
162172
Accept pipeline input: False
@@ -208,6 +218,21 @@ Accept pipeline input: False
208218
Accept wildcard characters: False
209219
```
210220
221+
### -UseUserManagedIdentity
222+
Specified to use User Managed Identity to authenticate the storage account. Only valid when SasToken is not set.
223+
224+
```yaml
225+
Type: System.Management.Automation.SwitchParameter
226+
Parameter Sets: (All)
227+
Aliases:
228+
229+
Required: False
230+
Position: Named
231+
Default value: None
232+
Accept pipeline input: False
233+
Accept wildcard characters: False
234+
```
235+
211236
### -Confirm
212237
Prompts you for confirmation before running the cmdlet.
213238

0 commit comments

Comments
 (0)