Skip to main content

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.view
  • create -> module.create
  • update, partial_update -> module.update
  • destroy -> 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:

  • name
  • user (user id)
  • permissions (list of permission strings from MachinePermission)

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:

  1. MachineAPIKeyAuthentication parses and validates auth header.
  2. Hash lookup checks cache first, then DB fallback.
  3. MachineAuthPermission resolves action/method permission.
  4. MachineAPIKeyRateThrottle applies per-key throttle scope.
  5. Optional MachineAuthLoggingMiddleware writes request log entry.

Logging modes

  • raw: stores full request/response payload snapshots
  • redacted: 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 redacted or metadata_only in production.
  • Run machine_auth_sync as 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.
  • Module '<name>' used by <ViewSet> is not registered:
    • Ensure <app>/api_key_perm.py exists and module name matches view.module.
  • Action "<action>" ... not defined in module:
    • Add action/method mapping in api_key_perm.py.
  • Permission denied for custom action:
    • Confirm API key includes exact module.action.method string.

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

django_machine_auth-0.1.0.tar.gz (27.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_machine_auth-0.1.0-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

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

Hashes for django_machine_auth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9ee717823d6466b1d58e3c36f490bc55e5b5fa45b8f240f0384b08b7d1b16c7f
MD5 69f6fb0356cff1272a1075b6eae4a9e4
BLAKE2b-256 e78cae47b7ac2693bd488e293965a68cb92aa07a489403e0390138e91e44bd54

See more details on using hashes here.

File details

Details for the file django_machine_auth-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_machine_auth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 91c453a9dcb5d161853daebe87f80df0ecf895070a3c8c2b6549e21d25724184
MD5 3ec34e9171fe872c4747ae75d4518062
BLAKE2b-256 b806d1f371aa21de8450ab7d4527d62d3406b22c9c0b3d172d6a869feb630d6d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page