Python bindings for Cedarling, a Rust-based authorization engine for Cedar policies
Project description
cedarling_python 🐍
This project uses maturin to create a Python library from Rust code. Follow the steps below to install and build the library.
Prerequisites
-
(Optional) Install build tools (for Linux users)
Install the
build-essentialpackage or its equivalent packages using your distribution's package manager.Ubuntu/Debian:
sudo apt install build-essentialArch Linux:
sudo pacman -S base-develRHEL/CentOS/Fedora:
sudo yum install gcc gcc-c++ make openssl-dev -
Ensure Rust is installed: Verify Rust installation by running:
cargo --versionIf Rust is not installed, you can install it from here.
-
Set up a virtual environment:
-
Install
venvfor your platform by following the instructions here. -
Create a virtual environment:
python3 -m venv venv
-
-
Activate the virtual environment: Follow the instructions here to activate the virtual environment.
Example for Linux/macOS:
source venv/bin/activate
Example for Windows:
.\venv\Scripts\activate
-
Install
maturinpip install maturinFor Linux, install patchelf dependency:
pip install maturin[patchelf] -
Clone the repository:
git clone https://github.com/JanssenProject/jans.git -
Navigate to the
cedarling_pythonfolder:cd jans/jans-cedarling/bindings/cedarling_python -
Build and install the package: Build the Rust crate and install it into the virtual environment:
maturin develop --release -
Verify installation: Check that the library is installed by listing the installed Python packages:
pip listYou should see
cedarling_pythonlisted among the available packages. -
Read documentation After installing the package you can read the documentation from python using the following command:
python -m pydoc cedarling_python
Examples
Standalone example scripts live in the examples/ directory, each with its own
directory-based policy store under example_files/. Make sure the virtual environment is
activated and the package is installed before running them.
Unsigned authorization (no JWT tokens)
Authorize requests by supplying principals directly as EntityData objects, without any JWT tokens. Useful for internal services or test harnesses.
python examples/unsigned_authz.py
- Script:
examples/unsigned_authz.py - Policy store:
example_files/policy-store-unsigned/
Multi-issuer authorization (JWT tokens)
Authorize requests carrying JWT tokens from one or more issuers, with Cedar policies that inspect token attributes via tags.
python examples/multi_issuer_authz.py
- Script:
examples/multi_issuer_authz.py - Policy store:
example_files/policy-store-multi-issuer/
Configuration
Policy Store Sources
Policy store sources can be configured via a YAML/JSON file or environment variables. Here are examples for each source type:
from cedarling_python import BootstrapConfig, Cedarling
# From a local JSON/YAML file
bootstrap_config = BootstrapConfig.load_from_file("/path/to/bootstrap-config.yaml")
instance = Cedarling(bootstrap_config)
# From a local directory (new format)
# In your bootstrap-config.yaml:
# CEDARLING_POLICY_STORE_LOCAL_FN: "/path/to/policy-store/"
bootstrap_config = BootstrapConfig.load_from_file("/path/to/bootstrap-config.yaml")
instance = Cedarling(bootstrap_config)
# From a local .cjar archive
# In your bootstrap-config.yaml:
# CEDARLING_POLICY_STORE_LOCAL_FN: "/path/to/policy-store.cjar"
bootstrap_config = BootstrapConfig.load_from_file("/path/to/bootstrap-config.yaml")
instance = Cedarling(bootstrap_config)
# From a URL (.cjar or Lock Server)
# In your bootstrap-config.yaml:
# CEDARLING_POLICY_STORE_URI: "https://example.com/policy-store.cjar"
bootstrap_config = BootstrapConfig.load_from_file("/path/to/bootstrap-config.yaml")
instance = Cedarling(bootstrap_config)
# Using environment variables instead of a file
import os
os.environ["CEDARLING_POLICY_STORE_LOCAL_FN"] = "/path/to/policy-store.json"
bootstrap_config = BootstrapConfig.from_env()
instance = Cedarling(bootstrap_config)
For complete working examples, see the examples/ directory.
For details on the directory-based format and .cjar archives, see Policy Store Formats.
Testing Configuration
For testing scenarios, you may want to disable JWT validation. You can set environment variables:
export CEDARLING_JWT_SIG_VALIDATION="disabled"
export CEDARLING_JWT_STATUS_VALIDATION="disabled"
Or configure in your Python code:
import os
os.environ['CEDARLING_JWT_SIG_VALIDATION'] = 'disabled'
For complete configuration documentation, see cedarling-properties.md.
Context Data API
The Context Data API allows you to push external data into the Cedarling evaluation context, making it available in Cedar policies through the context.data namespace.
Push Data
Store data with an optional TTL (Time To Live):
from cedarling_python import Cedarling, BootstrapConfig
config = BootstrapConfig.load_from_file("bootstrap-config.yaml")
instance = Cedarling(config)
# Push data without TTL (uses default from config)
instance.push_data_ctx("user:123", {"role": ["admin", "editor"], "country": "US"})
# Push data with TTL (5 minutes = 300 seconds)
instance.push_data_ctx("config:app", {"setting": "value"}, ttl_secs=300)
# Push different data types
instance.push_data_ctx("key1", "string_value")
instance.push_data_ctx("key2", 42)
instance.push_data_ctx("key3", [1, 2, 3])
instance.push_data_ctx("key4", {"nested": "data"})
Get Data
Retrieve stored data:
# Get data by key
# Note: get_data_ctx returns None for missing keys, not KeyNotFound
value = instance.get_data_ctx("user:123")
if value is not None:
print(f"User roles: {value['role']}")
Get Data Entry with Metadata
Get a data entry with full metadata including creation time, expiration, access count, and type:
# Note: get_data_entry_ctx returns None for missing keys, not KeyNotFound
entry = instance.get_data_entry_ctx("user:123")
if entry is not None:
print(f"Key: {entry.key}")
print(f"Created at: {entry.created_at}")
print(f"Access count: {entry.access_count}")
print(f"Data type: {entry.data_type}")
print(f"Value: {entry.value}")
Remove Data
Remove a specific entry:
# Remove data by key
removed = instance.remove_data_ctx("user:123")
if removed:
print("Entry was removed")
else:
print("Entry did not exist")
Clear All Data
Remove all entries from the data store:
instance.clear_data_ctx()
List All Data
List all entries with their metadata:
entries = instance.list_data_ctx()
for entry in entries:
print(f"Key: {entry.key}, Type: {entry.data_type}, Created: {entry.created_at}")
Get Statistics
Get statistics about the data store:
stats = instance.get_stats_ctx()
print(f"Entries: {stats.entry_count}/{stats.max_entries}")
print(f"Total size: {stats.total_size_bytes} bytes")
print(f"Capacity usage: {stats.capacity_usage_percent}%")
Error Handling
The Context Data API methods raise specific exceptions for different error conditions:
from cedarling_python import data_errors
try:
instance.push_data_ctx("", {"data": "value"}) # Empty key
except data_errors.InvalidKey:
print("Invalid key provided")
# Note: get_data_ctx and get_data_entry_ctx return None for missing keys,
# not KeyNotFound. KeyNotFound is only raised for operation failures.
value = instance.get_data_ctx("nonexistent")
if value is None:
print("Key not found")
Available exceptions:
InvalidKey: The provided key is invalid (e.g., empty)KeyNotFound: Raised for operation failures (not for missing keys -get_data_ctxandget_data_entry_ctxreturnNonefor missing keys)StorageLimitExceeded: The data store has reached its capacity limitTTLExceeded: The requested TTL exceeds the maximum allowed TTLValueTooLarge: The value exceeds the maximum entry sizeSerializationError: Failed to serialize/deserialize the value
Using Data in Cedar Policies
Data pushed via the Context Data API is automatically available in Cedar policies under the context.data namespace:
permit(
principal,
action == Jans::Action::"read",
resource
) when {
context.data has "user:123" &&
context.data["user:123"].role.contains("admin")
};
The data is injected into the evaluation context before policy evaluation, allowing policies to make decisions based on dynamically pushed data.
Trusted Issuer Loading Info
Cedarling exposes trusted issuer loading status APIs:
loaded_by_name = instance.is_trusted_issuer_loaded_by_name("issuer_id")
loaded_by_iss = instance.is_trusted_issuer_loaded_by_iss("https://issuer.example.org")
total = instance.total_issuers()
loaded_count = instance.loaded_trusted_issuers_count()
loaded_ids = instance.loaded_trusted_issuer_ids()
failed_ids = instance.failed_trusted_issuer_ids()
These values are meaningful when your policy store defines a trusted-issuers/ section.
Building the Python Library
If you only want to build the library without installing it in the Python environment, follow these steps:
-
Complete the prerequisites
-
Navigate to the
cedarling_pythonfolder:cd jans/jans-cedarling/bindings/cedarling_python
-
Build the crate: To build the library:
maturin build --release
Python types definitions
The python types definitions are available in the PYTHON_TYPES.md file. Or by clicking here.
Also after installing the library you can get same information using:
python -m pydoc cedarling_python
Testing the Python bindings
We use pytest and tox to create reproduceable environments for testing.
Run test with pytest
To run the tests, with pytest:
-
Make sure that you have installed the
cedarling_pythonpackage in your virtual environment or system. -
Install
pytest:pip install pytest
-
Make sure that you are in the
jans/jans-cedarling/bindings/cedarling_python/folder. -
Run the following command:
pytest
Or run
pytestwithout capturing the output:pytest -s -
See the results in the terminal.
Run test with tox
-
Ensure that you installed rust compiler and toolchain. You can install it by following the official rust installation guide.
-
Ensure tox is installed: You can install tox in your environment using pip:
pip install tox
-
Make sure that you are in the
jans/jans-cedarling/bindings/cedarling_python/folder. -
Run the following command:
tox
-
See the results in the terminal.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cedarling_python-0.0.26-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: cedarling_python-0.0.26-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 9.9 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
969993b3ba659b4e1263c3f99f0e8a63dacc1ee7005527ae3d12d809b9fba939
|
|
| MD5 |
b74b156bc4611e04f7c544054f5c29a7
|
|
| BLAKE2b-256 |
08e0e224f8e6be0990798aa2156c6fc1c4f9af0b95b05884d25305eb2366aabd
|
Provenance
The following attestation bundles were made for cedarling_python-0.0.26-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
build-packages.yml on JanssenProject/jans
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cedarling_python-0.0.26-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
969993b3ba659b4e1263c3f99f0e8a63dacc1ee7005527ae3d12d809b9fba939 - Sigstore transparency entry: 1760328026
- Sigstore integration time:
-
Permalink:
JanssenProject/jans@ed4c4317c14ceb9556ff59a95a82eed664a39b31 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JanssenProject
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-packages.yml@ed4c4317c14ceb9556ff59a95a82eed664a39b31 -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file cedarling_python-0.0.26-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: cedarling_python-0.0.26-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 9.9 MB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5734d1b4f6f60f876c6e4a4bca3714391396028e15a793381b4197136b5cc9c8
|
|
| MD5 |
888b2901d16f28d836a457524d99620f
|
|
| BLAKE2b-256 |
e4abf5821c7b528c386477bafa974213726a91ffbee25bc7914244ea763f139c
|
Provenance
The following attestation bundles were made for cedarling_python-0.0.26-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
build-packages.yml on JanssenProject/jans
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cedarling_python-0.0.26-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
5734d1b4f6f60f876c6e4a4bca3714391396028e15a793381b4197136b5cc9c8 - Sigstore transparency entry: 1760328062
- Sigstore integration time:
-
Permalink:
JanssenProject/jans@ed4c4317c14ceb9556ff59a95a82eed664a39b31 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JanssenProject
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-packages.yml@ed4c4317c14ceb9556ff59a95a82eed664a39b31 -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file cedarling_python-0.0.26-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: cedarling_python-0.0.26-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 9.9 MB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
649cc7ca233e4ab20d3fdf419750aa2d0190510372ccfab004a869d9d120b2e8
|
|
| MD5 |
d5e45388fd31424fe3e7841859d4dc18
|
|
| BLAKE2b-256 |
783e42145bb0c579f950d0208d08279580c303629523a6d4a0161a1f0f2d9382
|
Provenance
The following attestation bundles were made for cedarling_python-0.0.26-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
build-packages.yml on JanssenProject/jans
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cedarling_python-0.0.26-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
649cc7ca233e4ab20d3fdf419750aa2d0190510372ccfab004a869d9d120b2e8 - Sigstore transparency entry: 1760328105
- Sigstore integration time:
-
Permalink:
JanssenProject/jans@ed4c4317c14ceb9556ff59a95a82eed664a39b31 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JanssenProject
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-packages.yml@ed4c4317c14ceb9556ff59a95a82eed664a39b31 -
Trigger Event:
workflow_run
-
Statement type: