TL

認可モデルの体系(RBAC・ABAC・ReBAC と Policy Engine)

「誰が何をしてよいか」の決め方が体系で見える。RBAC・ABAC・ReBAC の使い分けと、PDP/PEP・OPA/Zanzibar の設計を原理から押さえ、最小権限を破綻なく実装できる。

応用認可アクセス制御RBACABACOPAZanzibar最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.認可は「主体・操作・資源・文脈」を入力に許可/拒否を返す関数。RBAC は役割、ABAC は属性、ReBAC は資源間の関係グラフで権限を決める。
  • 2.判定(PDP)と強制(PEP)を分離するのが定石。OPA/Rego はポリシーを外部化し、Google Zanzibar は関係タプルの到達可能性探索で「共有」を表現する。
  • 3.最小権限は役割の粒度設計、職務分掌は危険な権限の組み合わせ禁止で実装する。役割爆発を避けるため RBAC と ABAC のハイブリッドが現実解。

認可とは何か:許可判定を関数として捉える

認証と認可で見たとおり、認証が「あなたは誰か」を確かめるのに対し、認可は「その人がこの資源にこの操作をしてよいか」を決めます。認可の本質は、次の入力を受け取り許可/拒否を返す決定関数です。

decision = authorize(subject, action, resource, context)
# subject  : 主体(ユーザー・サービスアカウント)
# action   : 操作(read / write / delete など)
# resource : 対象資源(ドキュメント・口座・API)
# context  : 文脈(時刻・場所・端末状態・リクエスト属性)
# 戻り値    : Permit / Deny(環境によっては理由や義務を伴う)

認可モデルとは、この関数をどんなデータ構造とルールで表現するかの設計思想です。代表的な3つ——RBAC・ABAC・ReBAC——は、判定の根拠を「役割」「属性」「関係」のどこに置くかで分かれます。どれが正しいかではなく、扱う権限の形に合うものを選び、しばしば組み合わせます。

RBAC:役割を介して権限を束ねる

**RBAC(Role-Based Access Control)は、ユーザーに直接権限を与えず、間に役割(ロール)**を挟みます。ユーザー → 役割 → 権限 の2段の割り当てにすることで、人事異動のたびに個別権限を付け替える手間を消します。役割に権限をまとめておけば、人の入れ替えは役割の付け替えだけで済みます。

NIST の RBAC モデルは段階的に定義されます。核となる Core RBAC に対し、Hierarchical RBAC は役割の継承(上位役割が下位の権限を含む)を、Constrained RBAC は職務分掌のための制約を加えます。

# 割り当て関係(多対多)
UA: User × Role      例) 田中 ─assigned→ 経理担当
PA: Role × Permission 例) 経理担当 ─grants→ {仕訳read, 仕訳write}
# 有効権限 = ユーザーに割り当たった全役割の権限の和集合

RBAC の弱点は**役割爆発(role explosion)**です。「東京支店の経理で、かつ部長で、月末だけ承認できる」のように条件が増えるほど、その組み合わせごとに役割を新設する誘惑が生まれ、役割数が組み合わせ的に膨張します。役割が数千を超えると、もはや誰がなぜその権限を持つか追えなくなります。

役割は「職務」に対応させ、条件を詰め込まない

役割爆発の主因は、本来 ABAC で扱うべき条件(拠点・時間帯・データ区分)を役割名に押し込むことです。役割は「経理担当」「監査人」のような職務に対応させ、可変の条件は属性で評価する——この切り分けが、RBAC を健全に保つ最大のコツです。条件まで役割で表すと、組み合わせ爆発で破綻します。

ABAC:属性とポリシーで動的に判定する

ABAC(Attribute-Based Access Control)は、主体・資源・操作・環境の属性を入力に、ポリシー(ルール式)を評価して判定します。役割という固定の中間層を持たず、部署 == 資源の所有部署 AND 時刻 が 業務時間内 のような条件式で許可を表現します。標準仕様の XACML は、この評価の流れを規定しています。

ABAC の強みは表現力です。RBAC では役割を増やすしかなかった「自部署のデータだけ」「機密度が自分のクリアランス以下のみ」といったデータ依存・文脈依存の制御を、ルール1本で書けます。一方の弱みは、ポリシーが増えると**「結局この人は何ができるのか」を静的に列挙しにくい**ことです。許可は実行時に属性を当てはめて初めて確定するため、監査やレビューが難しくなります。

