Skip to main content

AttestSeal trust attestation headers for x402 / AP2 / MPP payment protocols. Drop-in middleware for FastAPI/Flask/aiohttp servers and a verifier for httpx/aiohttp clients.

Project description

attestseal-x402

AttestSeal trust attestation headers for x402, AP2, and MPP payment protocols. Drop-in middleware for FastAPI, Flask, and aiohttp servers, plus a verifier for httpx and aiohttp clients.

This is the reference implementation of the X-AttestSeal-* HTTP Header Specification.

Install

pip install attestseal-x402

Optional extras for framework-specific helpers:

pip install 'attestseal-x402[fastapi]'
pip install 'attestseal-x402[flask]'
pip install 'attestseal-x402[aiohttp]'

Server: stamp X-AttestSeal-* on your 402 responses

FastAPI / Starlette:

from fastapi import FastAPI, Response
from attestseal_x402.server import asgi_middleware, AttestationFetcher

app = FastAPI()
fetcher = AttestationFetcher()                                 # 24h cache by default
app.add_middleware(asgi_middleware, domain="merchant.example", fetcher=fetcher)

@app.get("/paid-resource")
def paid_resource():
    return Response(
        status_code=402,
        content='{"scheme":"x402","amount":"0.10","currency":"USD"}',
        media_type="application/json",
        headers={"Accept-Payment": "x402; scheme=base-usdc; amount=0.10"},
    )

Flask:

from flask import Flask, jsonify
from attestseal_x402.server import flask_after_request

app = Flask(__name__)
app.after_request(flask_after_request("merchant.example"))

@app.get("/paid-resource")
def paid_resource():
    body = jsonify(scheme="x402", amount="0.10", currency="USD")
    body.status_code = 402
    body.headers["Accept-Payment"] = "x402; scheme=base-usdc; amount=0.10"
    return body

The middleware fetches your domain's attestation from https://api.attestseal.com/v1/check/<domain> once per cache TTL (default 24 hours) and stamps the headers on every 402 response.

Client: verify before paying

import httpx
from attestseal_x402 import AttestationVerifier

verifier = AttestationVerifier(allowed_issuers={"did:web:attestseal.com"})

resp = httpx.get("https://merchant.example/paid-resource")
if resp.status_code == 402:
    result = verifier.verify_response_headers(
        resp.headers, request_url=str(resp.url),
    )
    if result.ok:
        # Apply policy keyed on assuranceBasis
        if result.attestation.assurance_basis == "well_known_tranco_anchor":
            pay(result.attestation, limit=5.00)
        elif result.attestation.assurance_basis == "kyc_verified":
            pay(result.attestation, limit=None)
        elif result.attestation.assurance_basis in {"tracking", "not_recommended"}:
            refuse()
        else:
            ask_user(result.attestation)
    else:
        # Verification failed; fall back to the AttestSeal API for a fresh check
        fallback_check(resp.url)

Reasons that come back as result.reason when verification fails: missing_required_header, domain_mismatch, expired, issuer_not_allowed, did_resolution_failed, key_not_found, bad_signature. Fall-back-to-API is the recommended response for everything except domain_mismatch and bad_signature, which suggest active tampering.

Architecture

attestseal_x402/
  attestation.py     -- Attestation dataclass + canonical signing form (SHA-256 over sorted-keys JSON)
  headers.py         -- X-AttestSeal-* names + (de)serialization
  did_resolver.py    -- did:web fetch + 24h TTL cache + Ed25519 key extraction
  client.py          -- AttestationVerifier (one entrypoint: verify_response_headers)
  server.py          -- AttestationFetcher + ASGI middleware + Flask hook

The same canonical signing form is used by the production AttestSeal API, so attestations issued by did:web:attestseal.com verify with this client.

Testing

pip install 'attestseal-x402[test]'
pytest tests/

The test suite covers signing-form stability across header round-trips, signature tampering detection, expiry, issuer allow-listing, and domain-mismatch rejection.

Spec compatibility

This package implements X-AttestSeal-* spec version 0.1.0. See spec/X-ATTESTSEAL-HEADERS.md in the main repo for the full protocol document. Compatibility is maintained across patch and minor versions of the spec; major version changes (signing form, required headers) will be published as attestseal-x402 major version bumps.

License

MIT. See LICENSE in the package root.

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

attestseal_x402-0.1.0.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

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

attestseal_x402-0.1.0-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

Details for the file attestseal_x402-0.1.0.tar.gz.

File metadata

  • Download URL: attestseal_x402-0.1.0.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for attestseal_x402-0.1.0.tar.gz
Algorithm Hash digest
SHA256 857da504a60c715a0db72084ce196367bc206ca81577a1fdb95f38fc4980df93
MD5 14f6ee519789b6f1889c742fde270cdc
BLAKE2b-256 293d07776cc272e5630ee11350c21e875bac1f43b720bf99dcc72768028b13d6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for attestseal_x402-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 49a74644e0a8cc116e26b77636f01e0691a6fc76f2b9553d841990c9e2e6af4c
MD5 855825a95c453d4b108c05aa169c6434
BLAKE2b-256 752fa2bed7ae678f2f52eb04fc020a85e49a8fe67ed2b4d44af679e1bb50fa46

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