---
title: "Casbinとは：モデルとポリシーを分ける認可ライブラリの仕組みとPythonでのRBAC実装"
url: "https://www.issoh.co.jp/tech/details/19048/"
published: 2026-10-29
updated: 2026-10-29
categories: ["セキュリティ"]
publisher: "株式会社一創"
---

# Casbinとは：モデルとポリシーを分ける認可ライブラリの仕組みとPythonでのRBAC実装

Casbinは、「誰が・何に・何をしてよいか」の判定をアプリケーションの外に出すための、オープンソースの認可ライブラリです。ルールの形を書くモデルファイルと、ルールの中身を書くポリシーを分けて持つので、権限を追加する際にコードを修正する必要はありません。この記事では、PERMモデルの4セクションの読み方、pycasbinでRBACを動かすmodel.confとPythonコード、ABACやマルチテナントへの広げ方を、設定例付きで解説します。後半では、本番で詰まりやすいDB保存と複数台の同期、OPAやCedarとの使い分けまで判断します。

## まとめ：Casbinは認可判定だけを受け持ちルールの形と中身を分けるライブラリ

Casbinが答えるのは「この利用者はこの操作をしてよいか」の1点です。ログインやパスワードの確認は受け持たないため、認証は別の仕組みで済ませ、その結果の利用者IDをCasbinに渡す構成になります。

手を動かす順番は次のとおりです。まずmodel.confにRBACの形を書き、policy.csvにロールと権限を並べ、`enforce()`を呼んで判定を確かめます。動いたら、ポリシーの置き場をファイルからデータベースへ移します。

採用してよいのは、認可を1つのアプリケーションか少数のサービスの中で完結させたい場合です。認可の判断を全社の複数言語・複数サービスで共有したいなら、OPAやCedarのような独立したポリシーエンジンのほうが合います。

## Casbinの正体と認証を扱わない認可ライブラリとしての守備範囲

