Machine-to-machine API key authentication for Django REST Framework
Project description
django_machine_auth
django_machine_auth is a machine-to-machine authentication framework for Django REST Framework using API keys and module-scoped permissions.
Navigation
- Quickstart: install, configure, define module, protect viewset
- Architecture: auth flow, permission resolution, and sync model
- Operations: rotation, logging mode, and monitoring guidance
- Troubleshooting: common setup and runtime issues
Features
- API key auth with
Authorization: machine_auth <api_key> - Module-driven permission model (
module.crud+module.action.method) - SHA256 key storage (raw keys are never persisted)
- Cache-first authentication payload lookups
- DB-backed permission registry (
MachinePermission) - Permission sync and documentation commands
- Optional request logging middleware with configurable privacy mode
- DRF-compatible throttling and permission classes
Installation
pip install django_machine_auth
Configure Django
Add app to INSTALLED_APPS:
INSTALLED_APPS = [
# ...
"django_machine_auth",
]
Optional settings:
MACHINE_AUTH = {
"KEY_PREFIX": "mac_", # default: mac_
"ENABLE_REQUEST_LOGGING": False, # default: False
"LOGGING_MODE": "redacted", # raw | redacted | metadata_only
"CACHE_TIMEOUT": 3600, # default: 3600 seconds
}
Define module permissions
Create <your_app>/api_key_perm.py:
from django_machine_auth.decorators import api_key_module
@api_key_module("users", label="User Management")
class UsersModule:
crud = ["view", "create", "update", "delete"]
actions = {
"profile": ["get", "post"],
}
Protect DRF endpoints
from rest_framework.decorators import action
from rest_framework.response import Response
from django_machine_auth.views import MachineAuthViewSet
class UserMachineViewSet(MachineAuthViewSet):
module = "users"
def list(self, request):
return Response({"ok": True})
@action(detail=False, methods=["get"])
def profile(self, request):
return Response({"ok": True})
Permission mapping
list,retrieve->module.viewcreate->module.createupdate,partial_update->module.updatedestroy->module.delete- Custom action ->
module.<action>.<http_method_lower>
Management commands
Sync code-defined permissions into DB:
python manage.py machine_auth_sync
python manage.py machine_auth_sync --dry-run
Print permission documentation:
python manage.py machine_auth_permissions
Admin token creation API (DRF)
Use MachineAPIKeyManagementViewSet for admin-only key issuance.
Simplest URL wiring:
from django.urls import include, path
urlpatterns = [
path("machine-auth/", include("django_machine_auth.urls")),
]
This exposes:
POST /machine-auth/machine-api-keys/
Required request fields:
nameuser(user id)permissions(list of permission strings fromMachinePermission)
Optional:
expires_at
Example request payload:
{
"name": "Gov Portal",
"user": 5,
"permissions": ["users.view", "users.create"],
"expires_at": "2026-12-31T23:59:59Z"
}
Response includes raw_api_key once. Store it securely; only hash is persisted.
Architecture overview
Runtime request flow:
MachineAPIKeyAuthenticationparses and validates auth header.- Hash lookup checks cache first, then DB fallback.
MachineAuthPermissionresolves action/method permission.MachineAPIKeyRateThrottleapplies per-key throttle scope.- Optional
MachineAuthLoggingMiddlewarewrites request log entry.
Logging modes
raw: stores full request/response payload snapshotsredacted: masks sensitive keys (authorization,password,token,secret,api_key)metadata_only: stores only metadata (status, url, method, timing, ip)
Enable middleware when needed:
MIDDLEWARE = [
# ...
"django_machine_auth.middleware.logging_middleware.MachineAuthLoggingMiddleware",
]
Security and operations
- Rotate API keys periodically.
- Use short expiry windows for integration keys where possible.
- Keep logging mode as
redactedormetadata_onlyin production. - Run
machine_auth_syncas part of deploy/startup checks after module permission changes.
Detailed operations guide: docs/OPERATIONS.md.
Troubleshooting
No default throttle rate set for 'machine_api_key':- Add
REST_FRAMEWORK.DEFAULT_THROTTLE_RATES.machine_api_key.
- Add
Module '<name>' used by <ViewSet> is not registered:- Ensure
<app>/api_key_perm.pyexists and module name matchesview.module.
- Ensure
Action "<action>" ... not defined in module:- Add action/method mapping in
api_key_perm.py.
- Add action/method mapping in
- Permission denied for custom action:
- Confirm API key includes exact
module.action.methodstring.
- Confirm API key includes exact
Local test workflow
python -m venv .venv
.venv/bin/python -m pip install -e ".[test]"
.venv/bin/pytest -q
Release and upgrade docs
- Changelog:
CHANGELOG.md - Upgrade guide:
UPGRADING.md
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 django_machine_auth-0.1.0.tar.gz.
File metadata
- Download URL: django_machine_auth-0.1.0.tar.gz
- Upload date:
- Size: 27.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ee717823d6466b1d58e3c36f490bc55e5b5fa45b8f240f0384b08b7d1b16c7f
|
|
| MD5 |
69f6fb0356cff1272a1075b6eae4a9e4
|
|
| BLAKE2b-256 |
e78cae47b7ac2693bd488e293965a68cb92aa07a489403e0390138e91e44bd54
|
File details
Details for the file django_machine_auth-0.1.0-py3-none-any.whl.
File metadata
- Download URL: django_machine_auth-0.1.0-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91c453a9dcb5d161853daebe87f80df0ecf895070a3c8c2b6549e21d25724184
|
|
| MD5 |
3ec34e9171fe872c4747ae75d4518062
|
|
| BLAKE2b-256 |
b806d1f371aa21de8450ab7d4527d62d3406b22c9c0b3d172d6a869feb630d6d
|