ABAC とは何か — RBACの限界を超える属性ベース設計

第4章で解説したRBACは「役割に権限を結びつける」という核心的洞察により業界標準となりましたが、 現実の組織では避けがたい構造的問題があります。 「東京オフィスの経理部門のマネージャーが、平日9〜18時のみ機密分類Aの帳票を閲覧できる」 —— このような条件をロールだけで表現しようとすると、地域×部門×職位×時間帯の組み合わせでロール数が爆発します。

これを解決するのが ABAC(Attribute-Based Access Control) です。 NIST SP 800-162(2014年)による定義は明快です。 「主体・客体・操作・環境条件に関連する属性をポリシー・ルールと照合してアクセスの可否を決定するアクセス制御」。 ロールという間接レイヤーを経由せず、属性という実体そのものをポリシーの入力とします。

属性の4カテゴリ

ABACが扱う属性は4つのカテゴリに分類されます。

  • Subject属性(主体): アクセスを要求する人やシステムの特性。 部署(department)・役職(title)・セキュリティクリアランス(clearance_level)・雇用形態(employee_type)など。
  • Object属性(客体): アクセス対象のリソースの特性。 機密分類(classification)・データ所有者(owner)・コンテンツカテゴリ(category)・プロジェクトID(project_id)など。
  • Action属性(操作): 実行しようとする操作の種別。 read / write / delete / approve / export などの操作タイプとその重要度。
  • Environment属性(環境): 要求時のコンテキスト情報。 時刻・日付・IPアドレス・接続元ネットワーク・デバイス認証状態・リスクスコアなど。

これら4カテゴリを組み合わせることで、 RBAC では表現できなかった複雑な認可条件を宣言的に記述できます。 典型的なポリシーの例:IF user.department == "Finance" AND resource.classification == "Confidential" AND env.time BETWEEN 09:00-18:00 THEN Permit

XACML アーキテクチャ — PEP/PDP/PAP/PIP の役割分担

ABACの実装標準として長年参照されてきたのが XACML(eXtensible Access Control Markup Language) です。 OASIS により標準化され、2013年に XACML 3.0 が公開されました。 XACMLの本質的な貢献はXML仕様そのものよりも、認可処理を5つのコンポーネントに明確分離したアーキテクチャパターンにあります。

5コンポーネントの役割

  • PEP(Policy Enforcement Point): リクエストを最初に受け取る関門。PDPの判定結果を強制する実行者。 「Permit なら通す、Deny なら403を返す」という単純な役割に集中します。
  • PDP(Policy Decision Point): ポリシーを評価して Permit / Deny / Indeterminate / NotApplicable の4値を返す頭脳。 PIPから属性値を収集してポリシーと照合します。
  • PAP(Policy Administration Point): ポリシーを作成・編集・管理する管理インターフェイス。 セキュリティ管理者がポリシーを定義する場所です。
  • PRP(Policy Retrieval Point): ポリシーを格納するリポジトリ。PDP がポリシーを取得する際の参照先です。
  • PIP(Policy Information Point): 属性値を外部から取得するデータブローカー。 LDAPからユーザーの部署を取得し、データベースからリソースの機密分類を取得するといった役割です。
graph LR
  Client([クライアント]) -->|リクエスト| PEP[PEP\n強制点]
  PEP -->|認可要求| PDP[PDP\n判定エンジン]
  PDP -->|ポリシー取得| PRP[(PRP\nポリシーDB)]
  PDP -->|属性取得| PIP[(PIP\n属性ソース)]
  PIP -->|ユーザー属性| LDAP[(LDAP/AD)]
  PIP -->|リソース属性| DB[(リソースDB)]
  PAP[PAP\n管理ツール] -->|ポリシー登録| PRP
  PDP -->|Permit/Deny| PEP
  PEP -->|アクセス許可 or 拒否| Client
  style PEP fill:#3b82f6,stroke:#1d4ed8,color:#fff
  style PDP fill:#8b5cf6,stroke:#6d28d9,color:#fff
  style PAP fill:#10b981,stroke:#059669,color:#fff
  style PRP fill:#374151,stroke:#6b7280,color:#fff
  style PIP fill:#374151,stroke:#6b7280,color:#fff
