Rotation des clés CosmosDB
Qui n’a pas été confronté un jour à une ressource inaccessible suite à la régénération de la clé d’accès par Douby le stagiaire ? Douby ou michel d’ailleurs peu importe…
La bonne pratique voudrait que nous n’utilisions pas la clé en direct dans notre code (ce que je recommande fortement) mais alors comment faire ? Certains types de ressources proposent des solutions via Key Vault, par exemple la fonctionnalité du managed storage qui permet au Key Vault d’auto regénéré la clé d’un storage account et de la référencer en tant que secret : https://docs.microsoft.com/en-us/azure/key-vault/key-vault-overview-storage-keys-powershell
Vous faites donc référence directement au secret au sein du Key Vault et donc plus besoin de renseigner une clé en dur dans votre code, de plus la clé étant régénérée automatiquement vous évitez qu’une clé divulgué se retrouve utilisable sur le long terme.
Malheureusement cette fonctionnalité n’est pas disponible pour toutes les ressources proposant des clés et c’est notamment le cas de CosmosDB.
D’où ma réflexion, comment référencer au sein d’un key vault les master keys de ma CosmosDB à chaque fois que Doubby régénère celles-ci ?
Premièrement comment détecter la regénération des clés ?
Réponse simple, Activity Logs !
Ok mais ensuite comment récupérer les nouvelles clés et surtout comment les ajouter à mon Key Vault ?
J’ai évidemment pensé à PowerShell mais au sein de Functions ce n’est pas encore ça… J’ai donc opté pour Logic App, plus graphique certes mais tout aussi efficace pour cette tâche.
Voyons comment cela a été mis en place.
J’ai tout d’abord créé ma Logic App en utilisant un trigger HTTP, le schéma à utiliser est le suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
{ "properties": { "data": { "properties": { "context": { "properties": { "activityLog": { "properties": { "authorization": { "properties": { "action": { "type": "string" }, "scope": { "type": "string" } }, "type": "object" }, "caller": { "type": "string" }, "channels": { "type": "string" }, "claims": { "type": "string" }, "correlationId": { "type": "string" }, "description": { "type": "string" }, "eventDataId": { "type": "string" }, "eventSource": { "type": "string" }, "eventTimestamp": { "type": "string" }, "level": { "type": "string" }, "operationId": { "type": "string" }, "operationName": { "type": "string" }, "resourceGroupName": { "type": "string" }, "resourceId": { "type": "string" }, "resourceProviderName": { "type": "string" }, "resourceType": { "type": "string" }, "status": { "type": "string" }, "subStatus": { "type": "string" }, "submissionTimestamp": { "type": "string" }, "subscriptionId": { "type": "string" } }, "type": "object" } }, "type": "object" }, "properties": { "properties": {}, "type": "object" }, "status": { "type": "string" } }, "type": "object" }, "schemaId": { "type": "string" } }, "type": "object" } |
On va ensuite récupérer le nom de la CosmosDB qui a déclenchée notre Logic App au sein d’une variable, pour cela on va spliter le resourceId :
1 |
split(triggerBody()?['data']?['context']?['activityLog']?['resourceId'],'/')[8] |
On va ensuite définir le nom du Key Vault à utiliser et plutôt que de le renseigner en dur nous allons utiliser une variable :
Nous avons alors les éléments nécessaire pour aller récupérer les clés via API mais il nous manque cependant un élément à savoir l’authentification !
Plutôt que d’utiliser un SPN nous allons utiliser MSI (Managed Service Identity)
L’activation se fait simplement comme ceci au sein de notre Logic App:
Notre Logic App possède désormais une identité que nous allons pouvoir utiliser pour lui assigner des droits, chose que nous allons faire afin de lui permettre de récupérer les clés de notre CosmosDB par API, pour se faire nous allons lui attribuer le rôle DocumentDB Account Contributor
On va ensuite créer une access policy afin de l’authoriser à créer / updater les secrets au sein de notre Key Vault:
Désormais notre Logic App sera capable à la fois de récupérer les clés puis de créer des secrets au sein de notre Key Vault.
L’étape de récupération des clés de notre CosmosDB se fera en utilisant les API de cette manière :
Nous allons ensuite parser le résultat afin de réutiliser les clés pour pouvoir créer nos secrets. :