.NET で秘密文字を安全に運用する（Azure Key Vault 編）

[.NET Core で秘密文字を安全に運用する（開発環境編）](https://qiita.com/tnishiki/items/0c3e73ed28a66591d676) の続きです。

開発環境では、UserSecret を用いた秘密文字列の管理方法と、.NET Core でのコード例について紹介しました。今回は、Azure KeyVault を用いた秘密文字列の運用について紹介します。KeyVault だと、Azure のセキュリティ機能を利用した安全な運用ができます。

# 概要

　Azure KeyVault で秘密文字を管理するには、まず、キーコンテナを作成し、そこに秘密文字の登録を行います。
その後、.NET コンソールプログラムから秘密文字を取得するサンプルコードを紹介します。

Azure Keyvault は、.NET に限らず、Java や Python などからも利用できます。各実装方法については、Microsoft Docs の KeyVault のドキュメントを参照ください。

[Azure KeyVault のドキュメント | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/key-vault/general/)

# キーコンテナを作成する

まずはキーコンテナを作成します。PowerShell の New-AzKeyVault コマンドを使います。このサンプルでのコンテナ名は vaultsample、作成先のリソースグループは MyResource、リージョンは東日本という設定です。
なお、KeyVault のコンテナ名は、DNS でも使用するため Azure 全体でユニークです。誰かが登録した名前は使用できません。
サンプルの「vaultsample」もすでに使用されていますので、他の名前をつけてご使用ください。

```powershell:Powershell
# Azure にログインしてキーコンテナを作成する
# コンテナ名: vaultsample
# リソース名: MyResource
# リージョン: japaneast
% Connect-AzAccount
% New-AzKeyVault -Name vaultsample -ResourceGroupName MyResource -Location japaneast
```

作成したキーコンテナに秘密の文字列を追加します。シークレット名をつけて、複数の秘密の文字列を管理できます。サンプルでは「SecretName」というシークレット名を使用します。

```powershell:Powershell
# 秘密文字を登録する。秘密文字は「secret_keyword!」です。
% $secword = ConvertTo-SecureString -String 'secret_keyword!' -AsPlainText -Force
% Set-AzKeyVaultSecret -VaultName vaultsample -Name SecretName -SecretValue $secword
```
なお、秘密文字の文字列は何度でも登録できます。またそれらをバージョンとして管理する機能があります。
Azure Portal の KeyVault のメニューからシークレット名を指定して確認してみます。

<img width="830" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/35d431f0-3c0b-0a24-b666-b2ec23d65ed3.png">

さらに、各バージョンで有効期間の設定などの管理ができます。

<img width="410" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/d55c034a-55da-fcb1-21f4-4885efe6933f.png">

このバージョン管理機能だけで、定期的に秘密の文字列を更新していく、といったことができます。

# アクセスポリシーの設定

秘密の文字列にアクセスできる人やプログラムの設定を行います。

今回は、Azure AD ユーザのアクセス許可設定を行います。Get-AzADUser コマンドでメールアドレスを指定すると、Azure 内での Id を取得できます。この Id を使って登録します。

```powershell:Powershell
% Set-AzKeyVaultAccessPolicy -VaultName vaultsample `
                             -EmailAddress  tnishiki@sample.mail.address.jp `
                             -PermissionsToSecrets {get} 
```

詳細については、Microsoft の公式ドキュメントが参考になります。

[Azure PowerShell を使用して Key Vault アクセス ポリシーを割り当てる](https://docs.microsoft.com/ja-jp/azure/key-vault/general/assign-access-policy-powershell)

# .NET コンソールプログラムから秘密の文字列を読む

プログラムから Azure Keyvault 内の秘密の文字列を読む方法は複数ありますが、ここではAzure Identity ライブラリを使用する方法を紹介します。

詳細は、次の Microsoft Docs をご参照ください。
[クイックスタート - .NET 用 Azure Key Vault クライアント ライブラリ (v4) | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/key-vault/secrets/quick-create-net)

Visual Studio から .NET コンソールのプロジェクトを作成します。プロジェクト作成後、パッケージマネージャーコンソールから Keyvault のパッケージをインストールします。

```powershell:Visual&#x20;Studio
PM> install-package Microsoft.Azure.Keyvault
PM> install-package Microsoft.Azure.Services.Appauthentication
```

```powershell:visual&#x20;Studioの場合
PM> install-package Azure.Security.Keyvault.Secrets
PM> install-package Azure.Identity
```

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/678207f1-1000-9ca4-ee69-548a3a08288f.png">


c# のサンプルコードは次の通りです。

```c#:c#
using System;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string keyVaultUrl = "https://vaultsample.vault.azure.net/";//コンテナのURL
            string secretName = "SecretName";//シークレット名

            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            KeyVaultSecret bankSecret = client.GetSecret(secretName);
            
            Console.WriteLine($"シークレット名: {bankSecret.Name}");
            Console.WriteLine($"秘密の文字列: {bankSecret.Value}");
            Console.WriteLine($"バージョン: {bankSecret.Id}");
        }
    }
}
```

このような出力になれば成功です。

```
シークレット名: SecretName
秘密の文字列: secret_keyword!
バージョン: https://vaultsample.vault.azure.net/secrets/SecretName/205ce3556e8942768d3d81df43f44fb7
```

# 最後に

 開発者の方だと、この KeyVault の使い方として真っ先に思い浮かぶのは、データベースへの connectionSgtring かと思います。利用者やバージョン管理ソフトから隠す方法として非常にスマートです。

しかし、ユーザのアクセストークンなど、他にも漏洩したくないものはたくさんあります。そういった際に、KeyVault は非常に強力なサービスです。うまく利用して安全なシステムを構築してください。