XACMLアーキテクチャ: PEP(強制)→PDP(判定)→PRP/PIP(ポリシー・属性取得)の処理フロー。PAPはポリシーの管理インターフェイス

XACML 3.0 の4つの決定結果

PDPが返す決定結果は4値です。単純な Permit/Deny に加え、例外状態が明示されています。

  • Permit: 適用可能なポリシーが存在し、アクセスを許可する
  • Deny: 適用可能なポリシーが存在し、アクセスを拒否する
  • Indeterminate: エラーが発生し(PIP接続失敗など)、判定不能
  • NotApplicable: 適用可能なポリシーが存在しない(デフォルト拒否の文脈では Deny 相当)

複数のポリシーが競合する場合、ポリシー結合アルゴリズム(Combining Algorithm)で解決します。 代表的なものとして、1つでも Deny があれば全体が Deny になる deny-overrides、 最初に Permit を返したポリシーの結果を採用する first-applicable があります。

OPA(Open Policy Agent)と Rego 言語

OPA(Open Policy Agent) は Styra が開発し、2021年に CNCF Graduated となったポリシーエンジンです。 Netflix・Goldman Sachs・Cloudflare などが本番採用しており、 Kubernetes の Admission Control・API Gateway の認可・マイクロサービス横断のポリシー統一など 幅広い用途で利用されています。

OPA のポリシー記述言語 Rego は、Datalog を起源とする論理型・宣言的言語です。 「何をするか」ではなく「何が true であるか」を記述します。

package abac

# デフォルトはアクセス拒否
default allow = false

# ユーザー属性の定義(実際には PIP から動的取得)
user_attributes := {
  "alice": {"department": "engineering", "security_level": 3},
  "bob":   {"department": "finance",     "security_level": 2},
}

# ABACポリシー: ユーザーの部署とリソースの部署が一致し、
# かつセキュリティレベルが要求レベル以上の場合のみ許可
allow {
  user := user_attributes[input.user]
  user.department == input.resource.department
  user.security_level >= input.required_level
}

# 時間帯制限: 9〜18時のみ許可(Environment属性の活用)
allow {
  user := user_attributes[input.user]
  user.department == "finance"
  input.resource.classification == "confidential"
  input.env.hour >= 9
  input.env.hour < 18
}

OPA のデプロイパターンは主に2つです。サイドカーパターンでは Kubernetes Pod にOPAコンテナを同梱し、 各マイクロサービスがローカルのOPAに問い合わせます。ネットワーク遅延がほぼゼロになります。エージェントパターンでは各ホストにOPAデーモンを常駐させ、 インフラ横断で統一したポリシーを適用します。

OPA の高度な機能として Partial Evaluation(部分評価) があります。 通常の認可は「このユーザーはこのリソースにアクセスできるか?」という問い合わせですが、 部分評価では「このユーザーがアクセスできるリソースの条件は何か?」を逆引きできます。 データベースのクエリフィルタとして活用することで、取得してから絞り込むのではなく 最初から認可済みのデータだけをフェッチする設計が実現します。

Cedar — 形式検証可能なポリシー言語

Cedar は AWS が開発したポリシー言語で、2023年にオープンソース化され、 2026年1月に CNCF Sandbox プロジェクトに加入しました。 Amazon Verified Permissions・Bedrock AgentCore で採用されており、 AWS のサービス基盤に組み込まれた実績を持ちます。

Cedar が既存のポリシー言語と一線を画す点は、Lean 定理証明器による形式検証を設計に組み込んでいることです。 ポリシーの正確性を数学的に証明するVerification-Guided Development(VGD) というアプローチを採用しています。

PARCモデル(Principal/Action/Resource/Context)

Cedar のポリシーは PARC モデル(Principal・Action・Resource・Context)で構造化されます。 XACML の Subject/Object/Action/Environment に対応する Cedar 流の定式化です。

// 基本的な許可ポリシー
permit (
  principal == User::"alice",
  action    == Action::"viewPhoto",
  resource  in Album::"alice_vacation"
);

// コンテキスト条件付きポリシー
permit (
  principal in Group::"finance_team",
  action    == Action::"read",
  resource  in Folder::"confidential_reports"
) when {
  context.ipAddress == "192.168.1.1" &&
  context.mfa_verified == true
};

