Key Vaultにシークレットをしまうところまではできた。でも、そこから先で多くの人が引っかかります。「じゃあ、アプリはどうやってKey Vaultからその値を取り出すの?」という問題です。ここで安易にKey Vaultへのアクセス用パスワードやシークレットをコードや設定ファイルに書いてしまうと、「秘密を守るためのKey Vaultに入るための秘密」という新しい漏れどころを自分で作ってしまいます。本末転倒ですよね。
この矛盾をきれいに解いてくれるのが、この記事の主役であるマネージドIDです。私自身、Azureの案件でいちばん「これは気持ちいい」と感じたのがこの仕組みで、接続文字列やパスワードを一切コードに書かずに、アプリがKey Vaultからシークレットを取ってくる——いわゆるキーレス連携を実現できます。本番でシークレットを漏らさないための、いちばんの基本です。

「Key Vaultにパスワードをしまったのはいいけど、そのKey Vaultに入るためのパスワードはどこに書けばいいの…?結局どこかに秘密が残るじゃん」
この記事では、マネージドIDにKey Vaultへのアクセスを許可するところから、VMやApp Serviceからパスワードなしでシークレットを取得する方法、そしてApp ServiceのKey Vault参照(@Microsoft.KeyVault(...))でアプリ設定に埋め込むいちばん手軽なやり方まで、公式Learnの正確さは押さえつつ、初心者がつまずく所を噛み砕いて解説します。読み終わるころには、「アプリに秘密を持たせない」設計が自分の手で組めるようになります。
なお、そもそもKey Vaultが何をするサービスなのか全体像があやふやな方は、先に Azure Key Vaultとは?シークレット・キー・証明書を安全に管理する仕組み に目を通しておくと、この記事の位置づけがはっきりします。本記事はその親記事の中の「アプリからどう安全に取り出すか」を深掘りする子記事です。
マネージドID=アプリに配られる「Azure内部専用の社員証」
手を動かす前に、マネージドIDのイメージだけつかんでおきましょう。ここが腑に落ちると、あとの手順が一本の線でつながります。
マネージドIDは、ひとことで言うとVMやApp Serviceといったリソースに配られる、Azure内部専用の社員証です。人間がオフィスの入館に社員証を使うのと同じで、アプリは「自分はこのVMです」「自分はこのApp Serviceです」という身元をこの社員証で証明します。そして重要なのは、この社員証の実体(パスワードや証明書)はAzureが裏側で自動生成・自動更新してくれて、私たちが目にすることも管理することもないという点です。
ここが「気持ちいい」ポイントです。ふつう、アプリが他のサービスにアクセスするにはIDとパスワード(=資格情報)が要ります。でもマネージドIDなら、その資格情報を私たちが一切持たない・書かない・見ない。パスワードが手元にないのだから、漏らしようがない。これがキーレス連携の本質です。
システム割り当てとユーザー割り当ての違い
マネージドIDには2種類あって、最初に「どっち?」と固まる所なので違いをはっきりさせておきます。
システム割り当て(System-assigned)は、社員証がそのリソース1台に強く紐づくタイプです。VMを1台作って、そこで社員証をオンにする——このイメージ。そのリソースが消えれば、社員証も一緒に消えます。人と社員証が一心同体で、退職したら社員証も破棄される、という感覚ですね。小さな構成や「このアプリ専用の身元があればいい」という場面ではこれで十分です。
対してユーザー割り当て(User-assigned)は、社員証を独立した1枚のカードとして先に作っておき、複数のリソースに貸し出すタイプです。1枚の社員証を、VMにもApp Serviceにも関数アプリにも持たせられる。リソースを作り直しても社員証は残るので、「同じ身元を複数のリソースで使い回したい」「リソースは頻繁に入れ替わるが権限設定は据え置きたい」ときに向きます。私が実務で多数のリソースを扱うときは、権限の付け直しを避けたいのでユーザー割り当てを選ぶことが多いです。
迷ったら、まずはシンプルなシステム割り当てで感覚をつかむのがおすすめです。この記事の手順もシステム割り当てを軸に進めます。
マネージドIDにKey Vaultへのアクセスを許可する
社員証(マネージドID)を配っただけでは、まだKey Vaultの中は見られません。「この社員証を持った人には、シークレットの読み取りを許可する」という権限付けが必要です。ここが連携の心臓部です。
手順はざっくり2ステップです。①リソースにマネージドIDを有効化する → ②そのIDにKey Vaultへのアクセス権を与える。まず①は、VMやApp Serviceの左メニューにある「ID(Identity)」を開き、システム割り当ての状態を「オン」にして保存するだけ。これで社員証が発行され、オブジェクトIDという識別子が表示されます。この値が「この社員証は誰か」を指す番号になります。
アクセスの許可方式は2つある(ここでよく混乱する)
②の「Key Vaultへのアクセス権を与える」で、初心者がいちばん混乱するのがここです。Key Vaultには権限モデルが2種類あり、作成時にどちらを選んだかで操作画面が変わります。
1つ目は昔からあるアクセスポリシー(Access Policy)方式。Key Vaultの「アクセスポリシー」を開き、「作成」からシークレットの権限で「取得(Get)」「一覧(List)」にチェックを入れ、プリンシパルの選択で先ほどのマネージドID(アプリ名やオブジェクトIDで検索)を指定します。Key Vault単位で「誰に何を許すか」を一覧管理するイメージです。公式のチュートリアルでもこの流れが基本形として紹介されています。
2つ目は新しめのAzure RBAC方式。こちらは「アクセス制御(IAM)」からロールの割り当てで、マネージドIDに Key Vault Secrets User(シークレットの読み取り専用ロール)を割り当てます。他のAzureサービスと同じRBACの作法でそろえられるので、組織全体で権限管理を統一したいときはこちらが主流になりつつあります。

