はじめに
どうも、masamoriです。しば犬って可愛いですよね。小紅書でしば犬ばっかり見てたら、タイムラインとレコメンドがしば犬ばっかりになって幸せです。
さて、今回はAzureの認証について調べたことについて書きます。
Azure Function を使ってKey Vaultにアクセスしようとする時、MSの推奨としてはマネージドIDを使うことになっています。
というより、Azureのリソース間で認証を行うときはマネージドIDが便利でセキュアです。なぜなら、コードにシークレットを埋め込む必要がなくなるからです。(.envとか使っていても、埋め込んでることにはなる。)
ちなみに、マネージドIDって何?って方は、こちらの記事を見ると分かりやすいです。
tech-lab.sios.jp
マネージドIDを使用して、Entra IDから資格情報を得るときに使うメソッドが.
DefaultAzureCredential()
.
です。
Functionをローカルで開発していて上手くいっていたのに、デプロイしてFiunctionを動かしてみるとKey Vaultの認証で弾かれてしまうことがありました。
というわけで、この原因を調べるべくDefaultAzureCredential()
について少し深掘りをしてみました。
そもそも
DefaultAzureCredential()
の定義はこちらです。
これが有効になっている場合、ドキュメントに書かれているCredentialの上から順番に試されていくんですね。なので、環境によっては違うCredentialが読み込まれることも十分にあり得るわけです。
そして、次にこちらの記事
これはApp ServiceからDBに接続するチュートリアルになりますが、注目する部分はここ
DefaultAzureCredential は、開発環境と Azure 環境の両方に適応できるだけの柔軟性を備えています。 ローカルで実行しているとき、任意の環境 (Visual Studio、Visual Studio Code、Azure CLI、Azure PowerShell) からログインしている Azure ユーザーを取得できます。 Azure で実行しているとき、マネージド ID が取得されます。 そのため、開発時と運用時の両方でデータベースへの接続が可能です。
コード実行の裏側で、こういうことが行われているんですね。
これ別の解釈すると、「環境によって取得するCredentialは違うから、気をつけて開発してね」っていうことなんだと思います。
ローカルとデプロイ環境だと当然環境も違うので、取得するCredentialが異なる。その結果、ローカルで動かした時に認証が上手くいっていても、デプロイ環境の設定(マネージドIDの設定やマネージドIDへの権限付与)が上手くいっていない場合、デプロイするとアプリケーションが動かない場合があるということです。
僕のケースでは、ローカル環境でaz account show
と打つと、自分のアカウントが出てきたので、AzureCLIにサインインしている状態です。
なので、認証としては"DefaultAzureCliCredential"が使われている可能性が高いです。そして、デプロイした場合"DefaultManagedIdentityCredential"が認証として読み込まれる優先順位が高いので、ManagedIDが設定されていなかったので、Functionの実行に失敗したという感じでしょうか。
あれ?そうなると、デプロイした環境だと"DefaultAzureCliCredential"は読み込まれないんでしょうか?挙動を見るとそうなりますよね。つまり、デプロイした環境(Azure環境)ではAzureCLI環境は読み込まれず、環境変数やマネージドIDを使って認証をすることになります。この辺、やや複雑ですね。間違っていたらご指摘ください。
というわけで
Functionを使ってAzureの各リソースにアクセスしたい場合、まずはFunctionのマネージドIDをオンにして、各リソースにそのマネージドIDに対して適切な権限を割り振りましょう。ユーザーに割り振ってしまうと、アプリケーションの想定する挙動とは異なると思います。
冒頭のKey Vaultにアクセスできない問題は、Key Vaultに対してユーザーにはシークレットの読み取り権限が設定されていたにも関わらず、FunctionのマネージドIDには割り振られていなかったんですね。
なので、全く同じコードでも動かなかったと。
というわけで、マネージドIDに権限を割り振ったら解消しました。
終わりに
認証周りは結構複雑になりがちです。ドキュメント通りに実装して他のAzureリソースにアクセスできない場合、認証を見直してみましょう。
個人的には認証周りはややこしいなーと思っています。 マネージドIDとかサービスプリンシパルとか、そもそもEntra IDってなんなの?みたいな。
マネージドID、サービスプリンシパルについてもいずれ記事にしてみたいと思います。
いつになるか分かりませんが。