観点RBAC(役割ベース)ABAC(属性ベース)
判定の根拠割り当てられた役割主体・資源・環境の属性とルール
得意な制御職務に紐づく静的な権限データ依存・文脈依存の動的な権限
権限の可視化役割を見れば列挙しやすい実行時評価のため静的列挙が難しい
主な弱点条件が増えると役割爆発ポリシー増で評価・監査が複雑化
変更の単位役割と割り当ての付け替えポリシー(ルール式)の編集

実務では両者をハイブリッドにするのが現実解です。職務の枠は RBAC(役割)で粗く決め、その内側の細かな条件(自分のテナント・営業時間内など)を ABAC のルールで絞る。役割で「何の仕事か」を、属性で「どのデータ・どの状況か」を担わせると、役割数を抑えつつ表現力を確保できます。

ReBAC:資源間の関係グラフで権限を導く

RBAC も ABAC も主体側の属性を見ますが、SaaS でよくある「このドキュメントを共有された人だけ読める」は、主体の属性ではなく資源と主体の関係で決まります。これを正面から扱うのが ReBAC(Relationship-Based Access Control)です。権限を、オブジェクト間の関係のグラフ上の到達可能性として定義します。

Google の Zanzibar は ReBAC の代表的設計で、すべての関係を関係タプルとして保存します。

# 関係タプル: <object>#<relation>@<subject>
doc:roadmap#owner@user:tanaka          # tanaka は roadmap の所有者
doc:roadmap#viewer@group:eng#member    # eng グループのメンバーは閲覧者
group:eng#member@user:sato             # sato は eng のメンバー

# 名前空間設定(疑似): viewer は owner を含み、親フォルダの viewer も継承
relation viewer = self | owner | parent->viewer

「sato は roadmap を読めるか」という問いは、doc:roadmap#viewer から出発し、グループや親フォルダの関係を辺としてたどってたどり着けるかというグラフ到達可能性探索に帰着します。継承(owner は viewer でもある)や入れ子グループ、フォルダ階層は、すべてこの探索で自然に表現されます。

Zanzibar が解いたのは「正しさ」より「一貫性とスケール」

Zanzibar の難しさは、世界中のデータセンターで毎秒数百万件の権限チェックをさばきつつ、「共有を取り消した直後に元の人が読めてしまう」古い結果を返さないことにあります。鍵は **Zookie(zookie)**と呼ぶスナップショットトークンで、これにより各チェックが「いつの時点の関係グラフか」を指定でき、新しい権限変更を反映しない古い読み取りを排除します。ReBAC の本質は到達可能性ですが、製品としての価値は分散環境での一貫性保証にあります。

PDP と PEP:判定と強制を分離する

どのモデルを採っても、認可の実装では判定する場所強制する場所を分けるのが定石です。XACML の用語で、この2つを PDP と PEP と呼びます。

  • PDP(Policy Decision Point):ポリシーと入力(主体・操作・資源・文脈)から Permit / Deny計算する頭脳。
  • PEP(Policy Enforcement Point):リクエストを受け、PDP に判定を問い合わせ、その結果を**実際に適用する(通す・拒む)**関所。API ゲートウェイやアプリのミドルウェアがこれにあたります。
リクエスト → [PEP] ─問い合わせ→ [PDP] ─参照→ ポリシー / 関係データ
                ↑                  │
                └──── Permit/Deny ──┘
PEP は Permit なら処理続行、Deny なら 403 を返す

分離の利点は、認可ロジックを各サービスのコードから引き剥がせることです。ポリシーを1か所で管理・更新でき、全サービスが同じ判定基準に従えます。アプリ内に if user.role == "admin" を散らす実装は、権限ルールがコードに埋もれて最小権限の見直しを困難にします。PDP/PEP 分離はこの密結合を断ち切ります。

OPA / Rego:ポリシーを宣言的に外部化する

PDP を汎用化した代表が **OPA(Open Policy Agent)**です。ポリシーを Rego という宣言的言語で記述し、JSON の入力に対して判定を返します。OPA はマイクロサービスのサイドカーやライブラリとして動き、Kubernetes のアドミッション制御から API 認可まで横断的に使えます。

package authz

default allow = false

# 自分が所有する注文は読める
allow {
  input.action == "read"
  input.resource.type == "order"
  input.resource.owner == input.subject.id
}

# 経理役割は業務時間内なら全注文を読める(RBAC × ABAC)
allow {
  input.action == "read"
  input.resource.type == "order"
  "accounting" in input.subject.roles
  input.context.hour >= 9
  input.context.hour < 18
}

