【図解】RBACとは?ロール・スコープ・割り当てのしくみをAzure・Kubernetes・Merakiの例で初心者向けに解説

API キーの記事で「キーの権限は、持ち主の権限そのもの」と書きました。では、その持ち主にどんな権限を、どうやって決めておけばよいのか。人もシステムも増えていく中で、権限を追いきれる形にしておく考え方が RBAC(ロールベースのアクセス制御)です。この記事では、RBAC のしくみを、Azure・Microsoft Entra ID・Kubernetes・Cisco Meraki の公式ドキュメントで確かめながら図にしました。

この記事でわかること
  1. RBAC は、人ではなく「役割(ロール)」に権限を付ける考え方であること
  2. 割り当ての3つの要素:誰に・何を・どこで(スコープ)
  3. Azure・Entra ID・Kubernetes・Meraki での RBAC の形
  4. 自分の API で RBAC を使うしくみ(Entra ID のアプリロール)
  5. 設計のコツと、RBAC だけでは足りない場面

RBAC とは:役割に権限を付ける

RBAC(Role-Based Access Control)は、権限を人に直接付けるのではなく、「閲覧者」「作業者」「管理者」のような役割(ロール)に付け、人をロールに入れる考え方です。NIST の説明では、利用者には1つ以上のロールが割り当てられ、ロールには1つ以上の権限が割り当てられます。NIST のモデルは、アメリカの標準 ANSI/INCITS 359 にもなっています。

人ごとに権限を付ける役割(ロール)に権限を付ける社員1社員2社員3社員4読む作る消す権限を配る人や権限が増えると線が増え、追いきれない社員1社員2社員3社員4閲覧者作業者管理者読む作る消す権限を配る人はロールに入れるだけ。異動はロールの付け替え
図1 人に付けるか、ロールに付けるか

人ごとに権限を付けると、人と権限の組み合わせが増えるほど、誰が何をできるのかを追いきれなくなります。ロールを挟むと、人の異動や入れ替わりは「どのロールに入れるか」を変えるだけで済み、ロールの中身を見れば、そのロールの人ができることがわかります。

認証(誰か)と認可(何をしてよいか)でいえば、RBAC は認可のしくみです。2つの違いは認証と認可の記事で説明しています。

割り当ての3つの要素:誰に・何を・どこで

Azure の RBAC では、権限は「ロールの割り当て(role assignment)」で与えます。割り当ては、「誰に」「何を」「どこで」の3つでできています。

わかりにくいのは「どこで」(スコープ)です。スコープは、割り当てを置く場所のことです。Azure ポータルでは、管理グループ、サブスクリプション、リソースグループ、リソースのそれぞれのページに「アクセス制御(IAM)」の画面があり、そこで割り当てを追加します。つまり割り当ては、「誰に・何を」を書いた札を、スコープに貼る操作だと考えるとわかりやすくなります。札を貼った場所(とその中)だけで、権限が効きます。

誰にMarketingグループ何をContributor作成・管理できるサブスクリプションリソースグループpharma-sales中のリソースを作成・管理できるリソースグループ(ほかのグループ)この割り当てでは届かないロールの割り当て誰に:Marketing何を:Contributorどこで(スコープ)= 札を貼る場所ここではリソースグループ pharma-sales割り当ては「誰に・何を」を書いた札を、スコープに貼ること。貼った場所の中だけで効く
図2 ロールの割り当て:「誰に・何を」の札をスコープに貼る

図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(閲覧者)リソースを見ることだけができる

スコープは親子でつながる

スコープは親子の関係になっていて、上で割り当てたロールは、その下のすべてに効きます。

管理グループManagement groupサブスクリプションSubscriptionリソースグループResource groupリソースResourceここで Reader を割り当てると下のすべてで読める下へ引き継がれるスコープは親子の関係。上で割り当てたロールは、その下のすべてに効く
図3 スコープの親子関係

