Metadata-Version: 2.4
Name: bpc-server
Version: 1.0.0
Summary: Python server-side middleware for BPC (Bound Pair Credentials) — FastAPI and Flask request verification
Project-URL: Homepage, https://selfconnect.ai
Project-URL: Repository, https://github.com/rblake2320/bpc-protocol
Project-URL: Documentation, https://github.com/rblake2320/bpc-protocol/tree/main/packages/bpc-server
Author-email: SelfConnect <hello@selfconnect.ai>
License: MIT
Keywords: authentication,bpc,cryptography,fastapi,flask,middleware,selfconnect
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.9
Requires-Dist: cryptography>=41.0.0
Provides-Extra: all
Requires-Dist: fastapi>=0.100.0; extra == 'all'
Requires-Dist: flask>=2.0.0; extra == 'all'
Requires-Dist: starlette>=0.27.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: bpc-client>=1.0.0; extra == 'dev'
Requires-Dist: fastapi>=0.100.0; extra == 'dev'
Requires-Dist: flask>=2.0.0; extra == 'dev'
Requires-Dist: httpx>=0.24.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.100.0; extra == 'fastapi'
Requires-Dist: starlette>=0.27.0; extra == 'fastapi'
Provides-Extra: flask
Requires-Dist: flask>=2.0.0; extra == 'flask'
Description-Content-Type: text/markdown

# bpc-server

Python server-side middleware for the **BPC (Bound Pair Credentials)** protocol. Verifies BPC-signed requests in FastAPI and Flask applications using the full 12-step pipeline from the BPC spec v1.0.

## Install

```bash
pip install bpc-server[fastapi]   # FastAPI + Starlette
pip install bpc-server[flask]     # Flask
pip install bpc-server[all]       # Both
```

## FastAPI

```python
from fastapi import FastAPI, Request
from bpc_server import BPCFastAPIMiddleware, InMemoryPairRegistry, PairRecord

app = FastAPI()
registry = InMemoryPairRegistry()

# Register a pair (in production, load from your database)
registry.register(PairRecord(
    pair_id="pair_abc123",
    name="my-agent",
    scope="read-write",
    mode="development",
    public_key_jwk={...},  # from bpc-client registration
    secret_hash="argon2id_hash_here",
))

app.add_middleware(BPCFastAPIMiddleware, registry=registry)

@app.get("/api/data")
async def get_data(request: Request):
    pair = request.state.bpc_pair  # BPCVerificationResult
    return {"pair_id": pair.pair_id, "scope": pair.pair.scope}
```

## Flask

```python
from flask import Flask, g
from bpc_server import BPCFlaskMiddleware, InMemoryPairRegistry

app = Flask(__name__)
registry = InMemoryPairRegistry()
BPCFlaskMiddleware(app, registry=registry)

@app.route("/api/data")
def get_data():
    return {"pair_id": g.bpc_pair_id}
```

## Standalone Verifier

```python
from bpc_server import BPCVerifier, InMemoryPairRegistry, InMemoryNonceStore

verifier = BPCVerifier(registry=registry, nonce_store=InMemoryNonceStore())
result = verifier.verify(headers=request.headers, method="GET", path="/api/data")
if not result.ok:
    return 401, result.error_code
```

## 12-Step Verification Pipeline

1. Headers present (`X-BPC-Pair-ID`, `X-BPC-Signature`, `X-BPC-Signed-Data`, `X-BPC-Version`)
2. Pair exists and is active (not revoked, not expired)
3. Pair not locked out
4. Decode and parse canonical payload
5. Protocol version check (`"1.0"`)
6. Timestamp within ±60s window
7. Nonce not seen before (replay prevention)
8. Method and path match payload
9. Body hash match (SHA-256)
10. ECDSA-SHA-256 signature valid
11. Scope enforcement (`read` / `read-write` / `admin`)

See the [full spec](https://github.com/rblake2320/bpc-protocol/blob/main/spec/bpc-spec-v1.md).
