Package: cedarpy
Cedar Pythoncedarpyhelps you use the (Rust)Cedar Policylibrary from Python. You can usecedarpyto:check whether a request is authorized by theCedar Policyengineformat policiescedarpypackages are availble for the following platforms:Operating SystemProcessor ArchitecturesLinuxx86_64, aarch64Macx86_64, aarch64Windowsx86_64Note: This project isnotofficially supported by AWS or the Cedar Policy team.Using the libraryReleases ofcedarpyare available on PyPi.  You can install the latest release with:pipinstallcedarpy(See the Developing section for how to use artifacts you've built locally.)Authorizing access with Cedar policies in PythonNow you can use the library to authorize access with Cedar from your Python project using theis_authorizedfunction.  Here's an example of basic use:fromcedarpyimportis_authorized,AuthzResult,Decisionpolicies:str="//a string containing cedar policies"entities:list=[# a list of Cedar entities; can also be a json-formatted string of Cedar entities{"uid":{"__expr":"User::\"alice\""},"attrs":{},"parents":[]}# ...]request={"principal":"User::\"bob\"","action":"Action::\"view\"","resource":"Photo::\"1234-abcd\"","context":{}}authz_result:AuthzResult=is_authorized(request,policies,entities)# so you can assert on the decision like:assertDecision.Allow==authz_result.decision# or use the 'allowed' convenience methodassertauthz_result.allowed# or even via AuthzResult's attribute subscripting supportassertauthz_result['allowed']TheAuthzResultclass also provides diagnostics and metrics for the access evaluation request.See theunit testsfor more examples of use and expected behavior.Authorize a batch of requestsYou can also authorize a batch of requests with theis_authorized_batchfunction.is_authorized_batchaccepts a list of requests to evaluate against shared policies, entities, and schema.Batch authorization is oftenmuchmore efficient (+10x) than processing authorization requests one by one withis_authorized.  This is because the most expensive part of the authorization process is transforming the policies, entities, and schema into objects that Cedar can evaluate.  SeeRFC: support batch authorization requestsfor details.Here's an example of how to useis_authorized_batchand the optional request-resultcorrelation_id:batch_id:str=randomstr()requests:List[dict]=[]foraction_nameinaction_names:requests.append({"principal":f'User::"{user_id}"',"action":f'Action::"{action_name}"',"resource":f'Resource::"{resource_id}"',"context":context_keys,"correlation_id":f"authz_req::{batch_id}-{action_name}"})# ... resolve get policies, entities, schema ...# process authorizations in batchauthz_results:List[AuthzResult]=is_authorized_batch(requests=requests,policies=policies,entities=entities,schema=schema)# ... verify results came back in correct order via correlation_id ...forrequest,result,inzip(requests,authz_results):assertrequest.get('correlation_id')==result.correlation_idcedar-py returns the list ofAuthzResultobjects in the same order as the list of requests provided in the batch.The above example also supplies an optionalcorrelation_idin the request so that you can verify results are returned in the correct order or otherwise map a request to a result.Formatting Cedar policiesYou can useformat_policiesto pretty-print Cedar policies according to
convention.fromcedarpyimportformat_policiespolicies:str="""permit(principal,action == Action::"edit",resource)when {resource.owner == principal};"""print(format_policies(policies))# permit (#   principal,#   action == Action::"edit",#   resource# )# when { resource.owner == principal };DevelopingYou'll need a few things to get started:Python +3.9Rust andcargoThis project is built on thePyO3andmaturinprojects.  These projects are designed to enable Python to use Rust code and vice versa.The most common development commands are in theMakefileCreate virtual envFirst create a Python virtual environment for this project with:make venv-devIn addition to creating a dedicated virtual environment, this will installcedar-py's dependencies.If this works you should be able to run the following command:maturin--helpBuild and runcedar-pytestsEnsure thecedar-pyvirtual environment is active by sourcing it in your shell:sourcevenv-dev/bin/activateNow run:makequickThemake quickcommand will build the Rust source code withmaturinand run the project's tests withpytest.If all goes well, you should see output like:(venv-dev)swedish-chef:cedar-pyskuenzli$makequick
Performingquickbuildset-e;\maturindevelop;\pytest
📦Includinglicensefile"/path/to/cedar-py/LICENSE"🔗Foundpyo3bindings
🐍FoundCPython3.9at/path/to/cedar-py/venv-dev/bin/python
📡Usingbuildoptionsfeaturesfrompyproject.toml
Ignoringmaturin:markers'extra == "dev"'don't match your environmentIgnoring pip-tools: markers 'extra=="dev"' don'tmatchyourenvironment
Ignoringpytest:markers'extra == "dev"'don'tmatchyourenvironment
💻Using`MACOSX_DEPLOYMENT_TARGET=11.0`foraarch64-apple-darwinbydefaultCompilingcedarpyv0.1.0(/path/to/cedar-py)Finisheddev[unoptimized+debuginfo]target(s)in3.06s
📦BuiltwheelforCPython3.9to/var/folders/k2/tnw8n1c54tv8nt4557pfx3440000gp/T/.tmpO6aj6c/cedarpy-0.1.0-cp39-cp39-macosx_11_0_arm64.whl
🛠Installedcedarpy-0.1.0================================================================================================testsessionstarts================================================================================================platformdarwin--Python3.9.12,pytest-7.4.0,pluggy-1.2.0
rootdir:/path/to/cedar-py
configfile:pyproject.toml
testpaths:tests/unit
collected10items

tests/unit/test_authorize.py::AuthorizeTestCase::test_authorize_basic_ALLOWPASSED[10%]tests/unit/test_authorize.py::AuthorizeTestCase::test_authorize_basic_DENYPASSED[20%]...snip...# a bunch of tests passing - please write more!tests/unit/test_import_module.py::InvokeModuleTestFunctionTestCase::test_invoke_parse_test_policyPASSED[100%]================================================================================================10passedin0.51s=================================================================================================Integration testsThis project supports validating correctness with official Cedar integration tests. To run those tests you'll need to retrieve thecedar-integration-testsdata with:makesubmodulesThen you can run:makeintegration-testscedar-pycurrently passes 69 of the 82 tests defined in theexample_use_cases_doc,multi,ip, anddecimalsuites. (The pass rate is actually higher, but we skip some tests that pass due to the way test suites are loaded.)  Seetest_cedar_integration_tests.pyfor details.Using locally-built artifactsIf you usedmake quickabove, then a development build of thecedarpymodule will already be installed in the virtual environment.If you want to use your localcedarpychanges in another Python environment, you'll need to build a release with:makereleaseThe release process will build a wheel and output it intotarget/wheels/Now you can install that file with pip, e.g.:pipinstall--force-reinstall/path/to/cedar-py/target/wheels/ccedarpy-*.whlContributingThis project is in its early stages and contributions are welcome. Please check the project's GitHubissuesfor work we've already identified.Some ways to contribute are:Use the project and report experience and issuesDocument usage and limitationsEnhance the library with additional functionality you needAdd test cases, particularly those fromcedar-integration-testsYou can reach people interested in this project in the#cedar-pychannel of theCedar Policy Slack workspace.