Azure カスタムロールの作成:「NotActions」を「Action」にする

Azure でのカスタムロール作成は複雑なプロセスになる場合があり、作成されるロール定義も長くて扱いづらく、管理しにくいものになることがあります。 しかし、この問題は避けることができます。 本ブログでは、Azure の「NotActions」属性と「NotDataActions」属性を使用してこのプロセスを簡素化し、コンパクトで管理しやすく、あえて言うならエレガントですらあるカスタム Azure ロールを作成する方法を紹介します。
Azure のロールベースのアクセス制御 (RBAC) メカニズムを使い慣れた方であれば、おそらく Azure のユーザー、グループ、サービスプリンシパルに許可されるアクションを定義するロールを使用したことがあるのではないでしょうか。 Azure は、組み込みロールという事前構築済みの一連のロールを提供していますが、カスタムロールを構築することもできます。 しかし、カスタムロール定義が長くなってしまい、維持が面倒で不便になってしまうことがあります。
このブログでは、Tenable Cloud Security が、Azure プロパティの NotActions と NotDataActions の使用を合理化することで、カスタムロールを使用して権限を割り当てるプロセスをどのように簡素化するかを説明します。 また、カスタムロールを読みやすく、管理しやすくすることが、セキュリティと運用の両面で有益である理由も概説します。
Azure のロールの概要
ロール割り当てに関する 3 つの要素とは、セキュリティプリンシパル、ロール定義、スコープです (Azure ロールの基本を再確認したい方は、Tenable のブログ記事「Deconstructing Azure Access Management using RBAC (RBAC を使用した Azure アクセス管理の分解)」をご覧ください)。
本ブログに関して重要なポイントは、Azure ロールが JavaScript Object Notation (JSON) ドキュメントであり、ロール割り当ての一環として、アイデンティティに付与される権限の一覧を詳細に記述するものだということです。 ロールを割り当てることで、所定のリソースまたは一連の Azure リソースに対する権限が、続いてアイデンティティに割り当てられます。
「NotActions」とは何か
ロールの「Actions」フィールドには、リソースの作成、管理、削除などといったコントロールプレーンアクションの一覧が示されます。これらのアクションは、ロール割り当ての一環として、ユーザーやグループなどのアイデンティティに対し、ロールによって付与されます。
同様に、「DataActions」フィールドには、リソース内のデータの読み書きなどといった、ロールが実行できるデータプレーンアクションの一覧が示されます。

図 1: 「Actions」と「DataActions」を使用した Azure ロールの例 出典: Azure のドキュメント
「NotActions」を使用すると、「Actions」フィールドに示されたコントロールプレーンアクションから一部のアクションを差し引き、ロールに付与されないようにすることができます。 つまり、組み込みの Azure ロールをカスタマイズしてカスタム Azure ロールを作成する場合は、「NotActions 」属性を介して組み込みロールのコントロールプレーン「Actions」フィールドから権限を削除できます。
同様に、「NotDataActions」属性は、「DataActions」に含まれる組み込みロールのデータプレーンから権限を削除します。
ワイルドカードという便利な仕組みも知っておくとよいでしょう。 ワイルドカード (*) を使うと、それぞれの権限を個別にリスト化する代わりに、「Actions」、「NotActions」、「DataActions」、「NotDataActions」の一連の権限を定義できます。
Microsoft のドキュメントページには「ワイルドカード (*) を使用すると、指定されたアクション文字列に一致するものすべてにアクセス許可が拡張されます」と記載されています。
Microsoft が提供している例を見ていきましょう。 Azure Cost Management とエクスポートに関連するすべての権限を追加したい場合、次の 5 つのアクション文字列を個別に追加できます。
Microsoft.CostManagement/exports/action
Microsoft.CostManagement/exports/read
Microsoft.CostManagement/exports/write
Microsoft.CostManagement/exports/delete
Microsoft.CostManagement/exports/run/action
または、上記 5 つの文字列に相当する、このワイルドカード文字列を追加することもできます。
Microsoft.CostManagement/exports/*
つまり、Azure Cost Management のエクスポートに対して、削除以外のすべてのアクションを許可するロールを作成したい場合、「NotActions」とワイルドカードを組み合わせて、「Actions」に以下のパターンを記述すればよいのです。
Microsoft.CostManagement/exports/*
そして、「NotActions」には以下を指定します。
Microsoft.CostManagement/exports/delete
このように定義されたロールはエクスポートの読み取り、書き込み、実行を許可されますが、削除は許可されません。 利用可能な 4 つのアクション (/read、/write、/action、/run/action) を指定する必要はなく、「Actions」でパターンを指定して、「NotActions」で除外する 1 つのアクションを指定するだけで済みます。
これは Azure のカスタムロールを作成する際には取るに足らない改善に思えるかもしれませんが、作業が一定の規模に達した場合には非常に有意義になる場合があります。
では、どのように有意義なのでしょうか。 それについてはすぐに説明しますが、 まず、これらのフィールドに関して注意するべき重要な点を 1 つ挙げておきます。
「NotActions」と「拒否割り当て」の違い
「許可/拒否」ルールを使用した経験があるならば、「NotActions」と「NotDataActions」を、(やや直感的に) 拒否割り当てだと考えたくなるでしょう。 しかし、そうではありません。
かなり大きな違いがあります。
拒否割り当ては、これらのフィールドの 1 つで指定されたアクションが、そのポリシーが割り当てられるアイデンティティに対して常に拒否されることを意味します。 換言すれば、このアクションが別の割り当てでこのアイデンティティに許可されたとしても、このアイデンティティはアクションを実行できません。
これが 「NotActions」にも当てはまるならば、リソースの周囲にセキュリティ境界を作るのに非常に役立ったでしょう。 しかし、実際は異なります。
あるロールで「NotActions」または 「NotDataActions」によって除外された権限は、別のロールで同じユーザーに付与できます。
このことを、必ず覚えておいてください。
「NotActions」の働きを見てみよう
Tenable Cloud Security は、クラウドの権限に関する最先端の分析を提供する製品であり、今回の話題に関して言えば、Azure のセキュリティを強化します。
Tenable Cloud Security の CIEM (クラウドインフラ権限管理) 機能の一部として、Tenable は Azure サブスクリプション内のすべてのアイデンティティに割り当てられたすべての権限を自動的に分析し、ログから検出された実際のアクティビティと比較します。 これにより、現在割り当てられているロールを、そのアイデンティティのビジネス機能に必要とされる権限のみを持つ、最小権限のカスタムロールに置き換えるための提案を自動的に生成できます。 そうすれば、アイデンティティが侵害されたとしても、そのアイデンティティがもっと広範で不必要な権限を持っていた場合と比べて影響が小さくなります。
これは、稼働中のロールに対してオンデマンドで実行できます (図 2を参照)。 例えば、テストプロトコルの一環としてステップを作成し、定義が簡単な比較的「緩い」権限セットを使用してテスト環境でサービスを実行させることができます。 そして、ステージング環境と本番環境においては、テスト期間中に観察されたサービスのアクティビティに基づいてオンデマンドで作成された適切な最小権限ロールで、「緩い」権限セットを置き換えることができます。

図 2: 特定のスコープと時間枠について、最小権限ロールをオンデマンドで生成する
また、Tenable Cloud Security は、過剰な権限を持つアイデンティティを自動的に検出し、セキュリティ上の問題としてフラグを立てることもできます。 そして、Tenable Cloud Security は、図 3 に示されているように、自動生成された最小権限カスタムロールに、問題の解決に特化した「修正」タブを提供します。

図 3: 検出された過剰な権限を持つアプリケーションと、それを解決するための修正案
Tenable が自動生成するカスタムロールでは、「NotActions」フィールドが考慮されます。そのため、アイデンティティに割り当てられた元のロールに「NotActions」フィールドが含まれている場合は、それを考慮して、最小権限ロールにもこのフィールドを含めます。
これがいかに有意義かを示すために、当社が分析したアイデンティティの 1 つについて、「NotActions」フィールドの「使用前」と「使用後」を示すビューを作成しました。 このアイデンティティに元々割り当てられていた、権限が過剰なロールには、「NotActions」が含まれていました。
以下は、「NotActions」を使わずに生成した最小権限ロールです。

図 4 - あるアイデンティティについて「NotActions」を使わずに生成されたカスタムロールの案
図 4 は Visual Studio Code でドキュメントの冒頭を表示したものであり、ドキュメント全体のごく一部に過ぎません。
図 5 に示すように、この JSON ドキュメントの 「Actions」フィールドは、7200 行以上 (!) に達しています。

図 5 - 図 2 のカスタムロールの案を一番下までスクロールしたところ
意味の正確な理解、またはデバッグのために、この膨大なドキュメントに目を通さなければならないとなると、大変さが想像できると思います。
しかし、Tenable Cloud Security が既存の 「NotActions」フィールドを考慮に入れて最小権限のカスタムロールを作成する場合には、より簡潔でエレガントな方法でこれを行えるので、JSON ドキュメント全体を 1 つのスクリーンショットに納めることができます。
Tenable Cloud Security の高度なロジックでカスタムロールの構成方法を計算すると、結果は次のようになるでしょう。
アクションとアクションパターン (ワイルドカードとして 「*」を使用) を含み、必要でない部分には「NotAction」が指定されていないカスタムロール (1 つまたは複数) ができるはずです。

図 6 - 完全に含める必要があるアクションパターンに関する、最小権限カスタムロールの案の第 1 の部分
また、既存の「NotActions」フィールドを再現するために、必要に応じてそれらを含むロール (1 つまたは複数) が用意されます。

図 7 - 「NotActions」フィールドに必要なアクションが含まれている、最小権限カスタムロールの案の第 2 の部分
信じられないかもしれませんが、合計しても 70 行に満たないこの 2 つのカスタムロールは、図 4 と図 5 に示した、「Actions」フィールドだけでも 100 倍 (!) の行数があるロールと同等のものです。
先ほどとは全然違いますね。
この 2 つの読みやすくエレガントなカスタムロールをアイデンティティに割り当てれば、管理が簡単になります。 また、デバッグもはるかに簡単になり、自信を持ってロールを適用できるようになります (もちろん、これらのアイデンティティを本番環境に移行する前に、徹底的なテストを行う必要はあります)。 最終的には、これが最小権限ロールを適用するか、過剰な権限を持つ古くて危険なロールを使い続けるかの分かれ目になるのかもしれません。
以上が、「NotActions」プロパティを適切に使うことが非常に効果的である理由です。
まとめ
Tenable Cloud Security が行っているのと同様に「NotActions」フィールドを使うことで、エレガントで理解しやすい Azure カスタムロールを書くことができます。ロールに含める権限と除外する権限を正確に把握し、本番環境に移行する前に下位環境で必ずテストを行ってください。
Tenable は、お客様が Azure やその他のクラウド環境でロールをテストし、権限が過剰ではないか確認して、過剰であれば推奨されるカスタムロールに置き換えることができるように、Tenable Cloud Security のデモをご提供いたします。
- Cloud
- Cloud