Skip to main content

CrimsonForge Library

A reusable Django library for validating JWT tokens issued by the CrimsonForge Web App backend using Ed25519 public key verification.

Public source for noncommercial use under PolyForm Noncommercial 1.0.0. Commercial use requires a separate written license from Crimson Forge, LLC.

Features

  • Ed25519 JWT Verification: Secure asymmetric signature verification using public keys
  • Automatic Key Fetching: Public keys are automatically fetched from the WA backend
  • Key Caching: Public keys are cached to minimize API calls
  • Key Rotation Support: Automatic handling of key rotation via kid header
  • Django Middleware: Automatic authentication on all requests
  • View Decorators: Easy authentication and permission enforcement
  • Team Isolation: Built-in support for multi-tenant applications
  • Proof of Possession: Browser handshake and per-request proofs backed by Redis

Installation

Requires Python 3.10 or newer and Django 5.2.17 or newer. Django REST Framework integrations use the optional drf extra. PoP requires a Redis service.

From Source

git clone --branch main https://github.com/CrimsonForge-io/crimsonforge-library.git
cd crimsonforge-library
python -m pip install .

From PyPI (After Publication)

Version 2.5.6 is prepared for review; it has not been published yet. Once published:

python -m pip install crimsonforge==2.5.6

For Django REST Framework integrations, install crimsonforge[drf]==2.5.6. Until publication, the built wheel can also be installed directly with pip.

Stable releases come from main; development releases come from dev and use versions such as 2.5.7.dev0. Pin the exact version in each deployment. To enforce the selection at Django startup, configure:

# Production
CRIMSONFORGE_LIBRARY_CHANNEL=main
CRIMSONFORGE_LIBRARY_VERSION=2.5.6

# Development (with crimsonforge==2.5.7.dev0 installed)
CRIMSONFORGE_LIBRARY_CHANNEL=dev
CRIMSONFORGE_LIBRARY_VERSION=2.5.7.dev0

Set one pair for the environment. A wrong channel or version stops Django startup. These settings select the library release; configure the matching CrimsonForge webapp API URL separately. Existing integrations can omit them until they adopt release pinning.

Quick Start

1. Configure Django Settings

Add the middleware and configure the WA backend URL:

# settings.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # Authenticate before verifying proof of possession
    'crimsonforge.auth.JWTAuthMiddleware',
    'crimsonforge.pop.PoPAuthMiddleware',
    # ... other middleware
]

# CrimsonForge configuration
CRIMSONFORGE = {
    'team_id': 'your-team-uuid',  # Required - get from Settings > Backend Configuration
    'service_name': 'king_phisher',  # Your service name
    'exempt_paths': ['/health/', '/status/'],  # Paths without auth
    'require_auth': True,  # Return 401 for missing tokens
    'pop_redis_url': 'redis://localhost:6379/0',
    # 'wa_backend_url': 'https://api.crimsonforge.io/api',  # Default, override if needed
    # 'public_key_cache_ttl': 3600,  # Cache public key for 1 hour (default)
}

# Or use environment variables:
# CRIMSONFORGE_TEAM_ID=your-team-uuid  (Required)
# CRIMSONFORGE_SERVICE_NAME=king_phisher
# CRIMSONFORGE_WA_BACKEND_URL=https://api.crimsonforge.io/api  (optional, this is the default)
# CRIMSONFORGE_SERVICE_CLIENT_ID=credential-uuid  (for machine-initiated WA calls)
# CRIMSONFORGE_SERVICE_CLIENT_SECRET=show-once-secret
# CRIMSONFORGE_POP_REDIS_URL=redis://localhost:6379/0

Add crimsonforge to INSTALLED_APPS and run python manage.py migrate when integrating it into an existing Django application. The package includes its historical migrations, including removal of the retired local team-key cache.

Your application must expose its PoP handshake POST route and protect it with JWT authentication while exempting it from the per-request PoP proof check. See the existing KP integration for application routing. The library supplies handshake helpers; installing it does not add application URL routes.

Machine-initiated calls use the client credential only at the WA backend's token exchange. The library caches the returned 15-minute JWT, renews it up to 60 seconds early, briefly backs off when an early refresh fails, and performs one coordinated forced refresh after a 401. The durable client secret is never sent to application endpoints.

2. Protect Your Views

Use decorators to enforce authentication:

# views.py

from django.http import JsonResponse
from crimsonforge.decorators import require_authenticated, require_admin

@require_authenticated
def list_campaigns(request):
    """List all campaigns for the authenticated team."""
    team_id = request.team_id  # Automatically set by middleware
    user_id = request.user_id
    email = request.email

    campaigns = Campaign.objects.filter(team_id=team_id)
    return JsonResponse({
        'campaigns': [c.to_dict() for c in campaigns]
    })

@require_admin
def admin_settings(request):
    """Admin-only endpoint."""
    # Only users with team_role='admin' can access
    return JsonResponse({'settings': {...}})

3. Access Token Data in Views

The middleware attaches token data to every authenticated request:

def my_view(request):
    if request.is_authenticated:
        user_id = request.user_id
        team_id = request.team_id
        email = request.email

        # Access full token for more details
        token = request.token
        is_admin = token.is_admin()
        mfa_verified = token.mfa_verified

Architecture

