サービスプリンシパルを知ろう！

# はじめに

Azureを触っていると様々なシーンでサービスプリンシパルを作る、もしくは（勝手に）作られることがあります。例えば、Automationアカウントを作成した時に、自動的にサブスクリプションスコープで「共同作成者」というRBAC権限を持つサービスプリンシパルが付与されたりします。（これって知っていないとそれなりにリスクとなり得る仕様なのです。）
そもそもプリンシパルって何でしょう？？Google先生に翻訳してもらうと「主要」とか「校長」という意味があるそうですが、もう少し真面目に調べると、Microsoftの.Netのサイトに以下の説明があります。

> プリンシパル オブジェクトは、コードが実行されているセキュリティ コンテキストを表します。 ロールベースのセキュリティを実装するアプリケーションは、プリンシパル オブジェクトに関連付けられたロールに基づいて権限を付与します。

__プリンシパル オブジェクトと ID オブジェクト__
https://docs.microsoft.com/ja-jp/dotnet/standard/security/principal-and-identity-objects

Azureにおいても「プリンシパル＝セキュリティコンテキスト」と捉えるのがしっくりきます。
ということで、今回はサービスプリンシパルの概要について書かせていただきます。

# サービスプリンシパルって？

サービスプリンシパルって何？というのは、Azure初心者であれば必ず遭遇する疑問です。
Azureには大きく分類すると「ユーザプリンシパル」と「サービスプリンシパル」という二つのプリンシパルがあります。この二つの違いをざっくりいうと、

* __ユーザプリンシパル__
   * 人間が使うアカウントIDとパスワードのセット
   * 条件付きアクセス（MFAやアクセス元制限）が使える
   * ユーザプリンシパルに付与されたRBACに沿ってリソース操作ができる
   
* __サービスプリンシパル__
   * アプリケーションが使うIDとシークレットのセット
   * MFAが使えない
   * サービスプリンシパルに付与されたRBACに沿ってリソース操作ができる

といった感じです。

# サービスプリンシパルの使い方

サービスプリンシパルの利用イメージとして、例えば、バッチ実行サーバ（VM）を構築して、夜間バッチ中にAzure上のリソースに何等か操作（対象VMの日次再起動など）したい時にサービスプリンシパルを使います。（厳密には「マネージドID」というものが間に挟まりますが、ここでは割愛します。）バッチ処理の中にユーザプリンシパルを埋め込むこともできますが、パスワードの有効期限を意識する必要があったり(まぁパスワード無期限もできますが)、ユーザプリンシパルは何かと人間が使うことを前提に機能が作り込まれているため、こういうシーンで使うことはオススメできません。
その他にも、3rdParty製のSaaSサービスが、サービスプリンシパルを利用して、ユーザのAzure環境内の情報を取得したり、設定変更するといったシーンでも使われます。

もう少し細かい動きをAutomationを例にとってみると、AutomationにPowerShellスクリプトで、とあるVMを起動する処理を書いたとします。なぜこのAutomationを実行するとVMが起動するかというと、冒頭でもお話した通り、Automationにはデフォルトでその環境（サブスクリプション）配下のリソースに対して「共同作成者」というRBACが割当たったサービスプリンシパルを作成し、それを使うように設定されているからです。
Azureリソースに対する操作はすべてRBACという権限制御が掛けられているため、Automation自体がリソースを操作できる訳ではありません。Automationが、リソースを操作できるRBAC権限をもつサービスプリンパルを使うことで機能として成り立っている、ということになります。

![スクリーンショット 2021-09-11 19.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/7d2b81a6-adfb-abaa-0938-4aa4145a8ea3.png)


# サービスプリンシパルの作り方

サービスプリンシパルの作り方は様々な方法があります。Azureポータルで作成することもできますし、PowerShellやCLIで作成することもできます。

__方法:リソースにアクセスできる Azure AD アプリケーションとサービス プリンシパルをポータルで作成する__
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-create-service-principal-portal

__Azure CLI で Azure サービス プリンシパルを作成する__
https://docs.microsoft.com/ja-jp/cli/azure/create-an-azure-service-principal-azure-cli

ひとつポイントは、"サービスプリンシパルを作る"＝"AzureADアプリケーションを作る"ということです。サービスプリンシパルを作成すると、同名のAzureADアプリケーションが作成されます。Azureポータルの管理ブレードから[Azure Active Directory]→[アプリの登録]→[すべてのアプリケーション]に進むと、AzureADアプリケーションを確認することができます。

![スクリーンショット 2021-09-12 19.32.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/e85b4e6f-c298-bca6-5db1-ea5f2ae5c332.png)

また、サービスプリンシパルを使うときには、一般的には下記の３つのパラメータを使います。

* __AzureADテナントID__
* __アプリケーションID__
* __シークレットキー__

感覚的にはAzureADアプリケーションを呼び出すような使い方をしていますが、AzureADアプリケーションは、サービスプリンシパルを使うためのインターフェイスのようなものです。（と私は理解しています。）AzureADアプリケーションを呼び出すことで実態はサービスプリンシパルを使うことになり、さらにそのサービスプリンシパルに付与されているRBACに沿った操作ができるようになる訳です。この理解ができるとサービスプリンシパルに対する理解がより深まると思います。

# サービスプリンシパル運用時の注意点

サービスプリンシパルを使う上で必ず気をつけないといけないことがあります。それは、シークレットの有効期限です。サービスプリンシパルを使うときに使うシークレットには有効期限があり、多くの場合１年or２年になっています。ちなみにAutomationを作った時にできるAzureADアプリケーションには証明書が付与されていますが、この有効期限は１年となります。

![スクリーンショット 2021-09-11 19.04.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/8031baf8-d901-fec6-a09a-a29d18a2afa0.png)

知らずに有効期限が切れていて、サービスプリンシパルが使えなくなり、結果、そのサービスプリンシパルを使うアプリケーションが実行時にエラーとなることは十分に考えられます。検証環境や開発環境であればそこまで問題になりませんが、本番環境であれば本番障害となってしまう恐れもあるため、極めて注意すべき事項です。クライアントシークレットについては、以前は有効期限を無期限（99年）とし、運用上は意識しなくて済むようにするということもできましたが、2021年から最大有効期限が2年までとしか設定できないという仕様変更（※）がありました。本番ワークフローの中でサービスプリンシパルを使っている場合は、運用カレンダーを作って定期チェックするなどして、必ず更新忘れがないように気をつけてください。

※この仕様変更については、「Japan Azure Identity Support Blog」の下記ブログ記事に詳細が記載されていますのでご参考ください。
https://jpazureid.github.io/blog/azure-active-directory/azuread-clientsecrets-202104/

# おわりに
今回はAzureを利用する上では避けて通れない「サービスプリンシパル」について書かせていただきました。「サービスプリンシパルってよくわからない」という人に対して少しでも参考になれば幸いです。サービスプリンシパルに関するノウハウは他にもたくさんありますので、また機会があれば紹介させていただきます。

それでは！