在 C# .Net 中使用 MSI 访问 Azure Key Vault

Using MSI to access Azure Key Vault in C# .Net

由于我是 Azure 的新手,这个问题可能很愚蠢。我正在尝试构建一项服务来配置和管理 VM 集群。出于安全考虑,我不想在每个集群上放一些敏感数据。因此,我决定为每个集群提供一个 Azure Key vault 来存储这些数据,并创建一个 MSI(托管身份)并分派到集群的每个节点,以便 vm 可以访问 key vault 以获取机密。

在服务端,我需要配置虚拟机、密钥库和 MSI。将 MSI 分配给每个 VM,同时授予 MSI 访问 AKV 的权限。这是我的问题:

  1. 系统 MSI 与用户 MSI,因为集群将有多个节点,为了减少供应整个集群的延迟,用户 msi 可能是更好的主意,因为我们可以供应一个 MSI 并授予一次访问权限。对于系统分配的 MSI,我们需要为每个身份授予访问权限。但缺点是,我们在删除整个集群时必须删除 MSI。你对此有何看法?
  2. 愚蠢的问题,如何配置 MSI、Azure 密钥保管库并授予访问权限。你能给我看一些代码示例吗?我试图在网上找到 public API 文档和教程,但失败了。

1. What is the difference between a system-assigned and user-assigned managed identity?

根据我的研究,系统分配的托管身份直接在 Azure 服务实例上启用。系统分配的标识的生命周期直接绑定到启用它的 Azure 服务实例。如果实例被删除,Azure 会自动清除 Azure AD 中的凭据和身份。

但是,用户分配的托管标识是作为独立的 Azure 资源创建的。创建身份后,可以将身份分配给一个或多个 Azure 服务实例。用户分配标识的生命周期与其分配到的 Azure 服务实例的生命周期分开管理。

详情请参考document.

2. How to provision a MSI, Azure Key vault and grant the access

提供用户分配的托管标识

根据我的研究,如果我们想要提供用户分配的托管身份,我们可以使用 Azure REST API, Azure Powershell and Azure CLI

例如

Azure CLI

az login
az identity create -g <RESOURCE GROUP> -n <USER ASSIGNED IDENTITY NAME>

Azure REST API 一种。使用 Azure CLI 获取访问令牌

az login
az account get-access-token

b。呼叫其余api

curl 'https://management.azure.com/subscriptions/<SUBSCRIPTION ID>/resourceGroup
s/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>?api-version=2015-08-31-preview' -X PUT -d '{"loc
ation": "<LOCATION>"}' -H "Content-Type: application/json" -H "Authorization: Bearer <ACCESS TOKEN>"

配置 Azure 密钥保管库并授予访问权限

根据我的研究,如果我们想要实现它,我们可以提供一个用户分配的托管身份,我们可以使用 Azure REST API, Azure Powershell, Azure CLI and sdk (such as .net). For more details, please refer to the document

例如

Azure Rest API

一个。使用 Azure CLI 获取访问令牌

az login
az account get-access-token

b。呼叫其余api

PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName}?api-version=2018-02-14
Header :
   Content-Type: application/json
   Authorization: Bearer <ACCESS TOKEN>
Body

  {
  "location": "westus",
  "properties": {
    "tenantId": "<your tenant id>",
    "sku": {
      "family": "A",
      "name": "standard"
    },
    "accessPolicies": [
      {
        "tenantId": "<your tenant id>",
        "objectId": "<the object id of the MSI>",
        "permissions": {
          "keys": [
            "encrypt",
            "decrypt",
            "wrapKey",
            "unwrapKey",
            "sign",
            "verify",
            "get",
            "list",
            "create",
            "update",
            "import",
            "delete",
            "backup",
            "restore",
            "recover",
            "purge"
          ],
          "secrets": [
            "get",
            "list",
            "set",
            "delete",
            "backup",
            "restore",
            "recover",
            "purge"
          ],
          "certificates": [
            "get",
            "list",
            "delete",
            "create",
            "import",
            "update",
            "managecontacts",
            "getissuers",
            "listissuers",
            "setissuers",
            "deleteissuers",
            "manageissuers",
            "recover",
            "purge"
          ]
        }
      }
    ],
    "enabledForDeployment": true,
    "enabledForDiskEncryption": true,
    "enabledForTemplateDeployment": true
  }
}

.Net SDK

一个。 create a service principal with Azure CLI

az login
az ad sp create-for-rbac -n "MyApp" --role contributor --sdk-auth

b。代码。详情请参考sample

// please install package  Microsoft.Azure.Management.Fluent
var credentials = SdkContext.AzureCredentialsFactory
    .FromServicePrincipal(<the sp app id>,
    <the sp password>,
    tenantId, 
    AzureEnvironment.AzureGlobalCloud);
var azure = Microsoft.Azure.Management.Fluent.Azure
    .Configure()
    .Authenticate(credentials)
    .WithSubscription ("<your subscription id>");
var vault =await azure.Vaults.Define("")
                       .WithRegion(Region.AsiaSouthEast)
                       .WithExistingResourceGroup("groupname")
                       .DefineAccessPolicy()
                              .ForObjectId("the object id of msi")
                              .AllowCertificateAllPermissions()
                              .AllowKeyAllPermissions()
                              .AllowSecretAllPermissions()
                              .Attach()
                       .WithDeploymentEnabled()
                       .WithDiskEncryptionEnabled()
                       .WithTemplateDeploymentEnabled()
                       .WithSku(Microsoft.Azure.Management.KeyVault.Fluent.Models.SkuName.Standard)
                       .CreateAsync()