Azure の RBAC には、ほかにも次の決まりがあります。

  • グループは入れ子でも効く:ユーザーが入っているグループが、さらに別のグループに入っていて、その別のグループにロールが割り当てられていれば、ユーザーもその権限を持ちます。
  • 足し算で決まる:複数の割り当てがあるときは、その合計が実際の権限になります。サブスクリプションで Contributor、その中のリソースグループで Reader を割り当てても、そのリソースグループでは Contributor として操作できます。
  • 拒否の割り当てが先:ロールの割り当てとは別に「拒否の割り当て(deny assignment)」があり、当てはまればアクセスはブロックされます。

API の呼び出しごとに判定される

Azure の RBAC は、Azure Resource Manager(Azure を操作する API の入口)で判定されます。呼び出しのたびに、次の順で確かめます。

① トークンを付けて API を呼ぶトークンにはグループのメンバーシップも入る② そのリソースに効く割り当てを集めるロールの割り当てと拒否の割り当て③ 拒否の割り当てに当たる?④ 持っているロールに、その操作が入っている?Actions − NotActions = できる操作⑤ 割り当てに条件があれば、条件を満たす?はいいいえいいえ拒否アクセスできないはい(条件がなければそのまま)許可いいえはい
図4 Azure Resource Manager がアクセスを判定する流れ

「ロールの定義」の中身は、許す操作(Actions)から除く操作(NotActions)を引いたものです。ワイルドカード(*)で広く許してから、一部を除く書き方ができます。

いろいろな RBAC:同じ考え方、別のしくみ

RBAC は考え方なので、製品ごとに別々のしくみとして作られています。名前が似ていても、データの置き場所も判定する場所も別です。

しくみ守る対象ロールと範囲の決め方
Azure RBACAzure のリソース(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 のロールと Entra のロールは別物

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 クレームに、割り当てたロールの値が入ります。

管理者Entra 管理センターMicrosoft Entra ID利用者のアプリ自社の APIroles を確かめる① API にアプリロールを定義② ユーザーやグループに割り当て③ サインインしてトークンを頼む④ トークン(roles: Survey.Create)⑤ API を呼ぶ(Bearer)roles に必要な値があるか⑥ 結果(なければ 403)ロールの判定に使う情報はトークンの roles に入り、判定するのは API 自身のコード
図5 アプリロールで API に RBAC を入れる流れ
項目内容(Microsoft のドキュメントの例)
表示名Survey Writer
割り当てる相手ユーザー・グループ、アプリ、またはその両方
値(Value)Survey.Create。トークンの roles に入る文字列で、API のコードで確かめる値と完全に一致させる
説明Writers can create surveys.

大事なのは、ロールの判定をするのは API 自身のコードだという点です。Entra ID はトークンに roles を入れるところまでで、どのロールなら何を許すかは、API の側で書きます。Microsoft のドキュメントでも、アプリロールを定義したら、その認可のロジックを実装するのはアプリの責任だとしています。

気をつける点(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 の管理者権限は、それぞれ別のしくみ
自社の APIEntra ID のアプリロールで roles をトークンに入れ、API のコードで判定する
設計最小権限、既定は拒否、スコープは狭く、グループに割り当て、毎回サーバ側で確かめる
限界ロールが増えすぎる、データ1件ごとの判断が苦手。属性(ABAC)との組み合わせを考える

参考にした資料

この記事は、次の資料と公式ドキュメントで内容を確かめて書きました。仕様や対応状況は変わることがあるので、最新の情報はリンク先で確かめてください。

あとがき

Azure・Entra ID・Kubernetes・Meraki と並べてみると、どれも「誰に・何を・どこで」の形は同じなのに、しくみはそれぞれ別で、名前の似たロールでも中身は違う、というのがいちばんの気づきでした。とくに、Entra ID の全体管理者が既定では Azure のリソースに触れないという点は、権限を設計するときに勘違いしやすいところだと感じます。

コメント