Skip to main content

Cerbosのポリシー

Cerbosのポリシーは、リソースに対するアクセス制御ルールを定義するYAMLまたはJSONファイルです。ここでは、様々な種類のポリシーとその定義方法について説明します。

ポリシーの種類 #

Cerbosでは、主に以下の種類のポリシーがあります:

  1. リソースポリシー - 特定の種類のリソースに対するアクセスルールを定義
  2. プリンシパルポリシー - 特定のプリンシパルに対するアクセスルールを定義
  3. 派生ロール - リソースやプリンシパルの属性に基づいて動的にロールを割り当てるルールを定義
  4. スコープポリシー - 特定のスコープ内でのアクセスルールを定義

リソースポリシー #

リソースポリシーは、特定の種類のリソースに対するアクセスルールを定義します。

---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  resource: "document:object"
  rules:
    - actions: ["view"]
      effect: EFFECT_ALLOW
      roles: ["user", "admin"]
      
    - actions: ["edit", "delete"]
      effect: EFFECT_ALLOW
      roles: ["admin"]
      
    - actions: ["share"]
      effect: EFFECT_ALLOW
      roles: ["user", "admin"]
      condition:
        match:
          expr: request.resource.attr.owner == request.principal.id

このポリシーでは:

  • useradminロールはdocument:objectリソースを表示できる
  • adminロールのみが編集と削除ができる
  • リソースの所有者である場合、useradminロールは共有できる

プリンシパルポリシー #

プリンシパルポリシーは、特定のプリンシパル(ユーザーやサービス)に対するアクセスルールを定義します。

---
apiVersion: api.cerbos.dev/v1
principalPolicy:
  principal: "john@example.com"
  version: "default"
  rules:
    - resource: "document:object"
      actions: ["view", "edit", "delete"]
      effect: EFFECT_ALLOW
      
    - resource: "report:object"
      actions: ["view"]
      effect: EFFECT_ALLOW

このポリシーでは、john@example.comというプリンシパルに対して:

  • document:objectリソースの表示、編集、削除を許可
  • report:objectリソースの表示のみを許可

派生ロール #

派生ロールは、リソースやプリンシパルの属性に基づいて動的にロールを割り当てるルールを定義します。

---
apiVersion: api.cerbos.dev/v1
derivedRoles:
  name: "common_roles"
  definitions:
    - name: "owner"
      parentRoles: ["user"]
      condition:
        match:
          expr: request.resource.attr.owner == request.principal.id
          
    - name: "team_member"
      parentRoles: ["user"]
      condition:
        match:
          expr: request.principal.attr.team == request.resource.attr.team

このポリシーでは:

  • リソースのowner属性がプリンシパルのIDと一致する場合、userロールを持つプリンシパルにownerロールを割り当てる
  • プリンシパルのteam属性がリソースのteam属性と一致する場合、userロールを持つプリンシパルにteam_memberロールを割り当てる

リソースポリシーで派生ロールを使用するには、以下のようにimportDerivedRolesを指定します:

---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  importDerivedRoles:
    - "common_roles"
  resource: "document:object"
  rules:
    - actions: ["edit", "delete"]
      effect: EFFECT_ALLOW
      derivedRoles: ["owner"]

条件 #

条件を使用すると、より細かいアクセス制御ルールを定義できます。条件は、Common Expression Language(CEL)を使用して記述します。

---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  resource: "document:object"
  rules:
    - actions: ["view"]
      effect: EFFECT_ALLOW
      roles: ["user"]
      condition:
        match:
          expr: request.resource.attr.status == "published" || request.resource.attr.owner == request.principal.id

このポリシーでは、userロールは以下の条件を満たす場合にdocument:objectリソースを表示できます:

  • リソースのステータスが「published」である、または
  • リソースの所有者がプリンシパルと一致する

変数と定数 #

変数と定数を使用すると、ポリシー内で再利用可能な値を定義できます。

---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  resource: "document:object"
  variables:
    - name: "isOwner"
      expr: "request.resource.attr.owner == request.principal.id"
  rules:
    - actions: ["edit", "delete"]
      effect: EFFECT_ALLOW
      roles: ["user"]
      condition:
        match:
          expr: variables.isOwner

スキーマ #

スキーマを定義することで、リソースやプリンシパルの属性の型を指定し、ポリシーの記述ミスを防ぐことができます。

---
apiVersion: api.cerbos.dev/v1
schema:
  id: "document:object"
  version: "1.0"
  definitions:
    document:
      type: "object"
      properties:
        owner:
          type: "string"
        status:
          type: "string"
          enum: ["draft", "published", "archived"]
        team:
          type: "string"
      required:
        - "owner"
        - "status"

ポリシーのテスト #

Cerbosには、ポリシーをテストするための機能が組み込まれています。テストケースは、YAMLファイルで定義します。

---
apiVersion: api.cerbos.dev/v1
policyTest:
  name: "Test document access"
  description: "Test access to document resources"
  principal:
    id: "john"
    roles:
      - "user"
    attr:
      team: "engineering"
  resources:
    - resource:
        kind: "document:object"
        id: "doc123"
        attr:
          owner: "john"
          status: "published"
          team: "engineering"
      actions:
        - action: "view"
          expected: "EFFECT_ALLOW"
        - action: "edit"
          expected: "EFFECT_ALLOW"
        - action: "delete"
          expected: "EFFECT_ALLOW"

ポリシーリポジトリのレイアウト #

Cerbosは、ポリシーリポジトリに特定のディレクトリレイアウトを期待します。

.
├── _schemas
│   ├── principal.json
│   └── resources
│       ├── document.json
│       └── report.json
├── derived_roles
│   ├── common_roles.yaml
│   └── team_roles.yaml
├── principal_policies
│   └── john.yaml
└── resource_policies
    ├── document.yaml
    ├── document_test.yaml
    ├── report.yaml
    └── report_test.yaml
  • _schemasディレクトリには、スキーマファイルを配置します。
  • derived_rolesディレクトリには、派生ロールの定義を配置します。
  • principal_policiesディレクトリには、プリンシパルポリシーを配置します。
  • resource_policiesディレクトリには、リソースポリシーとそのテストを配置します。

ベストプラクティス #

ポリシーのモデリング #

Cerbosでは、アクセスルールは常にリソース指向であり、ポリシーはシステム内のこれらのリソースにマッピングされます。ポリシーのモデリング方法は自由であり、アクション主導、ロール主導、属性主導、またはそれらの組み合わせなど、様々なアプローチが可能です。

派生ロールの活用 #

派生ロールを活用することで、ポリシーの記述がシンプルになります。例えば、「所有者」や「チームメンバー」などの動的なロールを定義し、それらに基づいてアクセスルールを定義することができます。

条件の使用 #

条件を使用して、より細かいアクセス制御ルールを定義できます。例えば、リソースの状態、時間帯、IPアドレスなどに基づいてアクセスを制限することができます。

スキーマの定義 #

スキーマを定義することで、ポリシーの記述ミスを防ぎ、より堅牢なアクセス制御システムを構築できます。

[出典: https://docs.cerbos.dev/cerbos/latest/policies/]