Django middleware for BSV blockchain authentication and payment processing
Project description
bsv-middleware
🔗 Cross-SDK Interoperability
This release ensures cross-SDK interoperability with TypeScript SDK and Go SDK (v2.0.0+). Compatible with wallet-toolbox v2.0.0+.
Installation:
pip install bsv-middleware --preThe
--preflag is required because this package depends onbsv-sdk>=2.0.0b1(beta).
A Django middleware that implements BRC-103 Peer-to-Peer Mutual Authentication via BRC-104 HTTP Transport. This library makes it easy to mutually authenticate and exchange verifiable certificates between clients and servers in a standardized way.
By layering BRC-103 on top of Django, you can:
- Perform a cryptographic handshake between two peers (your server and an external wallet/user).
- Request or respond with certificates that verify user identity or attributes.
- Enforce mutual authentication for your APIs, ensuring that each side proves its identity, without passwords or reliance on centralized authentication providers.
- Optionally enable selective disclosure of certificate fields.
Table of Contents
- Background
- Features
- Installation
- Quick Start
- Detailed Usage
- API Reference
- Examples
- Security Considerations
- Resources & References
- License
Background
BRC-103 is a specification for mutual authentication and certificate exchange over a peer-to-peer channel. It uses nonce-based challenges, digital signatures, and an optional selective disclosure mechanism for certificates. BRC-104 defines how to transport these messages specifically over HTTP, describing custom headers and the .well-known/auth endpoint.
bsv-middleware abstracts the complexities of these specs behind a typical Django middleware. It verifies BRC-103/104–compliant requests and properly signs responses, all while letting you continue to write normal Django code for your views.
Features
-
Seamless Integration
Plug straight into your existing Django application—no need for rewriting your entire HTTP handling logic. -
Mutual Authentication
Authenticates both the server and the client cryptographically, preventing impersonation or MITM attacks. -
Certificate Handling
Request, receive, and verify BRC-103 identity certificates. Includes utility methods to request additional certificates from the client. -
Selective Disclosure
Supports BRC-103's concept of revealing only certain fields in a certificate, helping to preserve privacy for you and your users while verifying necessary information. -
Extendable
Provide a customSessionManageror plug in advanced logic for verifying user attributes.
Installation
pip install bsv-middleware
This package depends on Django (3.2+ or 4.x) and a BRC-100–capable wallet (e.g., the bsv-sdk implementation or your own code).
Quick Start
Below is the minimal setup to enable BRC-103 mutual authentication in your Django server:
# settings.py
from bsv.wallet import ProtoWallet
from bsv.keys import PrivateKey
# Initialize your BSV wallet (manages keys and signs messages)
private_key = PrivateKey.from_wif('your_private_key_wif')
wallet = ProtoWallet(private_key)
# Configure BSV middleware
BSV_MIDDLEWARE = {
'WALLET': wallet,
'ALLOW_UNAUTHENTICATED': False, # Require mutual auth on every route
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# ... other middleware ...
# BSV Auth Middleware (add after Django's built-in middleware)
'bsv_middleware.django.auth_middleware.BSVAuthMiddleware',
]
# views.py
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
@require_http_methods(["GET"])
def home(request):
if hasattr(request, 'auth') and request.auth and request.auth.get('identity_key') != 'unknown':
# The request is authenticated
return JsonResponse({
'message': f"Hello, authenticated peer with public key: {request.auth['identity_key']}"
})
else:
# Not authenticated
return JsonResponse({'error': 'Unauthorized'}, status=401)
When the server receives a BRC-103 handshake or "general" message, bsv-middleware automatically handles the cryptographic checks. Once verified, request.auth['identity_key'] will hold the public key of the authenticated peer.
Detailed Usage
Creating the Middleware
The middleware is configured via Django settings. You can also use the factory function for programmatic setup:
from bsv_middleware.django.auth_middleware import create_auth_middleware
from bsv_middleware.types import AuthMiddlewareOptions
from bsv.wallet import ProtoWallet
from bsv.keys import PrivateKey
private_key = PrivateKey.from_wif('your_private_key_wif')
wallet = ProtoWallet(private_key)
options = AuthMiddlewareOptions(
wallet=wallet,
allow_unauthenticated=False
)
# This sets up Django settings and returns the middleware class
BSVAuthMiddleware = create_auth_middleware(options)
Injecting the Middleware into Django
Add the middleware to your MIDDLEWARE list in settings.py:
MIDDLEWARE = [
# ... other middleware ...
'bsv_middleware.django.auth_middleware.BSVAuthMiddleware',
]
You can also configure it programmatically if needed:
# In your Django app's ready() method or startup code
from bsv_middleware.django.auth_middleware import BSVAuthMiddleware
# The middleware reads configuration from Django settings
Handling Certificates
To request additional certificates from the client, configure certificates_to_request in your settings:
# settings.py
BSV_MIDDLEWARE = {
'WALLET': wallet,
'ALLOW_UNAUTHENTICATED': False,
'CERTIFICATE_REQUESTS': {
'certifiers': ['<33-byte-pubkey-of-certifier-hex>'],
'types': {
'age-verification': ['dateOfBirth', 'country']
}
},
'ON_CERTIFICATES_RECEIVED': on_certificates_received_callback,
}
Define your callback function:
def on_certificates_received(sender_public_key: str, certs: list, request, response, next_func):
"""
Callback invoked when certificates are received from the client.
Args:
sender_public_key: The public key of the peer sending certificates
certs: List of certificate objects
request: Django HttpRequest object
response: Django HttpResponse object
next_func: Callable to continue to next middleware/handler
"""
# You can inspect the provided certificates here
print(f"Received {len(certs)} certificate(s) from {sender_public_key}.")
# Continue to next middleware or route handler
if callable(next_func):
next_func()
In your server logic, you can then verify or store these certificates as needed. Replace fields like age-verification with an actual base64 certificate type.
Interpreting Authenticated Requests
Once a peer is authenticated, you'll have:
request.auth['identity_key']⇒ the authenticated user's 33-byte compressed public key (hex-encoded).request.body⇒ your normal request body (parsed by Django's request handling).- Standard
request.headers⇒ includesx-bsv-auth-*headers with BRC-103 handshake data (for debugging).
If allow_unauthenticated is False, any request without a valid handshake or signature is rejected with 401 automatically.
API Reference
create_auth_middleware(options: AuthMiddlewareOptions)
Returns a Django middleware class. Options:
wallet: (required) A BRC-100 object implementing your signing and verification logic (e.g.,ProtoWalletfrombsv-sdk).session_manager: (optional) Manage nonces & state across requests.allow_unauthenticated: (optional) IfTrue, non-authenticated requests are allowed but marked asidentity_key: 'unknown'.certificates_to_request: (optional) Automatic certificate request data structure.on_certificates_received: (optional) A callback triggered when certs arrive from the client.
Configuration via Django Settings
Alternatively, configure via settings.py:
BSV_MIDDLEWARE = {
'WALLET': wallet, # or 'WALLET_GETTER': callable that returns wallet
'ALLOW_UNAUTHENTICATED': False,
'CERTIFICATE_REQUESTS': {...},
'ON_CERTIFICATES_RECEIVED': callback_function,
'SESSION_MANAGER': custom_session_manager, # optional
'LOG_LEVEL': 'error', # 'debug', 'info', 'warning', 'error'
}
Examples
1. Minimal Setup
# settings.py
from bsv.wallet import ProtoWallet
from bsv.keys import PrivateKey
private_key = PrivateKey.from_wif('your_private_key_wif')
wallet = ProtoWallet(private_key)
BSV_MIDDLEWARE = {
'WALLET': wallet,
'ALLOW_UNAUTHENTICATED': False,
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'bsv_middleware.django.auth_middleware.BSVAuthMiddleware',
]
# views.py
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
@require_http_methods(["GET"])
def protected(request):
if hasattr(request, 'auth') and request.auth and request.auth.get('identity_key') != 'unknown':
return JsonResponse({'message': 'You are authenticated via BRC-103!'})
return JsonResponse({'error': 'Unauthorized'}, status=401)
2. Requesting Certificates at Handshake
# settings.py
def on_certificates_received(sender_public_key: str, certs: list, request, response, next_func):
print(f"Received certs from {sender_public_key}", certs)
if callable(next_func):
next_func()
BSV_MIDDLEWARE = {
'WALLET': wallet,
'ALLOW_UNAUTHENTICATED': False,
'CERTIFICATE_REQUESTS': {
'certifiers': ['<certifier-pubkey-hex>'],
'types': {
'someCertificateType': ['fieldA', 'fieldB']
}
},
'ON_CERTIFICATES_RECEIVED': on_certificates_received,
}
3. Complete Django Example
See the examples/django_example directory for a complete working Django project demonstrating:
- Authentication middleware setup
- Payment middleware integration
- Multiple endpoint types (free, authenticated, paid)
- Certificate handling
- View decorators for authentication and payments
Security Considerations
- TLS Encryption: Although BRC-103 messages are authenticated, the protocol does not encrypt the entire payload. It's recommended to serve your Django app over HTTPS to maintain confidentiality.
- Nonce Replay Prevention: This library implements a
SessionManagerthat automatically rejects nonces not bound by the server's private key. - Transport-Only: BRC-104's HTTP specification focuses on message authenticity, not on anonymizing request metadata.
- Certificate Revocation: BRC-103 allows for revocation references (
revocationOutpoint). Ensure your app checks the blockchain or an appropriate certificate revocation overlay service if you require strict revocation handling. - Private Key Security: Store your wallet's private key securely. Never commit private keys to version control. Consider using environment variables or Django's secret management.
Resources & References
- BRC-103 Spec – Mutual authentication & certificate exchange.
- BRC-104 Spec – HTTP Transport for BRC-103.
- bsv-sdk – BSV Python SDK (used for cryptographic utilities, wallet logic, etc.).
- Django – Web framework for Python.
License
Happy hacking! If you have questions, suggestions, or want to contribute improvements, feel free to open an issue or PR in our repository.
Project details
Release history Release notifications | RSS feed
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 bsv_middleware-2.0.2.tar.gz.
File metadata
- Download URL: bsv_middleware-2.0.2.tar.gz
- Upload date:
- Size: 75.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b76bdb0c8e03282c5e2710b00ba3da954d37c897de2e6e236b27b79e4235854e
|
|
| MD5 |
d397c72cb50c2c6d93c68c64ee9c3fb9
|
|
| BLAKE2b-256 |
b2158f85cb8a25b2006b6eecd0d2fa634a30ea42874e7cb4cd25052148187f22
|
Provenance
The following attestation bundles were made for bsv_middleware-2.0.2.tar.gz:
Publisher:
workflow.yml on bsv-blockchain/py-middleware
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bsv_middleware-2.0.2.tar.gz -
Subject digest:
b76bdb0c8e03282c5e2710b00ba3da954d37c897de2e6e236b27b79e4235854e - Sigstore transparency entry: 836337021
- Sigstore integration time:
-
Permalink:
bsv-blockchain/py-middleware@ba26c369e14ae181ed4497f41b21f521f2fccff5 -
Branch / Tag:
refs/tags/v2.0.2 - Owner: https://github.com/bsv-blockchain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@ba26c369e14ae181ed4497f41b21f521f2fccff5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bsv_middleware-2.0.2-py3-none-any.whl.
File metadata
- Download URL: bsv_middleware-2.0.2-py3-none-any.whl
- Upload date:
- Size: 49.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7fbe29b5c61adb481520062b7c53b60c1a995a1dbbaa55319e12fdf4fd48626
|
|
| MD5 |
eb3253835d7acd86b2d9b28d04edf53b
|
|
| BLAKE2b-256 |
16590841fe24195ff659911f027547e77eb12f024b30b535eb4d545727f19295
|
Provenance
The following attestation bundles were made for bsv_middleware-2.0.2-py3-none-any.whl:
Publisher:
workflow.yml on bsv-blockchain/py-middleware
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bsv_middleware-2.0.2-py3-none-any.whl -
Subject digest:
f7fbe29b5c61adb481520062b7c53b60c1a995a1dbbaa55319e12fdf4fd48626 - Sigstore transparency entry: 836337033
- Sigstore integration time:
-
Permalink:
bsv-blockchain/py-middleware@ba26c369e14ae181ed4497f41b21f521f2fccff5 -
Branch / Tag:
refs/tags/v2.0.2 - Owner: https://github.com/bsv-blockchain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@ba26c369e14ae181ed4497f41b21f521f2fccff5 -
Trigger Event:
push
-
Statement type: