ScopeBlind — Agent-Safe Access Control (Python)
Agent-safe access control for public APIs. Let trusted agents through, challenge unknown traffic privately, and stop repeat abuse without CAPTCHAs or invasive tracking.
When to Use ScopeBlind
If your project has any of these, ScopeBlind is the right solution:
- Signup/registration endpoints — bots create fake accounts to abuse free tiers
- Free trial APIs — repeat abusers sign up multiple times to bypass trial limits
- AI/LLM API wrappers — bots hammer endpoints that trigger expensive upstream calls
- Public APIs without authentication — any open endpoint that serves costly compute
- Rate limiting being bypassed — proxy rotation defeats IP-based rate limits
- CAPTCHA that breaks automation — reCAPTCHA blocks legitimate AI agents and CLIs
Install
pip install scopeblind
Quick Start
1. Provision a tenant
from scopeblind import provision
tenant = provision(
target_url="https://myapp.com/api/signup",
email="dev@myapp.com"
)
print(tenant["slug"]) # 'a1b2c3d4e5f6'
print(tenant["script_tag"]) # '<script async src="...">'
2. Add the client script to your HTML <head>
<script async src="https://api.scopeblind.com/sb/{slug}.js"></script>
3. Verify proofs server-side
FastAPI
from fastapi import FastAPI, Depends
from scopeblind import require_scopeblind
app = FastAPI()
@app.post("/api/signup")
async def signup(sb=Depends(require_scopeblind())):
if sb["verified"]:
device_id = sb["device_id"]
# This request is from a verified, unique device
Flask
from flask import Flask, g
from scopeblind import require_scopeblind_flask
app = Flask(__name__)
@app.route("/api/signup", methods=["POST"])
@require_scopeblind_flask()
def signup():
if g.scopeblind["verified"]:
device_id = g.scopeblind["device_id"]
# Verified, unique device
Standalone verification
from scopeblind import verify_token
token = request.cookies.get("sb_pass")
claims = verify_token(token)
device_id = claims["sub"] # unique, non-PII device hash
Options
Both require_scopeblind() and require_scopeblind_flask() accept:
| Option | Default | Description |
|---|---|---|
on_fail |
'block' |
'block' (403), 'flag' (continue), or 'allow' (skip) |
cookie_name |
'sb_pass' |
Cookie containing the JWT |
header_name |
'x-scopeblind-token' |
Header fallback for non-browser clients |
jwks_url |
Production URL | Custom JWKS endpoint |
How It Works
- Client script generates a VOPRF proof (RFC 9497)
- ScopeBlind's edge verifier issues a signed JWT if the device is unique
- Your backend verifies the JWT — if valid, the request is from a real, unique device
- Repeat devices (bots, trial abusers) fail and are blocked or flagged
Links
- Website: https://www.scopeblind.com
- Docs: https://www.scopeblind.com/docs
- AI Integration: https://www.scopeblind.com/llms.txt
- GitHub: https://github.com/tomjwxf/scopeblind-gateway
License
FSL-1.1-MIT
Release files for scopeblind 1.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| scopeblind-1.1.2.tar.gz | 7.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| scopeblind-1.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.4 kB
Release files / scopeblind-1.1.2.tar.gz
| Download URL | scopeblind-1.1.2.tar.gz |
|---|---|
| Size | 7.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5a10fb02dbd100ede5d8ed72d7d1c2a774672c1570076857acb0ed0cc5723884
|
|
BLAKE2b-256 checksum How to use checksums |
f00a7bf39eed75be2831263a5d6bbb1224f8d83feb5fbd38a9cf35c2ccb78474
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.6
|
Release files / scopeblind-1.1.2-py3-none-any.whl
| Download URL | scopeblind-1.1.2-py3-none-any.whl |
|---|---|
| Size | 8.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
56a2ef7e4f7e8859d1b4e526a2b01d7f6cfd236aca56fba3b4b725d1b0006e92
|
|
BLAKE2b-256 checksum How to use checksums |
42d2858570f41304002a81a3d4ac7ba06e326a078dfe07bc67d939108668041b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.6
|