第4回 Key VaultとマネージドID — Azure自動化でシークレットを安全に扱う

この記事の内容

  • Azure Key Vaultを使ってシークレットや証明書を安全に保管する方法を解説します
  • Key Vaultの作成手順とRBACによるアクセス制御の設定を紹介します
  • マネージドIDの仕組みと、なぜそれがKey Vaultへの認証問題を解決するのかを説明します
  • Azure VMでマネージドIDを使ってアクセストークンを取得するデモを行います
  • マネージドID → Key Vault → サービスプリンシパル認証という多段構成の実装例を示します

はじめに — なぜKey Vaultが必要なのか

前回までのシリーズでは、サービスプリンシパルのシークレットや証明書を使って認証する方法を解説しました。しかし、それらの認証情報をソースコードに直接書いてはいけません。リポジトリにシークレットやIDをそのまま公開してしまうと、アカウントが乗っ取られ深刻な被害を招く可能性があります。

証明書についても、1台のWindows PCのローカルストアにしか存在しない状態では、複数人での共有や運用に限界があります。

こうした課題を解決するのが Azure Key Vault です。シークレットや証明書を安全かつ共有可能な形で保管できる、Azure上のマネージドサービスです。Azureでこれらを扱う場合はKey Vault一択と言っても過言ではありません。


Azure Key Vaultの作成

Azure PortalでKey Vault(キーコンテナー)を新規作成します。なお、PortalのUIでは「キーコンテナー」と表示されますが、英語名では「Key Vault」です。どちらも同じものを指しています。

作成時の主な設定項目

  • リソースグループ: 任意のものを選択
  • キーコンテナー名: グローバルで一意の名前が必要です
  • 地域: Japan East など任意のリージョン
  • 価格レベル: 標準とプレミアムがあります。HSM(ハードウェアセキュリティモジュール)が必要でなければ標準で十分です
  • 論理的な削除: 削除されたKey Vaultを一定期間保持する機能です。本番環境では有効にしておくことを推奨します
  • アクセス許可モデル: 「コンテナーアクセスポリシー」と「Azureロールベースのアクセス制御(RBAC)」の2種類があります。RBACの方が新しい仕組みで、他のAzureリソースと同じ方法で権限管理できるため、今回はRBACを選択します

作成直後の注意点

Key Vaultを作成した直後は、作成者自身にも権限がありません。これはKey Vaultが非常に重要なリソースを扱うために、意図的にそのような設計になっています。まずIAMからロールを割り当てましょう。

  1. Key Vaultリソースの「アクセス制御(IAM)」を開く
  2. 「ロールの割り当ての追加」をクリック
  3. 「キーコンテナー管理者」ロールを選択
  4. 自分自身をメンバーとして選択して割り当てる

これでシークレットや証明書を操作できるようになります。


Key Vaultへのシークレット保管

サービスプリンシパルのシークレット値をKey Vaultに保存しておくことで、スクリプトがソースコードにシークレットを直接持つ必要がなくなります。

Key Vaultの「シークレット」メニューから手動で登録します。

  • 有効化する日付・有効期限: 特定の期間のみ有効なシークレットを設定できます
  • 値を登録したら、スクリプトはKey Vaultからその値を取得して使う設計にします

Key Vaultでの証明書作成

以前の回では、PowerShellで証明書を作成するとローカルマシンのストアに保存されるという話をしました。Key Vaultでは証明書を直接生成できるため、最初からKey Vault内に証明書が存在する状態を作れます。

