Create resources and roles with a Python policy script
Write a Python script that defines your resources and roles in code and creates them in a Permit.io environment with the Python SDK. This guide is for backend developers who keep the policy schema in source control instead of editing it in the Permit dashboard.
Prerequisites
- Python 3 and the
permitpackage installed in your project. See Check permissions with the Python SDK (asyncio). - An API key for the environment that the script changes. See Get your API key.
Structure of the policy script
The code blocks in this section show each part of the script. The full policy script combines the parts into one file.
1. Create a Permit client
Import the SDK and create a Permit client. Replace your_permit_key with your API key. The script calls the Permit API, which uses the API key to select the environment.
from permit import Permit
permit = Permit(
pdp="https://cloudpdp.api.permit.io",
token="your_permit_key",
)
2. Define resources
Define a resources list. Each item is a resource with a key, a name, and an actions dictionary. The example defines a secret resource with create, read, update, and delete actions.
resources = [
{
"key": "secret",
"name": "secret",
"actions": {
"create": {},
"read": {},
"update": {},
"delete": {},
},
}
]
3. Define roles and permissions
Define a roles list. Each role has a name and a list of permissions. Each permission names a resource and the actions that the role can perform on it. The script uses the role name as the role key.
roles = [
{
"name": "secret_manager",
"permissions": [
{
"resource": "secret",
"actions": ["create", "read", "update"]
}
]
}
]
4. Create the resources and roles
The script creates every resource first, because role permissions reference resource actions. For each role, the script converts the permissions to the resource:action format, for example secret:create, and creates the role.
The Permit client from from permit import Permit is asynchronous, so the script runs each call with asyncio.run().
import asyncio
if __name__ == "__main__":
for resource in resources:
# Creating each resource
asyncio.run(permit.api.resources.create(resource))
for role in roles:
# Processing role permissions and creating each role
role_permissions = [f"{permission['resource']}:{action}" for permission in role['permissions'] for action in permission['actions']]
role_obj = {
"name": role['name'],
"key": role['name'],
"permissions": role_permissions,
}
asyncio.run(permit.api.roles.create(role_obj))
Full policy script
The full script combines the parts. Before it creates a resource or role, the script checks whether the item exists. If get() raises PermitNotFoundError, the script creates the item. Otherwise, it prints a message and skips the item.
import asyncio
from permit import Permit, PermitNotFoundError
# This line initializes the SDK and connects your python app
permit = Permit(
pdp="https://cloudpdp.api.permit.io",
token="permit_key_",
)
roles = [
{
"name": "secret_manager",
"permissions": [
{
"resource": "secret",
"actions": [
"create","read","update"
]
}
]
}
]
resources = [
{
"key": "secret",
"name": "secret",
"actions": {
"create": {},
"read": {},
"update": {},
"delete": {},
},
}
]
async def create_policy():
for resource in resources:
try:
await permit.api.resources.get(resource["key"])
print(f"resource already exists: {resource['key']}")
except PermitNotFoundError:
await permit.api.resources.create(resource)
for role in roles:
role_permissions = [f"{p['resource']}:{a}" for p in role["permissions"] for a in p["actions"]]
try:
await permit.api.roles.get(role["name"])
print(f"role already exists: {role['name']}")
except PermitNotFoundError:
await permit.api.roles.create({"key": role["name"], "name": role["name"], "permissions": role_permissions})
if __name__ == "__main__":
asyncio.run(create_policy())
Run and verify the policy script
- Save the full script as
sync_policy.py, replacepermit_key_with your API key, and runpython sync_policy.py. - Run the script a second time. The second run prints
resource already exists: secretandrole already exists: secret_manager, and doesn't change the environment. - In the Permit dashboard, open the Policy Editor. The
secretresource and thesecret_managerrole appear, andsecret_managerhas thecreate,read, andupdatepermissions onsecret.
To add resources and roles, edit the resources and roles lists and run the script again. The script skips items that already exist, so it doesn't apply changed actions or permissions to an existing resource or role. To change an existing item, delete it first.