Skip to main content

Python bindings for Cedar, the open-source policy language for access control.

Project description

Cedar Python

Python bindings for Cedar, the open-source policy language for access control. This library lets you define, validate, and evaluate authorization policies directly from Python.

Installation

pip install cedar-python

Quick Start

from cedar import Authorizer, EntityUid, Policy, PolicySet, Request

# Create policies
policies = PolicySet('''
    permit(principal == User::"alice", action == Action::"read", resource);
    forbid(principal, action == Action::"delete", resource);
''')

# Create and evaluate a request
request = Request(
    EntityUid("User", "alice"),
    EntityUid("Action", "read"),
    EntityUid("Document", "doc1"),
)

authorizer = Authorizer()
response = authorizer.is_authorized(request, policies)
print(response.allowed)  # True

Core API

Entities

from cedar import Entity, EntityUid, Context

# Entity identifiers
uid = EntityUid("User", "alice")
uid.entity_type()  # "User"
uid.id()           # "alice"

# Entities with attributes and hierarchy
user = Entity(
    uid=EntityUid("User", "alice"),
    attrs={"email": "alice@example.com", "role": "admin"},
    parents=[EntityUid("Group", "admins")]
)

# Context for requests
context = Context({"ip_address": "10.0.0.1", "authenticated": True})

Authorization

from cedar import Authorizer, Request, Response

# Authorizer with entity hierarchy
authorizer = Authorizer(entities=[user, group])

# Full request with context
request = Request(
    principal=EntityUid("User", "alice"),
    action=EntityUid("Action", "read"),
    resource=EntityUid("Document", "doc1"),
    context=Context({"time": "2024-01-01T00:00:00Z"})
)

response = authorizer.is_authorized(request, policies)
response.allowed    # bool
response.decision   # "Allow" or "Deny"
response.reason     # Policy IDs that contributed to decision
response.errors     # Any evaluation errors

Schema Validation

Validate entities, requests, and context against a schema:

from cedar import Authorizer, Context, EntityUid, Request, Schema

schema = Schema.from_json('''...''')
action = EntityUid("Action", "read")

# Validate context against schema (requires action to determine expected shape)
context = Context({"ip_address": "10.0.0.1"}, schema=schema, action=action)

# Validate request components against schema
request = Request(
    principal=EntityUid("User", "alice"),
    action=action,
    resource=EntityUid("Document", "doc1"),
    context=context,
    schema=schema
)

# Validate entities when creating the authorizer
authorizer = Authorizer(entities=[user, doc], schema=schema)

# Validate request components using stored schema
authorizer.validate_request(principal, action, resource, context)

Dynamic Entity Management

Add, update, or remove entities in an existing authorizer:

from cedar import Authorizer, Entity, EntityUid

authorizer = Authorizer()

# Add a new entity (fails if entity already exists)
alice = Entity(EntityUid("User", "alice"), {"role": "admin"})
authorizer.add_entity(alice)

# Upsert an entity (adds or replaces existing)
alice_updated = Entity(EntityUid("User", "alice"), {"role": "user"})
authorizer.upsert_entity(alice_updated)

# Remove an entity by UID
authorizer.remove_entity(EntityUid("User", "alice"))

# With schema validation
schema = Schema.from_json('''...''')
authorizer = Authorizer(schema=schema)
doc = Entity(EntityUid("Document", "doc1"), {"owner": "alice"})
authorizer.add_entity(doc)  # Validates against schema

Policies

from cedar import Policy, PolicySet

# Single policy
policy = Policy('permit(principal, action, resource);', id="policy1")
policy.id()          # "policy1"
policy.effect()      # "Permit"
policy.annotations() # {"id": "policy1"}
policy.to_cedar()    # Formatted Cedar syntax
policy.to_json()     # JSON representation

# Policy sets
policy_set = PolicySet('''
    @id("read-access")
    permit(principal, action == Action::"read", resource);
''')
policy_set.policies()      # List of Policy objects
policy_set.policy("read-access")  # Get by ID
len(policy_set)            # Number of policies

Schemas

from cedar import Schema

# From JSON
schema = Schema.from_json('''{
    "": {
        "entityTypes": {"User": {}, "Document": {}},
        "actions": {
            "read": {"appliesTo": {"principalTypes": ["User"], "resourceTypes": ["Document"]}}
        }
    }
}''')

# From Cedar schema syntax
schema = Schema.from_cedarschema('''
    entity User;
    entity Document;
    action read appliesTo { principal: User, resource: Document };
''')

schema.entity_types()  # ["User", "Document"]
schema.actions()       # ["read"]
schema.principals()    # Entity types that can be principals
schema.resources()     # Entity types that can be resources

Validation

Validate policies against a schema for type checking and error detection:

from cedar import PolicySet, Schema

# Create schema and policies
schema = Schema.from_cedarschema('''
    entity User;
    entity Document;
    action read appliesTo { principal: User, resource: Document };
''')

policies = PolicySet('''
    permit(principal == User::"alice", action == Action::"read", resource);
''')

# Validate policies against schema
result = schema.validate_policyset(policies)
result.valid     # True if validation passed
result.errors    # List of ValidationError objects
result.warnings  # List of ValidationWarning objects

# ValidationError/ValidationWarning have policy_id and message attributes
for error in result.errors:
    print(f"{error.policy_id}: {error.message}")

Schema Module

Pydantic models for building schemas programmatically:

from cedar.schema import CedarSchema, NamespaceDefinition, EntityType, Action, AppliesTo

