Stocker des clés SAS de Storage Account dans un KeyVault

Voilà un peu plus d’un an, j’avais publié ce billet : Valet Key avec Azure Function App. Depuis ce temps, je l’utilise énormément. Ce n’est que très récemment en passant un peu de temps dans le KeyVault que j’ai découvert la commande PowerShell Set-AzureKeyVaultManagedStorageSasDefinition. Ça a un peu changé mon approche initiale. Avant, mon Azure Function retournait un clés SAS prête à consommer. Maintenant, j’utilise le Key-Valet pour stocker les clés SAS mises à disposition. Le KeyVault peut stocker ce type de secret (pas visible dans le portail à ce jour). On peut donc ainsi mettre à disposition des clés SAS pré-générées à des d’applications (limitées dans le temps évidement). Pour ce billet, on va se contenter de mettre en œuvre la fonctionnalité :

  • Etape n°1 : Initialisation de notre environnement
  • Etape n°2 : Génération du token SAS
  • Etape n°3 : Expérience côté consommateur

 

Etape n°1 : Initialisation de notre environnement

Pour initialiser notre environnement, nous allons commencer par définir quelques variables. La variable $KeyVaultConsumer désigne un utilisateur référencé dans notre Azure AD pour lequel nous allons mettre en place des permissions RBAC (pour accéder au KeyVault) ainsi que des Access-Policies pour accéder au secret mis à disposition.

$KeyVaultConsumer = « keyvaultconsumer@xxxxxxxxxx.xxx »

$random = Get-Random -Minimum 0 -Maximum 999

$AzureRegion = « WestEurope »

$vaultname = « keyvaultlab$random »

$ResourceGroupname = « KeyVaultLab$random »

$storageaccountname = « keyvaultlab$random »

$sastokenname = « sas$random »

$saspermission = « racwdlup »

$Sastokendurationinminutes = 15

$StorageSKUName = ‘Standard_LRS’

$StorageKind = ‘StorageV2’

$UserPrincipal = (Get-AzureRmContext).Account.id

clip_image002

 

Avec ces variables, nous allons pouvoir initialiser notre environnement comprenant un groupe de ressources contenant à la fois un Storage Account et une instance de Key Vault. Jusque-là rien de très nouveau.

New-AzureRmResourceGroup -name $ResourceGroupname -Location $AzureRegion

$StorageAccount = New-AzureRmStorageAccount -ResourceGroupName $ResourceGroupname -Name $storageaccountname `

-Location $AzureRegion `

-Kind $StorageKind `

-SkuName $StorageSKUName

$Keyvault = New-AzureRmKeyVault -ResourceGroupName $ResourceGroupname -Name $vaultname -Location $AzureRegion -Sku Standard

clip_image004

A ce jour, le portail Azure ne permet pas encore de gérer les permissions sur le Storage. On va donc commencer par se positionner des permissions pour ce type de secret puis référencer notre Storage Account comme « ManagedStorageAccount » auprès de notre instance KeyVault avec la commande Add-AzureKeyVaultManagedStorageAccount

Set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $ResourceGroupname -VaultName $vaultname `

-PermissionsToStorage get,list,delete,set,update,regeneratekey,getsas,listsas,deletesas,setsas,recover,backup,restore,purge `

-UserPrincipalName $UserPrincipal

$keyVault = Get-AzureRmKeyVault -VaultName $vaultname -ResourceGroupName $ResourceGroupname

$Keyvault.AccessPoliciesText

Add-AzureKeyVaultManagedStorageAccount -VaultName $vaultname -AccountName $storageaccountname `

-AccountResourceId $storageaccount.id `

-ActiveKeyName key1 `

-DisableAutoRegenerateKey

$StorageContext = New-AzureStorageContext -StorageAccountName $storageaccountname -Protocol https -StorageAccountKey Key1

clip_image006

Pour ceux qui ont suivi mon billet « Sécuriser ses Storage Accounts dans Azure« , c’est pour l’instant très proche. On peut donc même cumuler les deux fonctionnalités.

 

Etape n°2 : Génération du token SAS

De là, nous pouvons générer notre clé SAS. Par rapport à une approche Valet-Key, le secret n’est pas retourné au demandeur mais directement stocké dans le KeyVault. Attention, ce n’est pas un secret mais un objet de type « ms-sastoken-storage »

$start = [System.DateTime]::Now.AddMinutes(-1)

$end = [System.DateTime]::Now.AddMinutes($Sastokendurationinminutes)

$AccessToken = New-AzureStorageAccountSasToken -Service blob,file,Table,Queue `

-ResourceType Service,Container,Object `

-Permission $saspermission `

-Protocol HttpsOnly `

-StartTime $start `

-ExpiryTime $end `

-Context $StorageContext

$AccessToken

Set-AzureKeyVaultManagedStorageSasDefinition -AccountName $storageaccountname `

-VaultName $vaultname `

-Name $sastokenname `

-TemplateUri $AccessToken `

-SasType ‘account’ `

-ValidityPeriod ([System.Timespan]::FromDays(30))

$secret = Get-AzureKeyVaultSecret -VaultName $vaultname -Name « $vaultname-$sastokenname »

$secret.SecretValueText

$secret.Attributes.ContentType

clip_image008

Pour qu’un consommateur puisse accéder à ce nouveau type de secret (ms-sastoken-storage), il convient de s’assurer qu’il puisse voir l’objet KeyVault dans notre groupe de ressource puis de lui assigner une Access Policy avec uniquement les permissions nécessaires.

New-AzureRmRoleAssignment -SignInName $KeyVaultConsumer -ResourceGroupName $ResourceGroupname -RoleDefinitionName Reader

set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $ResourceGroupname -VaultName $vaultname `

-PermissionsToSecrets Get, List `

-UserPrincipalName $KeyVaultConsumer

Set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $ResourceGroupname -VaultName $vaultname `

-PermissionsToStorage get, list, getsas, listsas -UserPrincipalName $KeyVaultConsumer

$keyVault = Get-AzureRmKeyVault -VaultName $vaultname -ResourceGroupName $ResourceGroupname

$Keyvault.AccessPoliciesText

clip_image010

Etape n°3 : Expérience côté consommateur

Stocker un nouveau type de secret, c’est bien. Maintenant, il faut pouvoir le consommer. Pour la suite de ce billet, je pars du principe que nous sommes connectés avec son identité ($KeyVaultConsumer).

$keyvault = Get-AzurermKeyVault | Out-GridView -Title « Select KeyVault containing SAS Key. » -PassThru

Get-AzureKeyVaultSecret -VaultName $Keyvault.VaultName | Select-Object Name

$secret = Get-AzureKeyVaultSecret -VaultName $Keyvault.VaultName -Name (Get-AzureKeyVaultSecret -VaultName $Keyvault.VaultName).Name

$secret.ContentType

$secret.SecretValueText

clip_image012

 

Maintenant, on peut imaginer des process qui vont automatiquement renouveler des clés pour des consommateurs. Si en plus on combine avec la rotation automatique des clés de Storage Account vu dans mon précédent article, il n’y a plus de raison d’utiliser les clés Full.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Benoit

Simple, yes, Secure Maybe, by design for sure, Business compliant always!

Les derniers articles par Benoit (tout voir)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.