「アクセスポリシー画面が見当たらない!」の多くは、そのKey VaultがRBAC方式で作られているのが原因です。まず自分のKey Vaultがどちらの方式かを確認するのが最短の解決策です。
どちらを使うにせよ、渡す権限は「取得(Get)」だけで十分なケースがほとんどです。アプリはシークレットを読むだけで、書き換えたり消したりする必要はありません。必要最小限の権限しか渡さない——この最小権限の考え方が、あとで漏れが起きたときの被害を最小化してくれます。
ちなみにアクセスポリシー方式の詳しい割り当て手順は公式の アクセスポリシーの割り当てガイド にまとまっています。画面キャプチャ付きなので、実際に触るときの答え合わせに使うといいでしょう。
VMやApp Serviceからパスワードなしでシークレットを取得する
社員証を配り(マネージドID有効化)、その社員証に権限を付けた(アクセス許可)。これで準備は整いました。いよいよアプリがパスワードなしでシークレットを取り出すところです。ここでキーレスの気持ちよさを体感できます。
まず、いちばん原始的な確認方法から。マネージドIDを有効にしたVMにログインして、次のコマンドを叩くと、資格情報を一切入力していないのにトークンが返ってきます。
curl "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net" -H "Metadata:true"
この 169.254.169.254 という不思議なアドレスは、Azureが各VMの内部にだけ用意している専用の受付窓口(IMDS:Instance Metadata Service)です。外からはアクセスできず、そのVMの中からしか呼べません。VMは「自分の社員証でトークンをください」と頼み、Azureが「たしかにこのVMだね」と確認してアクセストークンを返す。この一連のやり取りにパスワードは一切登場しません。社員証(マネージドID)そのものがVMという場所に紐づいているので、その場所から呼べる時点で身元が保証される、という仕組みです。
そのトークンを使ってKey VaultのREST APIを叩けばシークレットが取れる——のですが、実務でここまで手で組むことはまずありません。Azure SDKやAzure CLIが、この面倒なやり取りを全部肩代わりしてくれるからです。
CLIとSDKなら「呼ぶだけ」で済む
マネージドIDを有効にしたVM上でAzure CLIにログインするときは、こう書きます。パスワードは出てきません。
az login --identity
az keyvault secret show --vault-name my-keyvault --name db-password --query value -o tsv
az login --identity:ユーザー名もパスワードも使わず、そのVMのマネージドID(社員証)でログインする。これがキーレスの入り口。az keyvault secret show:Key Vaultから指定した名前のシークレットを取得する。--vault-nameにKey Vault名、--nameにシークレット名を渡すだけ。
アプリのコードから取る場合も同じ発想です。.NETなら DefaultAzureCredential というクラスを使うのが定番で、公式チュートリアル「仮想マシンで Key Vault を使用する」でも、この一行に資格情報の面倒を全部押し込む形で紹介されています。
var client = new SecretClient(
new Uri("https://my-keyvault.vault.azure.net/"),
new DefaultAzureCredential());
KeyVaultSecret secret = await client.GetSecretAsync("db-password");
string dbPassword = secret.Value;
ポイントは DefaultAzureCredential の賢さです。これは「今いる環境で使える認証手段を、自動で順番に探して使ってくれる」クラスです。Azure上で動いていればマネージドIDを、ローカルの開発PCで動いていれば開発者自身のログイン(az login の情報など)を、自動で拾ってくれます。つまり、開発時も本番時もコードを一切書き換えなくていい。ここに接続文字列もパスワードも登場しないのが、見どころです。
App ServiceのKey Vault参照:アプリ設定に書くだけで値が解決される
ここまでは「コードからSDKで取る」話でしたが、App Serviceにはコードを1行も足さずにキーレス連携できる、さらに手軽な仕組みがあります。それがKey Vault参照(Key Vault References)です。私がApp Serviceで一番おすすめするのがこれです。
やり方は拍子抜けするほど簡単で、App Serviceのアプリ設定(環境変数)の値に、実際のパスワードの代わりに次のような特殊な文字列を書くだけです。
@Microsoft.KeyVault(SecretUri=https://my-keyvault.vault.azure.net/secrets/db-password/)
こう書いておくと、App Serviceが起動するときに、この @Microsoft.KeyVault(...) の部分を裏側でKey Vaultに問い合わせて、本物のシークレットの値に自動で差し替えてくれます。アプリのコードから見ると、ただの環境変数に本物のパスワードが入っているようにしか見えません。アプリ側は「環境変数を読むだけ」でよく、Key Vaultの存在すら意識しなくていい——これがこの仕組みの気持ちよさです。
この値の解決にも、当然マネージドIDが使われます。前提条件を整理すると、①App ServiceでマネージドIDを有効化し、②そのIDにKey Vaultの「取得(Get)」権限を付与しておくこと。これはこの記事の前半でやったことと全く同じです。準備が済んでいれば、あとはアプリ設定に上の文字列を貼るだけで連携が完成します。
つまずきポイント
この参照でよくハマるのが「アプリ設定の画面で参照がエラー表示になる」ケースです。原因はだいたい決まっていて、マネージドIDの有効化を忘れているか、そのIDにKey Vaultの取得権限を付けていないか、SecretUriのスペルミス(Key Vault名やシークレット名の打ち間違い)のどれかです。アプリ設定一覧では参照の横に「解決済み」か「エラー」かのステータスが出るので、まずそこを見て切り分けます。
もう一つ覚えておきたいのが、値の解決タイミングは基本的にアプリの起動時だという点です。つまり、Key Vault側でシークレットを新しい値に更新しても、App Serviceを再起動(またはスワップ)するまで古い値のままになることがあります。「値を変えたのに反映されない」と焦る前に、いったん再起動して確認してください。詳しい挙動は公式の App Service で Key Vault 参照を使用する にまとまっています。
秘密鍵をローカルに残さない:取得→利用→破棄という考え方
最後に、テクニックというより運用の心構えの話をします。キーレス連携を組んでも、扱い方が雑だと結局どこかに秘密が残ってしまう。本番でシークレットを漏らさないための、地味だけど一番大事なところです。
基本の考え方は「必要なときにKey Vaultから取得し、使い終わったら手元に残さない」です。取得→利用→破棄の流れですね。具体的には、こういう運用を避けるだけで大きく変わります。
- 取ってきたシークレットを、わざわざローカルの設定ファイルやテキストに書き出して保存する(→そのファイルが漏洩経路になる)。
- デバッグのつもりでシークレットの値をログやコンソールに出力する(→ログが平文の秘密の保管庫になってしまう)。
- 取得した接続文字列をソースコードに直書きしてコミットする(→Gitの履歴に永遠に残る)。
マネージドIDとKey Vault参照が優れているのは、この運用を仕組みとして半ば強制してくれる点にあります。アプリは起動時や実行時に必要な分だけメモリ上に値を受け取り、ファイルにもGitにも痕跡を残さない。人間が「気をつける」だけに頼らず、そもそも秘密が手元に残らない構造にしてしまうのが正解です。
加えて、Key Vault側ではシークレットの定期的なローテーション(更新)とアクセスログ(監査ログ)の有効化をしておくと万全です。万一漏れても定期更新で古い値を無効化でき、「いつ・誰の社員証が・どのシークレットを取ったか」がログに残る。このあたりの実践的な指針は公式の Key Vault のベストプラクティス に体系的にまとまっているので、本番運用に入る前に一度目を通しておくことを強くおすすめします。
まとめ
この記事では、マネージドIDを使ったKey Vaultとのキーレス連携を、実務でつまずく順に見てきました。要点を振り返っておきます。
- マネージドID:リソースに配られる「Azure内部専用の社員証」。資格情報をAzureが裏で管理するので、私たちがパスワードを持たない・書かない・見ない。
- 2種類の使い分け:1リソース専用ならシステム割り当て、複数で使い回すならユーザー割り当て。
- アクセス許可:Key Vaultの権限モデル(アクセスポリシー/RBAC)を確認し、マネージドIDに「取得(Get)」だけを最小権限で付与。
- 取得:VMやApp Serviceからは
DefaultAzureCredentialやCLIで、パスワードなしで取れる。 - App Service参照:アプリ設定に
@Microsoft.KeyVault(...)と書くだけで、起動時に値が自動解決される。コード変更ゼロ。 - 運用:取得→利用→破棄。ファイル・ログ・Gitに秘密を残さない構造にする。
ここまでできれば、「アプリに秘密を持たせずにシークレットを安全に取り出す」という、本番運用のいちばんの基本が身についたことになります。あとは実際のプロジェクトで、接続文字列やAPIキーを一つずつKey Vaultに移し、コードから消していくだけです。
あわせて読みたい:

