API キーの記事で「キーの権限は、持ち主の権限そのもの」と書きました。では、その持ち主にどんな権限を、どうやって決めておけばよいのか。人もシステムも増えていく中で、権限を追いきれる形にしておく考え方が RBAC(ロールベースのアクセス制御)です。この記事では、RBAC のしくみを、Azure・Microsoft Entra ID・Kubernetes・Cisco Meraki の公式ドキュメントで確かめながら図にしました。
- RBAC は、人ではなく「役割(ロール)」に権限を付ける考え方であること
- 割り当ての3つの要素:誰に・何を・どこで(スコープ)
- Azure・Entra ID・Kubernetes・Meraki での RBAC の形
- 自分の API で RBAC を使うしくみ(Entra ID のアプリロール)
- 設計のコツと、RBAC だけでは足りない場面
RBAC とは:役割に権限を付ける
RBAC(Role-Based Access Control)は、権限を人に直接付けるのではなく、「閲覧者」「作業者」「管理者」のような役割(ロール)に付け、人をロールに入れる考え方です。NIST の説明では、利用者には1つ以上のロールが割り当てられ、ロールには1つ以上の権限が割り当てられます。NIST のモデルは、アメリカの標準 ANSI/INCITS 359 にもなっています。
人ごとに権限を付けると、人と権限の組み合わせが増えるほど、誰が何をできるのかを追いきれなくなります。ロールを挟むと、人の異動や入れ替わりは「どのロールに入れるか」を変えるだけで済み、ロールの中身を見れば、そのロールの人ができることがわかります。
認証(誰か)と認可(何をしてよいか)でいえば、RBAC は認可のしくみです。2つの違いは認証と認可の記事で説明しています。
割り当ての3つの要素:誰に・何を・どこで
Azure の RBAC では、権限は「ロールの割り当て(role assignment)」で与えます。割り当ては、「誰に」「何を」「どこで」の3つでできています。
わかりにくいのは「どこで」(スコープ)です。スコープは、割り当てを置く場所のことです。Azure ポータルでは、管理グループ、サブスクリプション、リソースグループ、リソースのそれぞれのページに「アクセス制御(IAM)」の画面があり、そこで割り当てを追加します。つまり割り当ては、「誰に・何を」を書いた札を、スコープに貼る操作だと考えるとわかりやすくなります。札を貼った場所(とその中)だけで、権限が効きます。
図2は Microsoft のドキュメントの例です。Marketing グループに Contributor を、リソースグループ pharma-sales のスコープで割り当てています。Marketing グループの人は pharma-sales の中のリソースを作成・管理できますが、ほかのリソースグループのリソースには、別の割り当てがない限り手が届きません。
| 要素 | 意味 | 図2の例 |
|---|---|---|
| 誰に (セキュリティプリンシパル) | アクセスを求める側。ユーザー、グループ、サービスプリンシパル(アプリの ID)、マネージド ID のどれか | Marketing グループ |
| 何を (ロールの定義) | できる操作(読む、書く、消すなど)の集まり。組み込みのロールのほか、自分で作るカスタムロールもある | Contributor |
| どこで (スコープ) | 割り当てを置く場所で、権限が効く範囲。管理グループ、サブスクリプション、リソースグループ、リソースの4段階から選ぶ | リソースグループ pharma-sales |
Windows のフォルダのアクセス権(ACL)も、フォルダの側に「誰に・何を許すか」を設定し、その設定は既定で下のフォルダにも引き継がれます。Azure のスコープもこれと同じで、割り当ては対象の側(スコープ)に置かれ、下の階層へ効きます。ACL のしくみはアクセストークンと ACL の記事で説明しています。
Azure にはたくさんの組み込みロールがありますが、すべての種類のリソースに使える基本のロールは次の3つです。
| ロール | できること |
|---|---|
| Owner(所有者) | すべてのリソースを管理でき、ほかの人にロールを割り当てることもできる |
| Contributor(共同作成者) | すべてのリソースを管理できるが、ロールの割り当てはできない |
| Reader(閲覧者) | リソースを見ることだけができる |
スコープは親子でつながる
スコープは親子の関係になっていて、上で割り当てたロールは、その下のすべてに効きます。
Azure の RBAC には、ほかにも次の決まりがあります。
- グループは入れ子でも効く:ユーザーが入っているグループが、さらに別のグループに入っていて、その別のグループにロールが割り当てられていれば、ユーザーもその権限を持ちます。
- 足し算で決まる:複数の割り当てがあるときは、その合計が実際の権限になります。サブスクリプションで Contributor、その中のリソースグループで Reader を割り当てても、そのリソースグループでは Contributor として操作できます。
- 拒否の割り当てが先:ロールの割り当てとは別に「拒否の割り当て(deny assignment)」があり、当てはまればアクセスはブロックされます。
API の呼び出しごとに判定される
Azure の RBAC は、Azure Resource Manager(Azure を操作する API の入口)で判定されます。呼び出しのたびに、次の順で確かめます。
「ロールの定義」の中身は、許す操作(Actions)から除く操作(NotActions)を引いたものです。ワイルドカード(*)で広く許してから、一部を除く書き方ができます。
いろいろな RBAC:同じ考え方、別のしくみ
RBAC は考え方なので、製品ごとに別々のしくみとして作られています。名前が似ていても、データの置き場所も判定する場所も別です。
| しくみ | 守る対象 | ロールと範囲の決め方 |
|---|---|---|
| Azure RBAC | Azure のリソース(VM、ストレージなど) | Owner・Contributor・Reader など。範囲は管理グループ〜リソースの4段階 |
| Microsoft Entra ロール | Entra ID のリソース(ユーザー、グループ、アプリ) | 組み込みロールとカスタムロール。範囲はテナント全体、管理単位、個別のオブジェクト(特定のアプリなど) |
| Kubernetes RBAC | クラスタの中のリソース(Pod など) | Role(名前空間の中だけ)と ClusterRole(クラスタ全体)を、RoleBinding・ClusterRoleBinding で人に結び付ける |
| Cisco Meraki のダッシュボード | 組織とネットワークの設定 | 組織の権限は Full・Read-only・None。ネットワークの権限は Full・Read-only・Monitor-only・Guest ambassador |
Azure のロールは Azure のリソースを、Entra のロールは Entra ID のリソースを守ります。Microsoft のドキュメントでは、Entra ID の全体管理者(Global Administrator)であっても、既定では Azure のリソースにはアクセスできないと説明しています(必要なときに自分で権限を引き上げる操作は別にあります)。
Kubernetes の例:Role と RoleBinding
Kubernetes の RBAC は、ロール(Role)とその結び付け(RoleBinding)を YAML で書きます。Kubernetes のドキュメントの例では、default 名前空間の Pod を読むだけのロールを作り、それを利用者 jane に結び付けています。
例:Pod を読むだけのロール(Kubernetes のドキュメントの例)
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"]
例:そのロールを利用者に結び付ける(Kubernetes のドキュメントの例)
apiVersion: rbac.authorization.k8s.io/v1 # This role binding allows "jane" to read pods in the "default" namespace. # You need to already have a Role named "pod-reader" in that namespace. kind: RoleBinding metadata: name: read-pods namespace: default subjects: # You can specify more than one "subject" - kind: User name: jane # "name" is case sensitive apiGroup: rbac.authorization.k8s.io roleRef: # "roleRef" specifies the binding to a Role / ClusterRole kind: Role #this must be Role or ClusterRole name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to apiGroup: rbac.authorization.k8s.io
Kubernetes のドキュメントは、権限は足し算だけで、「拒否」のルールはないと明記しています。付けていない操作は、できません。
自分の API で RBAC を使う:Entra ID のアプリロール
自社で作った API に RBAC を入れたいときは、Microsoft Entra ID の「アプリロール」が使えます。API のアプリ登録にロールを定義し、ユーザーやグループに割り当てると、その人がもらうアクセストークンの roles クレームに、割り当てたロールの値が入ります。
| 項目 | 内容(Microsoft のドキュメントの例) |
|---|---|
| 表示名 | Survey Writer |
| 割り当てる相手 | ユーザー・グループ、アプリ、またはその両方 |
| 値(Value) | Survey.Create。トークンの roles に入る文字列で、API のコードで確かめる値と完全に一致させる |
| 説明 | Writers can create surveys. |
大事なのは、ロールの判定をするのは API 自身のコードだという点です。Entra ID はトークンに roles を入れるところまでで、どのロールなら何を許すかは、API の側で書きます。Microsoft のドキュメントでも、アプリロールを定義したら、その認可のロジックを実装するのはアプリの責任だとしています。
- アプリロールをアプリに割り当てると「アプリケーションの許可」になり、管理者の同意が必要です。
- サービスプリンシパルをグループに入れ、そのグループにアプリロールを割り当てても、今のところトークンに roles は入りません。
- ユーザー用とアプリ用で、別のロールを定義するよう勧めています(同じロールだと、ユーザーとしてのサインインとアプリとしてのサインインを見分けにくくなるため)。
設計のコツ
| コツ | 理由 |
|---|---|
| いちばん小さい権限から | OWASP は、最小権限を守らないと機密のリソースが危険にさらされるとしている。Entra のロールも、最小権限の原則に沿って細かく権限を渡せるよう作られている |
| 決めていなければ拒否 | OWASP は、既定でアクセスを拒否するよう求めている。Kubernetes のように、付けていない操作はできない作りが基本 |
| スコープは狭く | 上のスコープで割り当てると、下のすべてに効く。必要なリソースグループやリソースだけに割り当てる |
| 人ではなくグループに割り当てる | 入れ子のグループにも効くので、異動はグループの出入りで済む |
| 毎回、サーバ側で確かめる | OWASP は、ほとんどのリクエストで確かめるだけでは足りず、すべてのリクエストで確かめるよう求めている。確認はクライアントではなく、サーバやゲートウェイで行う |
RBAC だけでは足りない場面
RBAC は「ロールを持っているかどうか」だけで判断します。OWASP は、この単純さのために、ロールを作りすぎる「ロールの爆発」が起きやすいこと、「このデータの持ち主だけが編集できる」のような、データ1件ごとの判断が苦手なことを挙げ、アプリの開発では属性(ABAC)や関係(ReBAC)で判断する方式を勧めています。
Azure の RBAC も、ロールの割り当てに「条件」を付けられるようになっていて(図4の⑤)、ロールだけでは決めきれない絞り込みができます。ロールで大まかに分け、細かい判断は条件や属性で決める、という組み合わせが現実的です。
企業での例
| 場面 | しくみ | 割り当ての例 |
|---|---|---|
| 運用チームが、担当システムの Azure リソースを管理する | Azure RBAC | 運用チームのグループに、システムのリソースグループのスコープで Contributor。監査担当にはサブスクリプションのスコープで Reader |
| 拠点ごとのヘルプデスクが、その拠点の利用者だけを管理する | Entra ロール | 拠点ごとに管理単位を作り、そのスコープでユーザー管理のロールを割り当てる |
| 開発チームが、自分たちの名前空間だけを使う | Kubernetes RBAC | チームの名前空間に Role を作り、RoleBinding でチームのメンバーに結び付ける |
| 拠点の担当者は状況を見るだけ、本社のネットワーク担当は全部を設定する | Meraki | 拠点の担当者にはそのネットワークの Read-only か Monitor-only、本社のネットワーク担当には組織の Full |
| 自社の業務 API で、登録できる人と閲覧だけの人を分ける | アプリロール | API に作成用と閲覧用のアプリロールを定義し、部署のグループに割り当てる。API は roles を見て判断する |
Meraki の API キーは、発行した管理者と同じ権限を持ちます(API キーの記事)。自動化用の管理者に Read-only の権限だけを与えておけば、そのキーでは設定を変えられません。RBAC の設計は、キーやトークンの権限を絞ることにも直結します。
まとめ
| 項目 | ポイント |
|---|---|
| RBAC | 権限をロールに付け、人をロールに入れる。異動はロールの付け替えで済む |
| 割り当て | 誰に(プリンシパル)・何を(ロール)・どこで(スコープ)の3つで決まる |
| Azure の決まり | スコープは親子で下へ効く。グループは入れ子でも効く。権限は足し算。拒否の割り当てが先に効く |
| 製品ごとのしくみ | Azure RBAC、Entra ロール、Kubernetes RBAC、Meraki の管理者権限は、それぞれ別のしくみ |
| 自社の API | Entra ID のアプリロールで roles をトークンに入れ、API のコードで判定する |
| 設計 | 最小権限、既定は拒否、スコープは狭く、グループに割り当て、毎回サーバ側で確かめる |
| 限界 | ロールが増えすぎる、データ1件ごとの判断が苦手。属性(ABAC)との組み合わせを考える |
参考にした資料
この記事は、次の資料と公式ドキュメントで内容を確かめて書きました。仕様や対応状況は変わることがあるので、最新の情報はリンク先で確かめてください。
- Role Based Access Control(NIST CSRC):ユーザーにロール、ロールに権限を割り当てるモデル、ANSI/INCITS 359
- Authorization Cheat Sheet(OWASP):最小権限、既定で拒否、毎回の確認、サーバ側での確認、RBAC の限界と ABAC・ReBAC
- What is Azure role-based access control (Azure RBAC)?(Microsoft Learn):割り当ての3要素、4段階のスコープ、グループ、足し算、判定の流れ、Marketing グループの例
- Azure roles, Microsoft Entra roles, and classic subscription administrator roles(Microsoft Learn):Owner・Contributor・Reader、Azure のロールと Entra のロールの違い
- Overview of role-based access control in Microsoft Entra ID・Understand roles in Microsoft Entra ID(Microsoft Learn):Entra ロールの範囲、最小権限、別々のしくみであること
- Add app roles to your application and receive them in the token・Protected web API: Verify scopes and app roles(Microsoft Learn):アプリロールの定義と割り当て、roles クレーム、アプリへの割り当てと管理者の同意、グループ経由のサービスプリンシパルの注意、ユーザー用とアプリ用でロールを分けること
- Using RBAC Authorization(Kubernetes):Role と ClusterRole、RoleBinding、権限は足し算だけで拒否のルールはないこと、pod-reader の例
- Managing Dashboard Administrators and Permissions(Cisco Meraki Documentation):組織とネットワークの権限の種類
あとがき
Azure・Entra ID・Kubernetes・Meraki と並べてみると、どれも「誰に・何を・どこで」の形は同じなのに、しくみはそれぞれ別で、名前の似たロールでも中身は違う、というのがいちばんの気づきでした。とくに、Entra ID の全体管理者が既定では Azure のリソースに触れないという点は、権限を設計するときに勘違いしやすいところだと感じます。
コメント