C#: Azure KeyVaultシークレットの操作サンプル(一覧取得・作成・更新・削除・ 履歴取得)

C#でAzure KeyVaultのシークレットを操作するサンプルを紹介します。

概要

前提知識

シークレットの作成

  • シークレットの作成時、シークレット値以外にタグ等の情報を付加できます。

シークレットの削除仕様

  • [論理削除]が[有効](変更不可)になっており、削除されたシークレットは削除領域に退避されます。
  • [削除されたコンテナーを保持する日数]は既定で90日、[消去保護を無効にする]が有効になっています。削除領域にあるシークレットは復元することが可能ですが、90日経過後に消去(パージ)されます。
  • シークレットを削除しても削除領域に残っており消去されていない場合、同名のシークレットを新規作成することはできません。
  • キーコンテナ毎に「消去保護」の有効・無効を選択できます。
  • キーコンテナの消去保護が無効な場合(既定)
    • 既定の権限ではシークレットを消去できませんが、アクセスポリシーの[シークレットのアクセス許可]の[特権シークレット操作]の削除を有効にすることで消去できます。
  • キーコンテナの消去保護が有効な場合
    • シークレットの消去はできません。([特権シークレット操作]の削除が有効でも。)
    • 消去保護を一度有効にすると無効に戻せません。(無効にしたい場合、別途キーコンテナを作成し直す必要がある。)

シークレットの変更履歴

  • 個々のシークレットは変更履歴を持っており、シークレットの値が変更される度に、変更履歴が追加されます。各バージョンでのシークレット値を確認することも可能です。
  • シークレットのコンテンツタイプやタグ等のプロパティの更新では、変更履歴は追加されません。
  • シークレットの変更履歴は、Azureポータル上の[以前のバージョン]で確認できます。
    ここで表示されているバージョンは「変更した順番」ではないことに注意が必要です。(更新順番に関わらず、1,2,…,9,a,b,c,…の順に並んでいる。)
  • 変更履歴上の特定のバージョンを削除、などの変更履歴の編集はできません。
    azure Key Vault:how do delete latest version of secret using Azure CLI · Issue #8114 · Azure/azure-cli

キーコンテナのURI

  • サンプルプログラム等で定義する必要があるキーコンテナのURIは、キーコンテナの[概要]で確認できます。

サンプルコード

実装方法の概要

  • C#でAzure KeyVauultを操作する場合はAzure Key Vault secret client library for .NET(Azure.Security.KeyVault.Secretsパッケージ)を使用する必要があります。
  • このパッケージで提供されるSecretClientクラスを使用して、一覧取得/新規作成/更新/削除等のシークレットに対する操作を行います。
    個々のシークレットはKeyVaultSecretクラスで表現され、シークレット作成・更新時や特定シークレット取得時にこのクラスオブジェクトが返却されます。
  • KeyValut接続時の認証は、Azure.Identityパッケージが提供するDefaultAzureCredentialクラスを使用します。環境変数、マネージドID、Visual Studio資格情報等のように実行環境に応じた資格情報を使って自動的に認証が行われます。後述のサンプルでは、Visual Studioに登録した資格情報を使う前提のため、サンプルコードに資格情報は定義していません。
  • 個々のシークレットは変更履歴を保持しており、SecretClientを介して変更履歴の一覧を取得することもできます。SecretClientで取得した変更履歴は変更順にソートされておらず、変更順を意識した処理を行いたい場合は作成日時(CreatedOn)でソートする必要があります。KeyVaultのREST APIの問題なのかKeyVaultの内部実装の問題なのか分かりませんが、CreatedOnの精度は秒単位になっており、単位時間内で複数変更が発生した場合は正しい変更順を特定できません。
  • SecretClientの削除系メソッドは、論理削除の場合はDelete、消去(物理削除)はPurgeという単語が使用されています。
  • Azure Core共有ライブラリに起因するtips
    • Azure Key Vault secret client library for .NET(Azure.Security.KeyVault.Secretsパッケージ)は、Azure Core shared client library for .NET(Azure.Coreパッケージ)を使用しています。そのため、必要に応じてAzure.Coreの実装方法を理解する必要があります。
    • SecretClientのシークレット設定・取得(SetSecret, GetSecret)等の一部メソッドの戻り値はAzure.Response<T>になっています。Azure.Response<T>は返却値の自動型変換(implicit operator)が実装されており、varではなく明示的にKeyVaultSecret型を指定した変数に代入することで、型自動変換をトリガーしています。
    • SecretClientのシークレット一覧取得(GetPropertiesOfSecrets)等の一覧系メソッドは、返却値としてPeageable<T>, AsyncPageable<T>を返却します。一覧をループ処理したい場合、非同期メソッドの場合、await foreachを使用しますが、ここでは非同期Linq(System.Linq.Asyncパッケージ)を使用しています。詳細はこちらをご覧ください。
    • KeyVault接続のリトライ設定等は、SecretClientコンストラクタの引数(SecretClientOptions)で指定可能です。この機能もAzure Coreライブラリ(ClientOptions)に依存しています。詳細はこちらをご覧ください。

サンプルコード

次の操作を行うサンプルです。
完全なソースコードはこちらをご覧ください。

  • シークレット一覧取得
  • シークレット新規作成
  • シークレット更新、プロパティ更新(コンテンツタイプ、タグ)
  • シークレット更新履歴一覧取得
  • シークレット論理削除(delete)
  • シークレット物理削除(purge)

実行結果の例は次の通りです。
(キーコンテナの消去保護が無効かつ、特権シークレット操作の削除権限がある前提)

参考

シークレット消去時の権限不足

削除されたシークレットを消去(物理削除)する際に権限不足で次のエラーが発生する場合があります。
こちらで紹介しているように、実行ユーザに対して[特権シークレット操作]の削除を有効にする必要があります。

消去保護されたシークレットの消去

消去保護が有効化されたキーコンテナのシークレットを消去(物理削除)すると次のエラーになります。
こちらで説明しているように、消去保護は一度有効化すると無効化できないので、このエラーを回避できません。設計を考え直すか、消去保護が無効なキーコンテナを新規作成して使う必要があります。