주요 콘텐츠로 건너뛰기

Adapters

Casbin handles policy storage through adapters that function as middleware. Adapters enable loading policies from storage via LoadPolicy() and persisting them with SavePolicy(). To maintain a lightweight core library, adapter implementations are maintained separately.

지원되는 어댑터

Below is a comprehensive list of available Casbin adapters. Third-party contributions are welcome—contact us to have your adapter included:

Adapter Type Author AutoSave Description
File Adapter (built-in) File Casbin For .CSV (Comma-Separated Values) files
Filtered File Adapter (built-in) File @faceless-saint For .CSV (Comma-Separated Values) files with policy subset loading support
SQL Adapter SQL @Blank-Xu MySQL, PostgreSQL, SQL Server, SQLite3 are supported in master branch and Oracle is supported in oracle branch by database/sql
Xorm Adapter ORM Casbin MySQL, PostgreSQL, TiDB, SQLite, SQL Server, Oracle are supported by Xorm
GORM Adapter ORM Casbin MySQL, PostgreSQL, Sqlite3, SQL Server are supported by GORM
GORM Adapter Ex ORM Casbin MySQL, PostgreSQL, Sqlite3, SQL Server are supported by GORM
Ent Adapter ORM Casbin MySQL, MariaDB, PostgreSQL, SQLite, Gremlin-based graph databases are supported by ent ORM
Beego ORM Adapter ORM Casbin MySQL, PostgreSQL, Sqlite3 are supported by Beego ORM
SQLX Adapter ORM @memwey MySQL, PostgreSQL, SQLite, Oracle are supported by SQLX
Sqlx Adapter ORM @Blank-Xu MySQL, PostgreSQL, SQL Server, SQLite3 are supported in master branch and Oracle is supported in oracle branch by sqlx
GF ORM Adapter ORM @vance-liu MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
GoFrame ORM Adapter ORM @kotlin2018 MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
gf-adapter ORM @zcyc MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
Gdb Adapter ORM @jxo-me MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
GoFrame V2 Adapter ORM @hailaz MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
Bun Adapter ORM @JunNishimura MySQL, SQLite, PostgreSQL, SQL Server are supported by Bun ORM
Filtered PostgreSQL Adapter SQL Casbin For PostgreSQL
Filtered pgx Adapter SQL @pckhoi PostgreSQL is supported by pgx
Pgx Adapter SQL @gtoxlili PostgreSQL is supported by pgx, supports customizable column count
PostgreSQL Adapter SQL @cychiuae For PostgreSQL
RQLite Adapter SQL EDOMO Systems For RQLite
MongoDB Adapter NoSQL Casbin For MongoDB based on MongoDB Go Driver
RethinkDB Adapter NoSQL @adityapandey9 For RethinkDB
Cassandra Adapter NoSQL Casbin For Apache Cassandra DB
DynamoDB Adapter NoSQL HOOQ For Amazon DynamoDB
Dynacasbin NoSQL NewbMiao For Amazon DynamoDB
ArangoDB Adapter NoSQL @adamwasila For ArangoDB
Amazon S3 Adapter Cloud Soluto For Minio and Amazon S3
Go CDK Adapter Cloud @bartventer Adapter based on Go Cloud Dev Kit that supports: Amazon DynamoDB, Azure CosmosDB, GCP Firestore, MongoDB, In-Memory
Azure Cosmos DB Adapter Cloud @spacycoder For Microsoft Azure Cosmos DB
GCP Firestore Adapter Cloud @reedom For Google Cloud Platform Firestore
GCP Cloud Storage Adapter Cloud qurami For Google Cloud Platform Cloud Storage
GCP Cloud Spanner Adapter Cloud @flowerinthenight For Google Cloud Platform Cloud Spanner
Consul Adapter KV store @ankitm123 For HashiCorp Consul
Redis Adapter (Redigo) KV store Casbin For Redis
Redis Adapter (go-redis) KV store @mlsen For Redis
Etcd Adapter KV store @sebastianliu For etcd
BoltDB Adapter KV store @speza For Bolt
Bolt Adapter KV store @wirepair For Bolt
BadgerDB Adapter KV store @inits For BadgerDB
Protobuf Adapter Stream Casbin For Google Protocol Buffers
JSON Adapter String Casbin For JSON
String Adapter String @qiangmzsx For String
HTTP File Adapter HTTP @h4ckedneko For http.FileSystem
FileSystem Adapter File @naucon For fs.FS and embed.FS
NATS JetStream Adapter KV store grepplabs For NATS JetStream
Kubernetes Adapter Cloud grepplabs For Kubernetes
노트
  1. When you call casbin.NewEnforcer() with an adapter (explicit or implicit), policies load automatically.
  2. Call e.LoadPolicy() to refresh policies from storage.
  3. Without Auto-Save support, adapters cannot persist policy changes automatically when you modify policies. Call SavePolicy() manually to persist all rules.