// 明示的な禁止ポリシー(forbid は permit より優先)
forbid (
  principal,
  action    == Action::"delete",
  resource  in Folder::"audit_logs"
) unless {
  principal in Group::"admins"
};

形式検証と7つの主要定理

Cedar の Lean モデル(897行)と Rust 実装(13,664行)は差分テストで継続的に検証されます。 形式検証で証明された主要定理には以下が含まれます。

  • forbid-trumps-permit: forbid ポリシーが1つでも適用されれば、いくつ permit があっても必ず Deny となる
  • default-deny: 適用可能な permit ポリシーがなければ必ず Deny となる
  • order-independence: ポリシーの評価順序が結果に影響しない
  • validation-soundness: 型検証を通過したポリシーは評価時に型エラーを起こさない

OPA vs Cedar vs XACML — ポリシーエンジン比較

観点XACML 3.0OPA / RegoCedar
標準化OASIS 標準(2013年)CNCF Graduated(2021年)CNCF Sandbox(2026年)
記述言語XMLRego(Datalog派生)Cedar独自言語
学習コスト高(XML冗長・Combining Algorithm)中(論理型に慣れが必要)低〜中(自然言語に近い構文)
形式検証なしOPA Playground / テストLean定理証明(VGD)
ポリシー評価モデルPermit/Deny/Indeterminate/NotApplicabletrue/false(ルールの充足)permit優先→forbidで上書き
主な採用シーンエンタープライズ・規制産業Kubernetes・マイクロサービスAWS サービス・クラウドネイティブ
パフォーマンス中(XML処理オーバーヘッド)高(バンドル最適化)高(Rustネイティブ実装)
水平スケール可(ステートレス PDP)可(サイドカー分散)可(AWS マネージド)

ABAC と RBAC のハイブリッド設計

実際の本番システムで「純粋なABAC」だけを採用しているケースは稀です。 RBAC と ABAC を組み合わせるハイブリッド設計が現実解として広く採用されています。

設計指針はシンプルです。RBAC で粗粒度の役割を定義し、ABAC でコンテキスト条件を付加するという層構造です。 「誰がアクセスできるか」をRBACで大枠を決め、 「いつ・どこから・何の状態のときにアクセスできるか」をABACで絞り込みます。

AWS IAM のハイブリッド実装

AWS IAM はこのハイブリッド設計の最も普及した実例です。 IAM Role(RBAC的)にポリシーをアタッチし、ポリシー内の ConditionブロックでABACのコンテキスト条件を追加します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::confidential-bucket/*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/Department": "Finance",
          "s3:ExistingObjectTag/Classification": "Confidential"
        },
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        },
        "IpAddress": {
          "aws:SourceIp": "192.168.0.0/16"
        }
      }
    }
  ]
}

このポリシーは「Finance 部門タグを持つプリンシパルが、 Confidential タグの付いた S3 オブジェクトに、MFA 認証済みかつ社内 IP からのみアクセスを許可」 という ABAC の4カテゴリ(Subject・Object・Environment)をすべて活用した条件です。 ロールは単一の FinanceDataReader ロール1本のまま、 Condition ブロックで細粒度の制御を実現しています。

ハイブリッド設計の指針

  • RBAC を粗粒度の入り口として使う: 「このロールを持っていなければそもそもポリシー評価に到達しない」という第一関門として機能させる。 PDP の負荷を軽減できます。
  • 環境属性はABACで動的評価する: 時刻・IPアドレス・MFA状態・リスクスコアはリクエスト時点の値であり、事前にロールに組み込めません。 これらはポリシーエンジンのEnvironment属性として評価するのが適切です。
  • ポリシーのテストを自動化する: ABAC ポリシーは組み合わせ爆発が起きやすい。 OPA の opa test コマンドや Cedar のバリデーターを CI/CD パイプラインに組み込み、ポリシー変更のたびに境界条件を自動検証します。
  • PIP の信頼性を設計する: 属性値を提供する PIP(LDAP・DB・リスクエンジン)が単一障害点になります。 PIP 接続失敗時のフォールバック(Indeterminate → Deny)とキャッシュ戦略を明示的に設計します。

理解度チェック

問題 0 / 40%
Q1

XACML アーキテクチャにおいて、属性値を外部データソース(LDAP・データベース等)から取得する役割を担うコンポーネントはどれですか?

キーボード: 1〜4 で選択、Enter で回答