Skip to main content

Python Tests (Develop)

Python Tests (Master)

Django Permafrost

Django Permafrost is an extension to Django's permissions framework. Its goal is to allow developers to expose selected permissions to client users so they can create and manage custom user roles inside a tenant or site context.

It adds:

  • A View Mixin that supports user permissions based on different HTTP method types (GET, POST, PUT, etc) for extra granular control.
  • A View Mixin that captures into Django's logging setup any failed permission checks.
  • An app that supports client user definable roles and permissions. This uses Django's underlying permission system and controls which permissions are exposed to users.
    • Developers can define required permissions for each role category and optional permissions that can be selected by the client.

For example, a SaaS platform may allow client administrators to manage other users in their account. They may want one employee to manage email lists but not invite users, while another employee can do both. Permafrost lets the developer define the permission boundaries and lets the client assemble roles inside those boundaries.

Supported versions

This release targets:

  • Python 3.11+
  • Django 5.2 through Django 6.1

Django 5.1 and older are no longer supported.

Installation

To install, use pip:

python -m pip install django-permafrost

To add it to your project, add it to the list of installed apps in your settings.py:

INSTALLED_APPS = [
    ...
    "django.contrib.contenttypes",
    "django.contrib.auth",
    "django.contrib.sites",
    "permafrost",
    ...
]

Then migrate:

python manage.py migrate

Setup

The goal of Django Permafrost is to allow clients to create their own Permafrost roles under developer-defined categories with developer-defined required and optional permissions.

An example developer-defined category looks like this:

from django.utils.translation import gettext_lazy as _

PERMAFROST_CATEGORIES = {
    "user": {
        "label": _("User"),
        "access_level": 1,
        "optional": [
            {
                "label": _("Can Add Users to Role"),
                "permission": ("add_user_to_role", "permafrost", "permafrostrole"),
            },
        ],
        "required": [
            {
                "label": _("Can add Role"),
                "permission": ("add_permafrostrole", "permafrost", "permafrostrole"),
            },
        ],
    },
}

This would be added to your Django settings.py file (or, at least, included into).

In the above, we define the User category, give it the localizable label of "User", and provide two permissions in Django's natural key format. Primary keys can differ between environments, so natural keys are safer for permission configuration.

There is also an access_level setting to help make sorting access levels more easily.

Context model

Permafrost roles are scoped to a context object. By default, that context is Django's Site model, which preserves the original subdomain/site-per-client behavior:

PERMAFROST_CONTEXT_MODEL = "sites.Site"
PERMAFROST_CONTEXT_REQUEST_ATTR = "site"

Projects that use a different tenant model can set the context model once at the beginning of the project, similar to how a custom user model is configured:

PERMAFROST_CONTEXT_MODEL = "accounts.Organization"
PERMAFROST_CONTEXT_REQUEST_ATTR = "organization"

Permafrost expects the current context object to be available on the request using PERMAFROST_CONTEXT_REQUEST_ATTR. For example, middleware might attach request.organization. If no request context is available, the configured context model must provide a manager method named get_current(). The built-in Site default uses Site.objects.get_current().

Internally, Permafrost stores the context through Django's content type framework, but each project should configure exactly one context model for the lifetime of that project.

For more detail, see the files in docs/modules/, especially installation.md and models.md.

The complete Team setup guide covers middleware, authentication backends, role assignment, request-aware checks, queryset scoping, cross-Team isolation, and superuser behavior: docs/modules/team-context.md.

Recommendations

It is recommended that you update your code to use PermafrostRole's built-in functions to add users and permissions. They add an extra level of checking to make sure the permissions passed in are allowed by the PERMAFROST_CATEGORIES configuration.

For example, permissions on a Group:

group.permissions.set([permission_list])
group.permissions.add(permission, permission, ...)
group.permissions.remove(permission, permission, ...)
group.permissions.clear()

Can be replaced with:

PermafrostRole.permissions_set([permission_list])
PermafrostRole.permissions_add(permission, permission, ...)
PermafrostRole.permissions_remove(permission, permission, ...)
PermafrostRole.permissions_clear()

Convenience tools

There is a tool to help the developer list out the permissions available in the format permafrost expects.

> ./manage permlist

using the command will produce a list like this

> ./manage.py permlist

Permlist formatted for your PermafrostRoles configuration
{'label':_('Can add email address'), 'permission': ('add_emailaddress', 'account', 'emailaddress')},
{'label':_('Can change email address'), 'permission': ('change_emailaddress', 'account', 'emailaddress')},
{'label':_('Can delete email address'), 'permission': ('delete_emailaddress', 'account', 'emailaddress')},
...

Each line can be copied into the PERMAFROST_CATEGORIES config in the correct format.

Python and HTTP APIs

Permafrost includes a DRF-independent service API:

from permafrost.api import services

role = services.create_role(
    name="Account Manager",
    category="staff",
    context_object=organization,
)
services.set_role_permissions(role, permissions)
services.add_role_users(role, [user])

The HTTP API is built with Django REST Framework and remains optional. Install the API extra to use it:

python -m pip install "django-permafrost[api]"

The HTTP API supports Django REST Framework 3.16 through 3.18 and drf-spectacular 0.30.x. The base package and Python service API do not install or require either HTTP dependency. See the API documentation for the tested compatibility pairs.

Configure the schema backend in Django settings:

REST_FRAMEWORK = {
    "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}

Then include the API URLs:

from django.urls import include, path

urlpatterns = [
    path("api/permafrost/", include("permafrost.api.urls")),
]

The version 1 endpoints are then available below /api/permafrost/v1/. Unversioned HTTP routes are not exposed. See the API documentation and versioning policy for the supported contract. The OpenAPI schema is available at /api/permafrost/v1/schema/.

Authors and contributors

  • Grant Viklund, principal author and maintainer
  • Devon Jackson, contributor

Metadata

Release files for django-permafrost 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-permafrost 0.5.0
File Size Uploaded
django_permafrost-0.5.0.tar.gz 67.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-permafrost 0.5.0
File Interpreter ABI Platform
django_permafrost-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 141.2 kB

Release files / django_permafrost-0.5.0.tar.gz

Download URL django_permafrost-0.5.0.tar.gz
Size 67.6 kB
Tags Source
SHA-256 checksum
How to use checksums
a1a585c3e695ae0a30cb74973a46505856dba38bd72136bd2f70e48e8f329764
BLAKE2b-256 checksum
How to use checksums
9b646dbe229b7ee4562dcee59ea3cab65fbd042105f94739a10792e400540257
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / django_permafrost-0.5.0-py3-none-any.whl

Download URL django_permafrost-0.5.0-py3-none-any.whl
Size 73.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3b17b067653921ca3784004244cd767b9e749b1c09085213b4577d493e811b41
BLAKE2b-256 checksum
How to use checksums
766947672c1de68d5c78ffaa742f42a2e132b63ca0538ce8ff0eb6c148a8c752
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.2.23

2 release files

0.2.22

2 release files

0.2.21

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.16

2 release files

0.2.15

2 release files

0.2.14

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.36

2 release files

0.1.34

2 release files

0.1.33

2 release files

0.1.32

2 release files

0.1.31

2 release files

0.1.26

1 release file

0.1.25

1 release file

0.1.24

1 release file

0.1.23

1 release file

0.1.22

1 release file

0.1.21

1 release file

0.1.20

1 release file

0.1.19

1 release file

0.1.18

1 release file

0.1.16

1 release file

0.1.15

1 release file

0.1.14

1 release file

0.1.13

1 release file

0.1.12

1 release file

0.1.10

1 release file

0.1.9

1 release file

0.1.8

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page