예시

Several adapter usage examples follow:

파일 어댑터 (내장형)

Initialize an enforcer using the built-in file adapter:

import "github.com/casbin/casbin/v3"

e := casbin.NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")

Equivalent alternative:

import (
"github.com/casbin/casbin/v3"
fileadapter "github.com/casbin/casbin/v3/persist/file-adapter"
)

a := fileadapter.NewAdapter("examples/basic_policy.csv")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

MySQL 어댑터

Initialize an enforcer using a MySQL database connection at 127.0.0.1:3306 with root user and no password:

import (
"github.com/casbin/casbin/v3"
"github.com/casbin/mysql-adapter"
)

a := mysqladapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

자체 저장소 어댑터 사용

Integrate a custom adapter:

import (
"github.com/casbin/casbin/v3"
"github.com/your-username/your-repo"
)

a := yourpackage.NewAdapter(params)
e := casbin.NewEnforcer("examples/basic_model.conf", a)

다른 어댑터 간에 마이그레이션/변환

To migrate policies from adapter A to adapter B:

1.A에서 메모리로 정책 로드

e, _ := NewEnforcer(m, A)

또는

e.SetAdapter(A)
e.LoadPolicy()

2.Switch from adapter A to B

e.SetAdapter(B)

3.메모리에서 B로 정책 저장

e.SavePolicy()

런타임에 로드/저장

Reload models and policies or persist policy changes after initialization:

// Reload the model from the model CONF file.
e.LoadModel()

// Reload the policy from file/database.
e.LoadPolicy()

// Save the current policy (usually after changed with Casbin API) back to file/database.
e.SavePolicy()

AutoSave

Adapters with Auto-Save capability can persist individual policy changes directly to storage without a full save operation. This differs from SavePolicy(), which wipes storage and rewrites all policies, potentially causing performance issues with large policy sets.

When an adapter supports Auto-Save, control this behavior via Enforcer.EnableAutoSave(). This option defaults to enabled for compatible adapters.

노트
  1. Auto-Save is an optional feature. Adapters may implement it or not.
  2. Auto-Save only functions when the enforcer's adapter supports it.
  3. Check the AutoSave column in the adapter list above to determine support.

Auto-Save usage example:

import (
"github.com/casbin/casbin/v3"
"github.com/casbin/xorm-adapter"
_ "github.com/go-sql-driver/mysql"
)

// AutoSave is enabled by default when using compatible adapters with enforcers.
a := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

// Disable AutoSave.
e.EnableAutoSave(false)

// Policy changes affect only the in-memory enforcer,
// not the storage.
e.AddPolicy(...)
e.RemovePolicy(...)

// Enable AutoSave.
e.EnableAutoSave(true)

// Policy changes now persist to storage
// in addition to updating the in-memory enforcer.
e.AddPolicy(...)
e.RemovePolicy(...)

Additional examples: https://github.com/casbin/xorm-adapter/blob/master/adapter_test.go

어댑터 작성 방법

Implement the Adapter interface with at least two required methods: LoadPolicy(model model.Model) error and SavePolicy(model model.Model) error.

Three optional methods enable Auto-Save support.

메서드유형설명
LoadPolicy()필수저장소에서 모든 정책 규칙을 로드합니다
SavePolicy()필수모든 정책 규칙을 저장소에 저장합니다
AddPolicy()선택저장소에 정책 규칙을 추가합니다
RemovePolicy()선택저장소에서 정책 규칙을 제거하십시오
RemoveFilteredPolicy()선택 사항필터와 일치하는 정책 규칙을 저장소에서 제거하십시오
노트

When an adapter lacks Auto-Save support, provide empty implementations for the three optional methods. Golang example:

// AddPolicy adds a policy rule to the storage.
func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error {
return errors.New("not implemented")
}

// RemovePolicy removes a policy rule from the storage.
func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
return errors.New("not implemented")
}

// RemoveFilteredPolicy removes policy rules that match the filter from the storage.
func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error {
return errors.New("not implemented")
}

Casbin enforcers ignore the "not implemented" error when calling these optional methods.

