Skip to main content
๐Ÿ›ก๏ธ Verified Technical Content: Written by Serhii Hrekov. | Last reviewed & updated in Git: July 21, 2026

Casbin Policy Storage in Python: SQLite, Firestore, and SQLAlchemy Adapter Guide

ยท 7 min read
Serhii Hrekov
Senior Software Engineer & System Architect specializing in Python, Web Systems, Cloud Infrastructure & Automation

Using SQLite as the database adapter for Casbin policy storage is the ideal solution for local development, unit testing, and small-scale applications due to its lightweight, file-based nature.

In the Python Casbin ecosystem, this is achieved using the casbin-sqlalchemy-adapter, as SQLAlchemy natively supports SQLite without needing separate driver installations [2].

1. Installation and Dependenciesโ€‹

To set up Casbin with SQLite, you only need the core Casbin library and the Casbin SQLAlchemy Adapter:

# Install the core Casbin library
pip install pycasbin

# Install the SQLAlchemy Adapter (handles SQLite, PostgreSQL, MySQL, etc.)
pip install casbin-sqlalchemy-adapter

2. Setting Up the Casbin Enforcer with SQLiteโ€‹

The setup requires defining the SQLAlchemy connection string that points to your SQLite file. If the file doesn't exist, SQLite and the adapter will automatically create it.

Python Code Exampleโ€‹

import casbin
from casbin_sqlalchemy_adapter import Adapter as SQLAlchemyAdapter

# 1. Define the connection string for the SQLite database file.
# The 'sqlite:///' prefix indicates a file path (three slashes).
# 'policy.db' will be created in the current directory if it doesn't exist.
SQLITE_URL = 'sqlite:///policy.db'

# 2. Instantiate the Adapter
# This links Casbin's policy management to the SQLite file.
adapter = SQLAlchemyAdapter(SQLITE_URL)

# 3. Instantiate the Casbin Enforcer
# 'model.conf' defines the rules (e.g., RBAC, ABAC).
# The adapter is passed here, which triggers the LoadPolicy() operation.
e = casbin.Enforcer('model.conf', adapter)

# The Enforcer is now ready to perform checks against the policy stored in 'policy.db'.

# Example Enforcement
sub = "alice"
obj = "/users/101"
act = "edit"

if e.enforce(sub, obj, act):
print(f"{sub} is permitted to {act} {obj}.")
else:
print(f"{sub} is denied access to {obj}.")

Annotation: The SQLAlchemyAdapter translates Casbin policy rules (like p, alice, data1, read) into rows in a table named casbin_rule within the policy.db file [1].


3. Policy Managementโ€‹

When using the Casbin management API, the adapter ensures changes are immediately saved to the SQLite file, providing persistence across application restarts.

Adding and Removing Policiesโ€‹

# Adding a new policy rule
e.add_policy("bob", "/data/audit", "view")

# Adding a grouping rule (e.g., assigning a role)
e.add_grouping_policy("bob", "auditor")

# Removing a policy rule
e.remove_policy("alice", "/users/101", "edit")

Every successful call to the Casbin policy management API (e.g., add_policy, remove_grouping_policy) automatically calls the adapter's methods to update the SQLite database file.

Key Considerations for SQLiteโ€‹

  • No Watcher Needed: In a typical local development scenario, where only one instance of the Flask app is running, a Watcher (used for synchronizing policy changes across multiple services) is not necessary.
  • Performance: SQLite is extremely fast for local, single-user access, making it highly efficient for unit and integration tests.
  • Portability: The use of the SQLAlchemy Adapter means you can switch the policy storage to PostgreSQL or MySQL for staging/production simply by changing the connection string (SQLITE_URL) and installing the corresponding driver, without altering your core Casbin or Flask application code.

4. Using Firestore as Policy Storage (Cloud-Native)โ€‹

For production deployments on Google Cloud, you can use Firestore as the policy storage backend via a dedicated adapter. The setup involves the Firebase Admin SDK.

Prerequisites and Installationโ€‹

pip install pycasbin
pip install pycasbin-firebase-adapter firebase-admin

Ensure the environment where your Flask app runs (e.g., GCP App Engine, Cloud Run) has the necessary IAM permissions to access Firestore, or that you have set up a service account key [5].

Setting Up the Firestore Adapterโ€‹

import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
import casbin
from pycasbin_firebase_adapter import Adapter as FirestoreAdapter

# --- 1. Load Credentials ---
try:
cred = credentials.ApplicationDefault()
firebase_admin.initialize_app(cred)
except:
cred = credentials.Certificate("path/to/serviceAccountKey.json")
firebase_admin.initialize_app(cred)

db = firestore.client()

# 2. Instantiate the Adapter
adapter = FirestoreAdapter(db)

# 3. Instantiate the Enforcer
e = casbin.Enforcer("model.conf", adapter)

# --- Policy is automatically loaded into memory here (LoadPolicy()) ---
sub = "alice"
obj = "/reports/finance"
act = "read"

if e.enforce(sub, obj, act):
print(f"{sub} is permitted to {act} {obj}.")
else:
print(f"{sub} is denied access to {obj}.")

Firestore Policy Managementโ€‹

When you make changes using the Casbin management API, the adapter automatically translates those changes into Firestore documents.

Casbin API CallFirestore Document Action
e.add_policy("editor", "/data", "write")Creates a new document in the Casbin collection (e.g., ptype: p, v0: editor, v1: /data, v2: write).
e.add_grouping_policy("user_x", "editor")Creates a new document (e.g., ptype: g, v0: user_x, v1: editor).
e.save_policy()Overwrites the entire policy in Firestore with the current in-memory state.

Firestore Policy Document Structureโ€‹

FieldCasbin Policy Line Component
ptypeThe policy type (p, g, g2, etc.)
v0The first field (e.g., user or role)
v1The second field (e.g., resource or parent_role)
v2 to v5Subsequent fields (e.g., action or domain)

Sourcesโ€‹

  1. GitHub - pycasbin/sqlalchemy-adapter
  2. Casbin Documentation - Adapters
  3. GitHub - pycasbin-firebase-adapter
  4. Casbin Documentation - Policy Storage Details
  5. Google Cloud - Application Default Credentials (ADC) Guide

Related articles