Token Flow

  1. User authenticates via WebAuthn on the WA backend
  2. WA backend issues JWT signed with Ed25519 private key
  3. Frontend stores JWT and sends with all API requests
  4. Your backend validates JWT using public key from WA backend
  5. Public key is cached for performance (1 hour TTL)
  6. Key rotation is handled automatically via kid header

JWT Token Structure

{
  "alg": "EdDSA",
  "typ": "JWT",
  "kid": "key-id-uuid"
}
{
  "sub": "user-uuid",
  "email": "user@example.com",
  "team_id": "team-uuid",
  "team_role": "admin",
  "mfa": true,
  "exp": 1234567890,
  "iat": 1234565090
}

API Reference

Middleware

JWTAuthMiddleware

Validates tokens and attaches authentication data to request:

  • request.token - AccessToken object (or None)
  • request.team_id - Team ID from token (or None)
  • request.user_id - User ID from token (or None)
  • request.email - Email from token (or None)
  • request.is_authenticated - Boolean

Configuration options:

  • team_id - Team ID this backend serves (required)
  • wa_backend_url - URL of WA backend (default: https://api.crimsonforge.io/api)
  • exempt_paths - List of paths to skip auth check
  • require_auth - If True, return 401 for missing tokens
  • public_key_cache_ttl - Cache TTL in seconds (default: 3600)

Decorators

@require_authenticated

Requires a valid authentication token.

@require_authenticated
def my_view(request):
    ...

@require_admin

Requires admin team role.

@require_admin
def admin_view(request):
    ...

@require_permission(permission)

Requires a specific permission string.

@require_any_permission(permissions)

Requires at least one permission from a list.

@require_all_permissions(permissions)

Requires all permissions from a list.

Token Validation

validate_token(token_string)

Manually validate a JWT token:

from crimsonforge.tokens import validate_token

try:
    token = validate_token(jwt_string)
    print(f"User: {token.user_id}, Team: {token.team_id}")
except TokenValidationError as e:
    print(f"Invalid token: {e}")

Settings Access

settings.fetch_jwt_public_key(force_refresh=False)

Fetch the public key from WA backend:

from crimsonforge.settings import settings

key_data = settings.fetch_jwt_public_key()
# Returns: {'public_key': '-----BEGIN...', 'algorithm': 'EdDSA', 'kid': 'uuid'}

Testing

Run the test suite:

cd crimsonforge-library
python -m pip install -e ".[dev]"
python -m pytest

Or with coverage:

python -m pytest --cov=crimsonforge --cov-report=html

Security Considerations

  • Public Key Verification: Tokens are verified using Ed25519 public keys fetched from the WA backend
  • No Shared Secrets: Unlike HS256, the private key never leaves the WA backend
  • Key Rotation: Keys are rotated automatically; the library handles this via kid matching
  • Team ID Validation: The middleware validates that the JWT's team_id matches the configured team_id
  • HTTPS Only: Always use HTTPS in production
  • Token Expiration: Tokens expire after 15 minutes (enforced by JWT exp claim)
  • Machine Credential Isolation: Durable client secrets are hashed at rest and exchanged only for short-lived, audience-bound access JWTs
  • Team Isolation: The middleware enforces team isolation; only users from the configured team can access

About Team ID

The team_id configuration is not a secret. It simply identifies which team this backend instance serves. Think of it as a filter that ensures:

  1. Users from other teams cannot access your backend (even with valid JWTs)
  2. Each backend instance is explicitly bound to one team

Get your team ID from the CrimsonForge web app at Settings > Backend Configuration.

License

Copyright (c) 2026 Crimson Forge, LLC. Licensed under PolyForm Noncommercial 1.0.0. Use, modification, and distribution are permitted for the purposes specified by that license. Commercial use requires a separate written license. Preserve NOTICE and the license when distributing copies or modifications.

See the release guide for building packages and the manual TestPyPI/PyPI publishing workflow. Publication requires explicit release action.

Metadata

Release files for crimsonforge 2.5.6

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

Source distribution (sdist)

Source distribution for crimsonforge 2.5.6
File Size Uploaded Provenance Actions
crimsonforge-2.5.6.tar.gz 90.0 kB With provenance Details for crimsonforge-2.5.6.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for crimsonforge 2.5.6
File Interpreter ABI Platform Actions
crimsonforge-2.5.6-py3-none-any.whl Python 3 none any Details for crimsonforge-2.5.6-py3-none-any.whl

Total release size: 154.2 kB

Release files / crimsonforge-2.5.6.tar.gz

Download URL crimsonforge-2.5.6.tar.gz
Size 90.0 kB
Tags Source
SHA-256 checksum
How to use checksums
cebb2f4100051df14fc9685647044d5558dfd6c1218c2211bb091afe0df1514a
BLAKE2b-256 checksum
How to use checksums
fe0963dcfde01a831ae6f94b53a361b25a8a381b5063b25bc2790179dc65df06
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 Oct 6, 2026.

Transparency log

Release files / crimsonforge-2.5.6-py3-none-any.whl

Download URL crimsonforge-2.5.6-py3-none-any.whl
Size 64.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
88c7df643020cf1099bfd120120d7d96cd1f2ccc3c3b02bdfdac02b6610f87a5
BLAKE2b-256 checksum
How to use checksums
315aa66cceb7c8e7e478d02758f552a6f51d41b8ac7bf94338b122c276ef25de
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 Oct 6, 2026.

Transparency log

Security for crimsonforge 2.5.6

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for crimsonforge-2.5.6.tar.gz

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 Oct 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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