証明書の作成手順

  1. Key Vaultの「証明書」メニューから「生成/インポート」を選択
  2. 証明書の名前を入力(例: cert-for-sp
  3. 証明機関は「自己署名証明書」を選択
  4. 件名に CN=<任意の名前> を入力(例: CN=service-principal-sp
  5. 有効期間や自動更新ポリシーを設定して作成

自動更新を設定しておけば、証明書の有効期限切れリスクを大幅に低減できます。

証明書のダウンロードと利用

  • CER形式(公開鍵のみ): サービスプリンシパルにアップロードするために使います
  • PFX形式(秘密鍵付き): ローカルにダウンロードする場合は取り扱いに細心の注意が必要です。秘密鍵が含まれるため、本番環境では安易にダウンロードしないでください

CER形式の公開鍵をダウンロードし、Entra IDのアプリ登録(サービスプリンシパル)の「証明書とシークレット」にアップロードします。


鶏が先か卵が先か — Key Vault認証の問題

ここで重要な問題が生じます。

Key Vaultに保管したシークレットや証明書をスクリプトで取得するには、まずKey Vaultへの認証が必要です。しかし、その認証にもシークレットや証明書が必要になります。それらを安全に置く場所はKey Vaultなのに、そのKey Vaultにアクセスするための認証情報はどこに置けばよいのか……という循環に陥ります。

この問題を解決するのが マネージドID(Managed Identity) です。


マネージドIDとは

マネージドIDは、技術的にはサービスプリンシパルの一種ですが、使い勝手がまったく異なります。

  • Azure上のリソースでのみ使用可能(Azure VMなど)
  • パスワード不要・シークレット不要・証明書不要でトークンを取得できる
  • Azureが認証の仕組みを裏で管理してくれる

つまり、Azureリソース上で動いているスクリプトは、特別な認証情報なしにアクセストークンを取得できるのです。


Azure VMでマネージドIDを有効にする

システム割り当てマネージドIDの有効化

  1. 対象のAzure VMを開く
  2. 「セキュリティ」→「ID」メニューを開く
  3. 「システム割り当て済み」タブで状態を「オン」に設定して保存

保存するとオブジェクトID(プリンシパルID)が発行されます。これはEntra IDのエンタープライズアプリケーションにサービスプリンシパルとして登録されている実体です。VMのマネージドIDをオンにすると、裏でサービスプリンシパルが自動的に作成されるという仕組みです。


マネージドIDでアクセストークンを取得する

Azure VM上では、次のエンドポイントにリクエストを送るだけでアクセストークンを取得できます。

Invoke-WebRequest -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" -Headers @{Metadata="true"} -UseBasicParsing

このIPアドレス 169.254.169.254 はAzureのIMDS(Instance Metadata Service)エンドポイントです。Azure VM上でのみアクセスできるアドレスで、ローカルPCから試しても応答は返ってきません。

# ローカルPCから実行すると → タイムアウトになる
Invoke-WebRequest -Uri "http://169.254.169.254/..." -TimeoutSec 5
# 接続できません

Azureリソース上でこのエンドポイントにアクセスすると、そのリソースのマネージドIDに基づいた正しいトークンがMicrosoftの仕組みによって返却されます。

マネージドIDでサインインする(PowerShell)

Connect-AzAccount -Identity

IDもパスワードも不要で、このコマンド一発で認証できます。


マネージドIDにKey Vaultへのアクセス権を付与する

VMのマネージドIDがKey Vaultにアクセスできるよう、ロールを割り当てます。

  1. Key VaultのIAM(アクセス制御)を開く
  2. 「ロールの割り当ての追加」を選択
  3. 「キーコンテナー管理者」などの適切なロールを選択
  4. 割り当て先として「マネージドID」を選択
  5. 対象のVMのマネージドIDを選択して割り当て

これでVMはKey Vaultに保管されているシークレットや証明書を取得する権限を持ちます。


実践デモ — マネージドID → Key Vault → サービスプリンシパル認証

以下の流れでAzureリソースグループを作成するデモを行います。

  1. マネージドIDで認証する
  2. Key Vaultからサービスプリンシパルのシークレットを取得する
  3. そのシークレットを使ってサービスプリンシパルとして認証する
  4. リソースグループを作成する

シークレットを使った例

# 変数定義
$applicationId = "<サービスプリンシパルのアプリケーションID>"
$tenantId = "<テナントID>"
$vaultName = "<Key Vaultの名前>"
$secretName = "<シークレット名>"

# マネージドIDで認証
Connect-AzAccount -Identity

# Key Vaultからシークレットを取得
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -AsPlainText

# サービスプリンシパルとして認証
$secureSecret = ConvertTo-SecureString $secret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($applicationId, $secureSecret)
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $tenantId

# リソースグループを作成
New-AzResourceGroup -Name "test-resource-group" -Location "japaneast"

このスクリプトにはパスワードもシークレットも直接記述されていません。ソースコードが流出しても安全です。

証明書を使った例

Key Vaultから証明書(PFX形式、秘密鍵付き)を取得し、ローカルのWindows証明書ストアにインストールして使う方法もあります。

# マネージドIDで認証
Connect-AzAccount -Identity

# Key Vaultから証明書を取得(PFX形式)
$cert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certName
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $cert.Name

# 証明書をWindows証明書ストアにインストール
$secretValue = ConvertTo-SecureString -String $secret.SecretValueText -AsPlainText -Force
$certBytes = [System.Convert]::FromBase64String($secret.SecretValueText)
# ... (証明書のインストール処理)

# 証明書を使ってサービスプリンシパルとして認証
Connect-AzAccount -ServicePrincipal -ApplicationId $applicationId -CertificateThumbprint $thumbprint -Tenant $tenantId

なお、このインストール処理は Azure Key Vault VM拡張機能 を使うことで自動化できます。この拡張機能を利用すると、Key Vaultから証明書を自動取得してWindowsの証明書ストアに展開してくれるため、スクリプトをシンプルに保てます。


Azure Arcによるオンプレミスへの拡張

マネージドIDはAzureリソース上でしか使えないというのが原則です。しかし Azure Arc を使うと、オンプレミスのWindowsやLinuxサーバーをAzureリソースとして扱えるようになります。

Azure Arcを使えば、Azureの外にあるマシンからでもマネージドIDでトークンを取得し、Azureリソースにアクセスできるようになります。オンプレミス環境でのAzure自動化を検討している場合は、Azure Arcを活用する選択肢があります。


補足 — Azureのみで完結する場合

今回のデモでは、マネージドIDでKey Vaultにアクセスし、そこからサービスプリンシパルの認証情報を取得して処理を行うという多段構成を解説しました。

ただし、AzureリソースのみでAzure操作を完結させる場合は、Key Vaultを経由せず最初からマネージドIDに直接権限を付与するだけで十分です。Key Vaultが本当に必要なのは、複数の認証フローが絡み合う構成や、Azure外のシステムと連携する場合などに限られます。


まとめ

  • シークレットや証明書をソースコードに直接書くことは絶対に避けてください。GitHubなどに誤って公開すると取り返しのつかない被害につながります
  • Azure Key Vault はシークレット・証明書を安全かつ一元管理できるAzureのマネージドサービスです。Azureで認証情報を扱う際の第一選択肢です
  • Key Vault自体への認証には マネージドID を使うことで、鶏と卵の問題を解消できます
  • マネージドIDはAzure VMなどのAzureリソース上でのみ利用でき、パスワードも証明書も不要でトークンを取得できる強力な仕組みです
  • Azure Arc を使えばオンプレミスマシンでもマネージドIDを活用できます
  • Azureリソース内だけで完結する処理なら、マネージドIDに直接権限を付与するだけでKey Vaultを介さない構成も可能です