schema = CedarSchema(root={
    "": NamespaceDefinition(
        entityTypes={"User": EntityType()},
        actions={"read": Action(appliesTo=AppliesTo(principalTypes=["User"]))}
    )
})

Lean Module (Formal Verification)

Symbolic policy analysis using cedar-lean-cli:

from cedar.lean import (
    check_equivalent,
    check_implies,
    check_disjoint,
    compare_policysets,
    analyze_policies,
)

# Check if two policies are equivalent
result = check_equivalent(policy1, policy2, schema)
result.satisfied      # True if equivalent
result.counterexample # Example where they differ (if not equivalent)

# Compare policy sets
comparison = compare_policysets(old_policies, new_policies, schema)
comparison.is_equivalent   # True if all request signatures are equivalent
comparison.more_permissive # Request envs where source allows more
comparison.less_permissive # Request envs where source allows less

CLI

# Validate a policy against a schema
cedar schema validate policy.cedar schema.json

# Run the MCP server
cedar mcp

MCP Server

For AI coding assistants, Cedar provides an MCP server with policy tools:

pip install cedar-python[mcp]
cedar mcp

Available tools: validate_policy, validate_policy_set, validate_schema, format_policy

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cedar_python-0.1.2-cp314-cp314-macosx_10_12_x86_64.whl (4.0 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

cedar_python-0.1.2-cp313-cp313-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.13Windows x86-64

cedar_python-0.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

cedar_python-0.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

cedar_python-0.1.2-cp313-cp313-macosx_11_0_arm64.whl (3.8 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

cedar_python-0.1.2-cp313-cp313-macosx_10_12_x86_64.whl (4.0 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

cedar_python-0.1.2-cp312-cp312-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.12Windows x86-64

cedar_python-0.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

cedar_python-0.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

cedar_python-0.1.2-cp312-cp312-macosx_11_0_arm64.whl (3.8 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

cedar_python-0.1.2-cp312-cp312-macosx_10_12_x86_64.whl (4.0 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

File details

Details for the file cedar_python-0.1.2-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 4742c9f548fa7f0958c4341f0230819f46a03d6f28d092b812e69b7b64a3ed4b
MD5 84b1e2f2b3584f851b42d5cee03bc18c
BLAKE2b-256 0ef4f5d23100ffcb62f9f075d168cf72fb8b083c7c273ee5df0a07e28a692508

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 ba111c448351521eebf2b3c310f3bdee15ab67617b13b11247922cb76b219537
MD5 27ddab377a9efbc8d7966fb2f528017f
BLAKE2b-256 5d0001056205b3206411389961a5ba9c45c3dc1e99c276d319c345c9f0877b6b

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 01d15f0a8c5f842da3839a09df59df7b5a13bf43c5d29aa9f8bf8263bcc87d6a
MD5 f86c81d5ef58ed716a8b571318975ab1
BLAKE2b-256 a0012c22ea45d2142c01991075b5dcb092e75bd21821a69d473b8ec9a3b4c398

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 fa2a016a38ab782d2abb9e05e01abb487ca7e6d8ec88cf89819e1efbbb82f2f4
MD5 2843a7b2e1050d66602c1b94e6c17a8b
BLAKE2b-256 83740d8b2f5e036f76ceeb6c928a164ffe8507493869d690c161ac2e918dfd12

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 aabbe0d2c2b7bbe8ecd583330229cb4fab778f7e8560e098b1d73fc07193a6e7
MD5 e151b14538109524b312c46878be929d
BLAKE2b-256 2a39113dead43eb17bd0aa01cfb27541462755440395a53509d3dcaf13c05a90

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0de1295618fc011331ccb0f939e9e8c710056f2d8413c7d5d5d0adbff12fba75
MD5 e393f21c8c9d1a241e1f0e4e008ca417
BLAKE2b-256 f76f31f00b7a7332a74d1207f355d4b674b4a5eb4f77bf8dd99c4fd7fc370808

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 27633cfe50b3a79ed4020cf884f3d1df0a2aef2fcd3638a218aea802c062c80c
MD5 9a66f343a0d7932967483cde39cdc6e7
BLAKE2b-256 e2e321dfb6256162ea2883b4d8b472006491b766005d8f0a4bdd3df9f4c400c8

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a456d043bc9704fbf8c450bf0484c0b8378d7f2879bc34f34c6ee14601883ef6
MD5 31f7bb20eb781f201eaaa808cb5e7e79
BLAKE2b-256 bfd15d6f6f4ff0b03604a17d1790a1e81eb833d0800bb9deeff74a52452ae8c3

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 912532b06633f94950b34fa2ce7e577a55af20bb8f54d6b52e1572cef60fcb17
MD5 2cf29b37a3efd31de146950d5ebc9aca
BLAKE2b-256 c2843a7203c412302c1a2622d8e82fccaa823c5875655a095810db35e38209c4

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ecd87f82934363806dc9b2d707d7056dc8247f091d2e3723d758c45f45b63469
MD5 9ea9016df16baf89255b809957c29247
BLAKE2b-256 8b4eddd00519f403545480b375df76ee9a4cf343f9d92b11ce4dc1e3ad6a0f15

See more details on using hashes here.

File details

Details for the file cedar_python-0.1.2-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for cedar_python-0.1.2-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 53269c65a6ca8e865479ac54efecb155e47b5c66e5c83193b6d23bc238f460e7
MD5 3504d5381f9e08ffc7657d289cbe0dad
BLAKE2b-256 4386e48f0167820cf44c3ae5963a69db7828bb215a6844785fe0078b427b9815

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page