[Casbinの公式概要](https://casbin.apache.org/docs/overview/)は、自らを「リソースへの制御されたアクセスが必要なアプリケーション向けの認可ライブラリ」と説明しています。ACL・RBAC・ABACに加え、ReBACやドメイン付きRBACなど複数のアクセス制御モデルを、同じ書式のモデルファイルで表現できる点が特徴です。

### Apache Casbinへの移管と2026年10月時点の各言語実装の版番号

Casbinは2026年2月7日に[Apache Software FoundationのIncubator](https://incubator.apache.org/projects/casbin.html)へ入り、公式サイトもcasbin.orgからcasbin.apache.orgへ移りました。GitHubのリポジトリもapache配下に移っています。ライセンスはApache License 2.0です。

| 実装                   | 2026年10月29日時点の最新版 | 公開日        |
| -------------------- | ----------------- | ---------- |
| Go（本家）               | v3.11.0           | 2026年8月20日 |
| Python（pycasbin）     | 2.8.0             | 2026年2月2日  |
| Node.js（node-casbin） | 5.51.1            | 2026年6月25日 |
| Java（jCasbin）        | 1.99.0            | 2026年2月12日 |

Go版は[v3.11.0のリリースページ](https://github.com/apache/casbin/releases/tag/v3.11.0)で確認できます。各実装は機能の揃い方に差があり、公式も「完全な統一はまだ達成していない」と書いています。Go以外を使うなら、必要な関数がその言語版にあるかを先に確かめてください。

### Casbinが受け持つ認可判定と受け持たないログイン・ユーザー管理の線引き

公式概要には、Casbinがしないことも明記されています。ユーザー名とパスワードの確認、ユーザーやロールの一覧の管理、パスワードの保存の3つです。RBACで保持するのは「ユーザーとロールの対応」だけです。

実務では、ログインをOAuthやOpenID Connectの仕組みに任せ、受け取ったトークンから利用者IDを取り出してCasbinに渡します。認証と認可の分担は[OAuth 2.0の仕組みと認証との違い](https://www.issoh.co.jp/tech/details/8369/)で整理しています。ユーザー情報の正本は自社のユーザーテーブルかIdPに置き、Casbinには持たせません。

## PERMモデルの4セクションとポリシーファイルが判定を組み立てる仕組み

CasbinはPERM（Policy・Effect・Request・Matchers）という考え方で、アクセス制御モデルを設定ファイルに落とし込みます。モデルを差し替えれば、同じ`enforce()`呼び出しのままACLからRBACへ切り替えられます。

### PERMモデルの4要素とrole\_definitionによるロール定義の役割

[モデル構文のドキュメント](https://casbin.apache.org/docs/syntax-for-models/)によると、モデルファイルには`[request_definition]`・`[policy_definition]`・`[policy_effect]`・`[matchers]`の4セクションが必須です。RBACを使うときだけ`[role_definition]`を足します。

- request\_definition：`enforce()`に渡す引数の並び。例は`r = sub, obj, act`
- policy\_definition：ポリシー1行の列の意味。例は`p = sub, obj, act`
- matchers：リクエストとポリシー1行を突き合わせる式
- policy\_effect：一致した行が複数あるときの最終判定の決め方
- role\_definition：`g = _, _`でユーザーとロールの継承関係を宣言

matcherには`&&`や`||`が使えます。公式は、軽い比較を前に、ロール検索のような重い条件を後ろに置く順序を勧めています。

### policy\_effectの5種類の式とallowとdenyがぶつかったときの決まり方

policy\_effectに書ける式は決まっており、公式は「独自の式は現在の実装ではサポートしない」としています。選べるのは次の5種類です。

```
# 1. allow-override
e = some(where (p.eft == allow))
# 2. deny-override
e = !some(where (p.eft == deny))
# 3. allow-and-deny
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))
# 4. priority
e = priority(p.eft) || deny
# 5. subjectPriority
e = subjectPriority(p.eft)
```

| 名前              | 判定の決まり方                |
| --------------- | ---------------------- |
| allow-override  | allowが1行でも一致すれば許可      |
| deny-override   | denyが1行も一致しなければ許可      |
| allow-and-deny  | allowがあり、denyが無いときだけ許可 |
| priority        | 優先度が高い行の結果を採用          |
| subjectPriority | ロール階層の深さで優先度を決める       |

業務システムでは3行目のallow-and-denyを選ぶ場面が多くなります。「経理ロールには請求書の閲覧を許すが、退職予定者には拒否する」のような例外をdenyの1行で足せるからです。`p.eft`列を省略した行はallow扱いになります。

## PythonでRBACを動かす：pycasbinの導入からAPIパスの判定まで

ここからは、注文APIに管理者と担当者の2つのロールを設ける例で、model.conf・policy.csv・Pythonコードを順に書きます。API名と関数の挙動は、pycasbin 2.8.0のソースに沿って記述しています。

### pip install pycasbinでの導入と旧パッケージ名casbinとの取り違え

Python版は[PyPIのpycasbin](https://pypi.org/project/pycasbin/)として配布されています。旧名の`casbin`は1.43.0（2025年5月10日）で更新が止まり、2024年10月25日の1.36.3以降はpycasbinの名前で版を重ねています。import名は今も`casbin`のままです。

```
pip install pycasbin==2.8.0
python -c "import casbin; print(casbin.__file__)"
```

落とし穴は周辺パッケージ側にあります。SQLAlchemyアダプタ1.4.0は依存先を旧名の`casbin>=0.8.1`と宣言しているため、一緒に入れると旧パッケージも入り得ます。導入後に`pip list`でcasbinとpycasbinが両方入っていないかを確認してください。

### model.confとpolicy.csvを書いてロール経由でAPIパスを認可する例

モデルはRBACに、URLのパターン一致を足した形にします。`keyMatch2`は`:id`や`*`を含むRESTのパスと照合する組み込み関数です。1つ目をmodel.conf、2つ目をpolicy.csvとして保存します。

```
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act
```

```
p, role_admin, /api/orders/*, GET
p, role_admin, /api/orders/*, DELETE
p, role_staff, /api/orders/:id, GET
g, alice, role_admin
g, bob, role_staff
```

`p`の行が「ロールに許す操作」、`g`の行が「ユーザーへのロール付与」です。ロール名に`role_`の接頭辞を付けているのは、[RBACのドキュメント](https://casbin.apache.org/docs/rbac/)が「ユーザーとロールに同じ名前を使わない」よう求めているためです。同名だとCasbinは両者を区別できません。

### Enforcerで判定を呼び出しロールを追加するPythonコードと戻り値

Enforcerにモデルとポリシーを読ませ、`enforce()`に利用者・パス・HTTPメソッドを渡します。戻り値はTrueかFalseです。

```
import casbin

e = casbin.Enforcer("model.conf", "policy.csv")

print(e.enforce("alice", "/api/orders/42", "DELETE"))  # True（role_admin）
print(e.enforce("bob", "/api/orders/42", "GET"))       # True（role_staff）
print(e.enforce("bob", "/api/orders/42", "DELETE"))    # False

# 新しい担当者にロールを付与する（ファイル運用ではメモリ上の変更）
e.add_role_for_user("carol", "role_staff")
print(e.enforce("carol", "/api/orders/7", "GET"))      # True

# ロール経由で継承した権限まで含めて一覧する
print(e.get_implicit_permissions_for_user("bob"))
```

`get_roles_for_user()`は直接付与したロールだけを返し、`get_implicit_roles_for_user()`は階層をたどった結果を返します。監査用に「この人は実際に何ができるか」を出すなら後者を使います。ロール階層の深さは既定で10段が上限です。

Webフレームワークに組み込むときは、ミドルウェアで全リクエストに`enforce()`を通し、Falseなら403を返します。個別のハンドラに判定を書き散らすと、付け忘れた1本から[IDORや権限昇格といった認可バイパス](https://www.issoh.co.jp/tech/details/16399/)が起きます。

## ABACとマルチテナントへ広げるときのeval関数とドメイン付きRBAC

ロールだけでは表しきれない条件は、属性で判定するABACか、テナントごとにロールを分けるドメイン付きRBACで受けます。どちらもモデルの書き換えだけで対応できます。

### 属性をリクエストに渡してeval()で役職レベルを判定する書き方

[ABACのドキュメント](https://casbin.apache.org/docs/abac/)では、matcher内で`r.sub.Age`のようにリクエストの属性を参照します。条件式をポリシー側に置くときは`eval()`を使います。属性を参照できるのはリクエスト側だけで、ポリシーの列には構造体を入れられません。次の3つをabac\_model.conf・abac\_policy.csv・Pythonコードとして使います。

```
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub_rule, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = eval(p.sub_rule) && keyMatch2(r.obj, p.obj) && r.act == p.act
```

```
p, r.sub.level >= 3, /api/invoices/:id/approve, POST
p, r.sub.level >= 1, /api/invoices/:id, GET
```

```
from dataclasses import dataclass
import casbin

@dataclass
class User:
    name: str
    level: int

e = casbin.Enforcer("abac_model.conf", "abac_policy.csv")
print(e.enforce(User("sato", 3), "/api/invoices/10/approve", "POST"))    # True
print(e.enforce(User("suzuki", 1), "/api/invoices/10/approve", "POST"))  # False
```

役職レベルや部署のような属性は、判定のたびにアプリ側で最新値を引いて渡します。属性条件を増やす前に、RBACとの役割分担を[ABACの仕組みとRBACとの使い分け](https://www.issoh.co.jp/tech/details/16407/)で確認しておくと、ポリシーが散らかりません。

### g = \_, \_, \_で同じ利用者にテナントごとの別ロールを割り当てる方法

SaaSのように1人が複数の会社（テナント）に属する場合は、[ドメイン付きRBAC](https://casbin.apache.org/docs/rbac-with-domains/)を使います。role\_definitionの引数を3つにし、3つ目にテナントを入れます。モデルとポリシーの組は次のとおりです。

```
[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act

[role_definition]
g = _, _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
```

```
p, admin, tenant1, data1, read
g, alice, admin, tenant1
g, alice, user, tenant2
```

aliceはtenant1では管理者、tenant2では一般利用者として判定されます。テナントIDをリクエストから取るときは、URLやヘッダーの値をそのまま使わず、ログイン中の利用者が本当にそのテナントに属するかをアプリ側で照合してから渡してください。

## 本番運用で詰まる3箇所：DBアダプタ・複数台の同期・ルール数の上限

ファイルで動いたCasbinを本番へ出すと、ポリシーの置き場・サーバー間の整合・ルール数の3つで設計が要ります。ここを決めずに出すと、権限を外したのに一部のサーバーでは操作できる、という事故になります。

### SQLAlchemyアダプタでポリシーをDBに置くときのAutoSaveの挙動

Casbinはポリシーの読み書きを[アダプタ](https://casbin.apache.org/docs/adapters/)に任せます。Pythonでは[SQLAlchemyアダプタ](https://github.com/apache/casbin-python-sqlalchemy-adapter)のほか、Django ORMやPeewee用などが用意されています。

```
import os
import casbin
import casbin_sqlalchemy_adapter

# 接続文字列は環境変数から渡す（例: SQLAlchemy形式のPostgreSQL URL）
adapter = casbin_sqlalchemy_adapter.Adapter(os.environ["AUTHZ_DATABASE_URL"])
e = casbin.Enforcer("model.conf", adapter)

# AutoSave 対応アダプタでは、この1行がそのままDBの行追加になる
e.add_policy("role_staff", "/api/customers/:id", "GET")
```

AutoSaveに対応したアダプタでは、`add_policy()`のような個別の変更がその場でDBへ反映され、既定で有効です。一方の`save_policy()`は保存先を消して全行を書き直すため、ルールが多い環境で呼ぶと遅くなります。公式表ではMongoEngineとPymongoのアダプタがAutoSave非対応です。

### 複数台構成でWatcherを入れないと権限の剥奪が他のサーバーに届かない問題

Enforcerは起動時にポリシーをメモリへ読み込みます。サーバーが2台以上あると、1台で権限を外しても、残りのサーバーのメモリには古いルールが残ったままです。

これを防ぐのが[Watcher](https://casbin.apache.org/docs/watchers/)です。ポリシーを変えたEnforcerがRedisやEtcd、PostgreSQLなどを通じて他のインスタンスへ通知し、受け取った側がポリシーを読み直します。Python用にはRedis・Etcd・PostgreSQL・RabbitMQのWatcherがあります。ロードバランサーの後ろに2台以上置くなら、Watcherは最初から入れてください。

### 数百万ルール規模での性能劣化とテナント単位のポリシー部分読み込み

[性能のドキュメント](https://casbin.apache.org/docs/performance/)は、ルールが数百万件に達すると判定と読み込みの両方が遅くなり得ること、単一のEnforcerで毎秒1万件超のリクエストは目安を超えることを挙げています。

対策の優先順位は、まずユーザー個人ではなくロールに権限を付けてルール数を減らすことです。公式はテナントあたり100件未満を目安にしています。それでも多いときは、[ポリシーの部分読み込み](https://casbin.apache.org/docs/policy-subset-loading/)でテナント単位に必要な行だけを読み込みます。

## Casbinを採用する条件とOPA・Cedarを選ぶべき場面の判断

認可を外に出す手段はCasbinだけではありません。比較の相手は、ポリシー言語Regoで書く[Open Policy Agent（OPA）](https://www.openpolicyagent.org/docs)と、AWSが開発した[Cedar](https://cedarpolicy.com/)です。

### アプリケーション内で完結する認可にCasbinを採用してよい条件

次の条件に当てはまるなら、Casbinを選んで構いません。

- 認可を判定するのが1つのアプリケーションか、同じ言語で書いた少数のサービスである
- 権限の大半がRBACで表せ、属性条件は一部の操作に限られる
- 判定をネットワーク越しにせず、プロセス内のライブラリ呼び出しで済ませたい
- ポリシーを自社のデータベースに置き、管理画面から追加・削除したい

4つ目は、Casbinの管理APIがそのまま管理画面の裏側になる点で、ほかの選択肢より実装量が少なく済みます。権限の画面設計からAPIの認可まで一体で作る場合は、[API開発・システム連携](https://www.issoh.co.jp/service/system/api/)の範囲として相談いただけます。

### OPAやCedarを選ぶべき場面とCasbinを入れなくてよい小規模な場合

Casbinを選ばないほうがよい場面もはっきりしています。Go・Java・Pythonなど複数言語のサービスが同じ認可ルールを共有する場合、言語版ごとの機能差が運用の負担になります。この場合に合うのは、PDPを別プロセスに立てられるOPAです。ポリシーの静的検証や、AWSのAmazon Verified Permissionsとの連携を重視するならCedarです。

逆に、ロールが「管理者」と「一般」の2つしかない社内ツールなら、Casbinは過剰です。フレームワーク標準の権限機能やデコレータで十分で、モデルファイルの学習と保守のほうが重くなります。目安は、ロールが5つを超えるか、テナントが分かれるかです。ロール設計そのものの考え方は[RBACの仕組みと導入判断](https://www.issoh.co.jp/tech/details/6488/)にまとめています。

## よくある質問

Casbinを検討するときによく出る疑問に、公式ドキュメントの記述をもとに答えます。

### Casbinはログイン機能も提供しますか？

提供しません。公式概要は、ユーザー名とパスワードの確認、ユーザーやロールの一覧管理、パスワードの保存をCasbinの対象外としています。ログインはOAuth 2.0やOpenID Connect、あるいはフレームワークの認証機能で行い、確定した利用者IDを`enforce()`の第1引数に渡す構成にします。Casbinが保存するのは、ユーザーとロールの対応、ロールと権限の対応だけです。

### pip install casbinとpip install pycasbinはどちらが正しいですか？

2026年10月時点で更新が続いているのはpycasbinです。PyPIの旧名casbinは1.43.0（2025年5月10日）で止まり、pycasbinは2.8.0（2026年2月2日）まで進んでいます。どちらも`import casbin`で読み込むため、両方が入ると古いほうを読む恐れがあります。アダプタが旧名に依存している場合もあるので、導入後に`pip list`で確認してください。

### Casbinのポリシーはどのデータベースに保存できますか？

アダプタを差し替えて、MySQL・PostgreSQL・SQLite・MongoDB・Redisなどに保存できます。Pythonで使えるものとして公式の一覧に載っているのは、SQLAlchemy・Django ORM・Peewee・Tortoise ORM・SQLModel用のアダプタです。既存のORMに合わせて選ぶのが手堅く、管理画面から権限を編集するならAutoSave対応のアダプタを選ぶと、変更がその場でDBに反映されます。

### CasbinとOPAはどちらを選べばよいですか？

判定をプロセス内で済ませ、ポリシーを自社DBで管理したいならCasbinが向きます。複数言語のサービスやKubernetesの受け入れ制御など、組織全体で同じポリシーを共有したいならOPAが候補です。OPAはRegoという専用言語を覚える必要があり、判定のたびに別プロセスへ問い合わせる構成では応答遅延の設計も要ります。1つの業務システムの認可ならCasbinから始めるのが現実的です。

### Casbinのモデルを試しに動かす方法はありますか？

公式サイトの[オンラインエディタ](https://casbin.apache.org/editor/)で、モデルとポリシーとリクエストを貼り付けて判定結果を確かめられます。手元で試すなら、この記事のmodel.confとpolicy.csvをそのまま保存し、`pip install pycasbin`のあとにPythonコードを実行する手順です。本番のポリシーを変える前には、想定するリクエストと期待値の組を単体テストに書いておくと、ルール変更の影響を機械的に確かめられます。

## 関連記事

- [RBACとは？ロールベースアクセス制御の仕組みと導入判断を実装視点で解説](https://www.issoh.co.jp/tech/details/6488/)：Casbinで書くロール設計の前提になる考え方です。
- [ABACとは？属性ベースアクセス制御の仕組みとRBACとの使い分けを実装視点で解説](https://www.issoh.co.jp/tech/details/16407/)：eval()で属性条件を足す前に決めておく役割分担です。
- [認可バイパスとは？IDOR・権限昇格の仕組みとサーバ側で止める実装対策を解説](https://www.issoh.co.jp/tech/details/16399/)：認可の付け忘れが招く攻撃と直し方です。
- [Spring Securityとは？認証・認可の仕組みと基本設定を7.1で解説](https://www.issoh.co.jp/tech/details/2465/)：Javaでフレームワーク標準の認可を使う場合の比較対象です。
- [IDおよびアクセス管理（IAM）とは：ID管理と認可の違い、企業IAM基盤の構成と導入判断](https://www.issoh.co.jp/column/details/18706/)：Casbinの外側に置くID管理の全体像です。

---

出典: [Casbinとは：モデルとポリシーを分ける認可ライブラリの仕組みとPythonでのRBAC実装](<https://www.issoh.co.jp/tech/details/19048/>)（株式会社一創）
