Apache Casbin

repository·master·Indexed 12 days ago

https://github.com/apache/casbin

A multi-language access control library providing authorization enforcement based on the PERM metamodel. It supports various models including ACL, RBAC, and ABAC, and features a v3 Go package with high-performance options like SyncedCachedEnforcer and CachedEnforcer, as well as AI-powered authorization explanations.

Tokens
22.8K
Snippets
85
Records
112
Agent score
94%

What's inside Casbin

  1. Supported access control models

    master

    Apache Casbin supports a wide variety of access control models, including:

    • ACL (Access Control List): The simplest model.
    • ACL with superuser: Supports a built-in superuser (e.g., root) that can bypass explicit permissions.
    • ACL without users/resources: Useful for systems without authentication or for targeting resource types (e.g., write-article).
    • RBAC (Role-Based Access Control): Includes variations like RBAC with resource roles and RBAC with domains/tenants.
    • ABAC (Attribute-Based Access Control): Uses attributes (e.g., resource.Owner) for fine-grained control.
    • RESTful: Supports path patterns (e.g., /res/*, /res/:id) and HTTP methods.
    • Deny-override: Supports both allow and deny rules, where deny takes precedence.
    • Priority: Allows prioritizing policy rules similar to firewall rules.
  2. Manage permissions with Management and RBAC APIs

    master

    Apache Casbin provides two distinct API sets for permission management:

    • Management API: The primitive API that provides full support for all Apache Casbin policy management tasks.
    • RBAC API: A user-friendly subset of the Management API specifically designed for Role-Based Access Control (RBAC) scenarios. Use this to simplify your code when working with roles.

    Additionally, a web-based UI is available for visual model and policy management.

  3. Configure policy persistence and consistency

    master

    To manage how Casbin policies are stored and synchronized, use the following mechanisms:

    • Adapters: Used for policy persistence (storing policies in databases, files, etc.).
    • Watchers: Used to maintain policy consistency across multiple nodes in a distributed system.
  4. How Apache Casbin works: The PERM metamodel

    master

    Apache Casbin abstracts access control models into a configuration (CONF) file based on the PERM metamodel:

    1. Policy: Defines the rules (e.g., p, alice, data1, read).
    2. Effect: Defines how the policy rules are combined to reach a decision (e.g., some(where (p.eft == allow))).
    3. Request: Defines the structure of the request being checked (e.g., r = sub, obj, act).
    4. Matchers: Defines the logic used to match the request against the policy (e.g., m = r.sub == p.sub && r.obj == p.obj && r.act == p.act).

    This abstraction allows you to switch or upgrade authorization mechanisms (like moving from ACL to RBAC or ABAC) simply by modifying the configuration file without changing your core application logic.

    # Request definition
    [request_definition]
    r = sub, obj, act
    
    # Policy definition
    [policy_definition]
    p = sub, obj, act
    
    # Policy effect
    [policy_effect]
    e = some(where (p.eft == allow))
    
    # Matchers
    [matchers]
    m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
  5. Explore Casbin model and policy examples

    master

    Casbin supports various access control models. You can find specific .conf (model) and .csv (policy) files in the repository's examples/ directory to implement the following patterns:

    ModelModel FilePolicy File
    ACLbasic_model.confbasic_policy.csv
    ACL with superuserbasic_model_with_root.confbasic_policy.csv
    ACL without usersbasic_model_without_users.confbasic_policy_without_users.csv
    ACL without resourcesbasic_model_without_resources.confbasic_policy_without_resources.csv
    RBACrbac_model.confrbac_policy.csv
    RBAC with resource rolesrbac_model_with_resource_roles.confrbac_policy_with_resource_roles.csv
    RBAC with domains/tenantsrbac_model_with_domains.confrbac_policy_with_domains.csv
    ABACabac_model.confN/A
    RESTfulkeymatch_model.confkeymatch_policy.csv
    Deny-overriderbac_model_with_deny.confrbac_policy_with_deny.csv
    Prioritypriority_model.confpriority_policy.csv
  6. Get started with Apache Casbin in Go

    master

    To implement authorization in your Go application, follow these three steps:

    1. Initialize the Enforcer: Create a new enforcer instance by providing a model configuration file and a policy file (CSV or database).
    2. Enforce Permissions: Call the Enforce method with the subject, object, and action to check if access should be granted.
    3. Manage Permissions: Use the provided APIs to manage roles and policies at runtime.
    // 1. New a Casbin enforcer with a model file and a policy file
    e, _ := casbin.NewEnforcer("path/to/model.conf", "path/to/policy.csv")
    
    // 2. Add an enforcement hook
    sub := "alice" // the user
    obj := "data1" // the resource
    act := "read"  // the operation
    
    if res, _ := e.Enforce(sub, obj, act); res {
        // permit alice to read data1
    } else {
        // deny the request
    }
    
    // 3. Runtime permission management example
    roles, _ := e.GetImplicitRolesForUser(sub)
  7. Use SyncedCachedEnforcer for high-performance policy enforcement

    master

    The SyncedCachedEnforcer is a wrapper around SyncedEnforcer that provides a decision sync cache. It improves performance by caching the results of Enforce() calls. When a decision is made, the result is stored in a cache; subsequent identical requests can be served directly from the cache instead of re-evaluating the entire policy engine.

    Key behaviors:

    • Automatic Cache Invalidation: When policies are modified via AddPolicy, AddPolicies, RemovePolicy, or RemovePolicies, the enforcer automatically attempts to remove the relevant cached decisions to ensure consistency.
    • Policy Reloading: Calling LoadPolicy() clears the entire cache to prevent stale decisions after a full policy reload.
    • Cache Configuration: You can enable/disable the cache, set an expiration time for cached results, or provide a custom cache.Cache implementation.
    // Create a new sync cached enforcer
    enforcer, err := casbin.NewSyncedCachedEnforcer(adapter, model)
    if err != nil {
        panic(err)
    }
    
    // Set how long decisions stay in cache
    enforcer.SetExpireTime(time.Minute * 10)
    
    // Perform an enforcement check (will use cache if enabled)
    allowed, err := enforcer.Enforce("alice", "data1", "read")
  8. How transaction commit and rollback work

    master

    Casbin uses a two-phase commit protocol to ensure consistency between the persistent storage (database) and the in-memory model.

    1. Concurrency Control: Transactions attempt to acquire a commitLock with a timeout. If the lock cannot be acquired, the transaction fails.
    2. Conflict Detection: Before applying changes, the system checks if the modelVersion has changed. If it has, a ConflictDetector validates that the buffered operations do not conflict with the current state of the model.
    3. Database Phase: Operations are applied to the database. If the adapter supports batching (BatchAdapter) or updates (UpdatableAdapter), it uses those for efficiency. If a database error occurs, the database transaction is rolled back.
    4. Model Phase: If the database commit succeeds, the in-memory model is updated. If this phase fails, it results in a critical error because the database and memory are now out of sync.
    5. Role Rebuilding: If the transaction modified the g (grouping) section and autoBuildRoleLinks is enabled, the enforcer automatically rebuilds role links to maintain correct RBAC behavior.
  9. Use SyncedEnforcer for thread-safe policy management

    master

    The SyncedEnforcer is a wrapper around the standard Enforcer that provides synchronized access using a sync.RWMutex. It is designed for environments where multiple goroutines need to perform enforcement or modify policies concurrently without race conditions. It also includes built-in support for automatic policy reloading.

    // Create a new synchronized enforcer
    e, err := casbin.NewSyncedEnforcer("model.conf", "policy.csv")
    if err != nil {
        panic(err)
    }
    
    // Use it just like a regular enforcer, but it's thread-safe
    ok, err := e.Enforce("alice", "data1", "read")
  10. Use CachedEnforcer for performance optimization

    master

    The CachedEnforcer wraps a standard Enforcer and provides a decision cache to speed up repeated authorization requests. When enabled, it stores the results of Enforce() calls. To ensure cache consistency, the CachedEnforcer automatically invalidates or updates the cache when policies are reloaded or removed.

    Key behaviors:

    • Cache Key Generation: The cache uses GetCacheKey to generate keys from input parameters. Parameters must be either string types or implement the CacheableParam interface. If parameters cannot be converted to a key, the cache is bypassed for that specific call.
    • Automatic Invalidation: Calling LoadPolicy(), RemovePolicy(), RemovePolicies(), or ClearPolicy() will trigger cache clearing or specific key deletion to prevent stale authorization decisions.
    • Concurrency: The CachedEnforcer uses a sync.RWMutex to ensure thread-safe access to the underlying cache.
    // Example of creating and using a CachedEnforcer
    enforcer, err := casbin.NewCachedEnforcer("model.conf", "policy.csv")
    if err != nil {
        panic(err)
    }
    
    // Set expiration for cached decisions
    enforcer.SetExpireTime(time.Minute * 10)
    
    // Enable the cache (enabled by default in NewCachedEnforcer)
    enforcer.EnableCache(true)
    
    // The first call performs the actual enforcement
    allowed, err := enforcer.Enforce("alice", "data1", "read")
    
    // Subsequent identical calls will return the cached result
    allowed, err = enforcer.Enforce("alice", "data1", "read")