Adapter implementation requirements:

  • 데이터 구조. Support reading at minimum six columns.
  • 데이터베이스 이름. Default to casbin.
  • 테이블 이름. Default to casbin_rule.
  • Ptype 열. Name as ptype (not p_type or Ptype).
  • Table definition: (id int primary key, ptype varchar, v0 varchar, v1 varchar, v2 varchar, v3 varchar, v4 varchar, v5 varchar).
  • Unique key index: Build on columns ptype,v0,v1,v2,v3,v4,v5.
  • LoadFilteredPolicy accepts a filter parameter structured like this:
{
"p": ["", "domain1"],
"g": ["", "", "domain1"]
}

데이터베이스를 생성할 책임이 누구인가요?

By convention, adapters should automatically create a casbin database if it doesn't exist and use it for policy storage. Reference implementation: https://github.com/casbin/xorm-adapter

Update Adapter

The UpdateAdapter interface extends the basic Adapter interface to enable direct policy updates in storage. This approach is more efficient than the remove-and-add sequence when modifying existing rules.

Adapters implementing UpdateAdapter provide these methods:

MethodTypeDescription
UpdatePolicy()optionalUpdate a single policy rule in the storage
UpdatePolicies()optionalUpdate multiple policy rules in the storage
UpdateFilteredPolicies()optionalUpdate policy rules that match the filter in the storage

예시

Update adapter usage:

import (
"github.com/casbin/casbin/v3"
"github.com/casbin/gorm-adapter/v3"
)

a, _ := gormadapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/")
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)

// Update a single policy
// Change: p, alice, data1, read -> p, alice, data1, write
e.UpdatePolicy(
[]string{"alice", "data1", "read"},
[]string{"alice", "data1", "write"},
)

// Update multiple policies at once
e.UpdatePolicies(
[][]string{{"alice", "data1", "write"}, {"bob", "data2", "read"}},
[][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}},
)

// Update all policies matching a filter
e.UpdateFilteredPolicies(
[][]string{{"alice", "data1", "write"}},
0,
"alice", "data1", "read",
)

How to write an update adapter

To implement UpdateAdapter, add the update methods to your basic Adapter implementation:

// UpdatePolicy updates a policy rule from storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdatePolicy(sec string, ptype string, oldRule, newRule []string) error {
// Update the policy in storage
// SQL example: UPDATE casbin_rule SET v0=?, v1=?, v2=? WHERE ptype=? AND v0=? AND v1=? AND v2=?
return nil
}

// UpdatePolicies updates multiple policy rules in the storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdatePolicies(sec string, ptype string, oldRules, newRules [][]string) error {
// Update multiple policies in storage
// Use transactions for consistency
return nil
}

// UpdateFilteredPolicies updates policy rules that match the filter from the storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdateFilteredPolicies(sec string, ptype string, newRules [][]string, fieldIndex int, fieldValues ...string) error {
// Find policies matching the filter, then update them
return nil
}
노트

Without UpdateAdapter support, Casbin automatically falls back to combining RemovePolicy() and AddPolicy() operations.

컨텍스트 어댑터

ContextAdapter provides context-aware operations for Casbin adapters.

Context enables features like timeout control for adapter API calls.

Example

gormadapter supports context. Below is timeout control using context:

ca, _ := NewContextAdapter("mysql", "root:@tcp(127.0.0.1:3306)/", "casbin")
// Set 300s timeout
ctx, cancel := context.WithTimeout(context.Background(), 300*time.Microsecond)
defer cancel()

err := ca.AddPolicyCtx(ctx, "p", "p", []string{"alice", "data1", "read"})
if err != nil {
panic(err)
}

컨텍스트 어댑터를 작성하는 방법

ContextAdapter API adds a context processing layer on top of standard Adapter API. After implementing the standard Adapter API, wrap your logic with context handling.

Reference implementation: adapter.go

Transaction

Casbin supports transactions. Transaction usage in gormadapter:

db, _ := gorm.Open(...)
adapter, _ := gormadapter.NewTransactionalAdapterByDB(db)
e, _ := casbin.NewTransactionalEnforcer("examples/rbac_model.conf", adapter)

ctx := context.Background()

// WithTransaction executes a function within a transaction.
// Errors trigger rollback; otherwise, automatic commit occurs.
err := e.WithTransaction(ctx, func(tx *casbin.Transaction) error {
tx.AddPolicy("alice", "data1", "read")
tx.AddPolicy("alice", "data1", "write")
return nil
})

// Manual transaction handling
tx, _ := e.BeginTransaction(ctx)
tx.AddPolicy("alice", "data1", "write")
if err := tx.Commit(); err != nil {
// handle transaction failure
}

Implement TransactionalAdapter and TransactionContext from persist/transaction.go to add transaction support.

Reference: adapter.go