Rego の評価は、allow を真にするルールが1つでも成立すれば許可という論理和(OR)が基本で、既定は falseデフォルト拒否)です。重要なのは、これはポリシー評価エンジンであって、関係データの保管庫ではない点です。「誰がどの資源を共有されたか」という大規模な関係グラフは、OPA に全部載せるよりも、Zanzibar 系の専用ストア(SpiceDB / OpenFGA など)に持たせ、OPA からはその結果を参照する構成が向きます。評価ロジックと関係データの所在を分けて考えるのが設計の勘所です。

RBAC・ABAC・ReBAC は排他ではなく層になる

現実のシステムは1つのモデルで割り切れません。「経理役割を持つ(RBAC)」「自テナントかつ業務時間内(ABAC)」「かつこの帳票を共有されている(ReBAC)」を AND で重ねるのが典型です。OPA のようなエンジンで役割・属性条件を評価し、関係グラフの判定だけ Zanzibar 系に委譲する——この層分けが、表現力と運用性を両立させます。

最小権限と職務分掌:原理を制約に落とす

認可モデルは、2つの古典原則を実装可能な制約へ翻訳する道具でもあります。

ひとつは最小権限の原則で、各主体には職務遂行に必要な権限だけを、必要な期間だけ与えます。RBAC なら役割の粒度を職務に合わせて設計し、過剰な権限をまとめ持ちさせない。恒久付与を避け、必要時だけ昇格させる JIT(Just-In-Time)アクセスや時間制限付き付与も、最小権限を時間軸へ広げた実装です(→ 最小権限の原則)。

もうひとつは職務分掌(SoD:Separation of Duties)で、不正やミスを防ぐため、危険な権限の組み合わせを同一人物に持たせない制約です。たとえば「支払いを申請する権限」と「支払いを承認する権限」を1人が同時に持つと、自分で申請して自分で承認できてしまいます。これを Constrained RBAC では役割間の相互排他制約として表現します。

# 静的職務分掌(SSD): 同時に割り当て不可
mutually_exclusive(role:payment_requester, role:payment_approver)
# → 同じユーザーへ両役割を割り当てる操作自体を拒否する

# 動的職務分掌(DSD): 割り当ては可だが、同一トランザクションでの併用を禁止
# → 申請者は、自分が申請した案件の承認セッションを起動できない
権限の「足し算」だけ管理し「組み合わせ」を見落とす

多くの権限事故は、個々の権限が妥当でも組み合わせると危険になる見落としから生じます。SoD は単独の権限審査では検出できず、役割やポリシーをまたいだ組み合わせ分析が要ります。鍵やトークンの管理を含む権限設計では、シークレット管理と同様に「誰が・何を・いつまで」を継続的に棚卸しし、相互排他の制約を定期監査することが不可欠です。付与した瞬間に正しくても、積み重ねで破綻します。

まとめ

認可モデルは、authorize(subject, action, resource, context) という決定関数を、何を根拠に組み立てるかの違いです。RBAC は役割で職務に紐づく静的権限を、ABAC は属性でデータ・文脈依存の動的権限を、ReBAC は関係グラフで「共有」のような資源間の権限を表します。これらは排他ではなく、層として重ねるのが実務の解です。

実装では判定(PDP)と強制(PEP)を分離し、OPA/Rego でポリシーを外部化し、大規模な関係は Zanzibar 系ストアに委ねる。その上で、役割の粒度設計で最小権限を、相互排他制約で職務分掌を担保します。認可は「与える」設計であると同時に、ゼロトラストが説くように「アクセスのたびに評価し続ける」運用でもある——この両輪が、権限を破綻なく保つ条件です。

セキュリティ Article

認可モデルの体系(RBAC・ABAC・ReBAC と Policy Engine)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

認可

比較で見る軸

難易度: advanced / カテゴリ: セキュリティ / タグ数: 6

導入後に効く点

判定(PDP)と強制(PEP)を分離するのが定石。OPA/Rego はポリシーを外部化し、Google Zanzibar は関係タプルの到達可能性探索で「共有」を表現する。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
セキュリティ
タグ数
6

判断チェックリスト

  • 自社の用途が「認可 / アクセス制御」に近いか確認する。
  • 強みである「認可は「主体・操作・資源・文脈」を入力に許可/拒否を返す関数。RBAC は役割、ABAC は属性、ReBAC は資源間の関係グラフで権限を決める。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

認可アクセス制御RBACABACOPA認可アクセス制御RBAC
参考: 公式情報