Django, Flask and FastAPI
Before you start
Section titled “Before you start”A firewall integration enforces the signed policy bundle of your site in front of your origin: block, redirect, challenge and token-gated routes. It fetches the bundle from GET /v1/policies/<site key>, verifies its signature offline and decides every request the same way in every language. It does not replace verifying tokens in your own code. A request that reaches your origin another way (a direct IP, another hostname, a path the integration was not installed on) is never evaluated, so let only the integration reach the origin. See firewall policies.
The secret key (rgsk_...) is needed only for requireToken rules. Without it such a rule applies its onError setting.
Install and mount
Section titled “Install and mount”Package revokegpt-firewall (Python 3.15 or later; dependencies cryptography and httpx). It is a native port of the core and passes every row of the shared policy test vectors.
Django (put the middleware FIRST):
# Put the middleware FIRST: nothing may read request.headers before it.MIDDLEWARE = [ "revokegpt_firewall.django.RevokeGPTMiddleware", "django.middleware.security.SecurityMiddleware",]REVOKEGPT = {"site_key": "rgpk_...", "secret_key": "rgsk_..."}FastAPI / Starlette (wrap the app OUTERMOST):
from fastapi import FastAPIfrom revokegpt_firewall import Configfrom revokegpt_firewall.asgi import RevokeGPTASGI
fastapi_app = FastAPI()cfg = Config(site_key="rgpk_...", secret_key="rgsk_...")app = RevokeGPTASGI(fastapi_app, cfg) # wrap the app OUTERMOSTA plain WSGI app can use revokegpt_firewall.wsgi.WSGIFirewall(app, cfg).
from flask import Flaskfrom revokegpt_firewall import Configfrom revokegpt_firewall.flask import init_app
app = Flask(__name__)cfg = Config(site_key="rgpk_...", secret_key="rgsk_...") # or Config.from_env()init_app(app, cfg) # wraps app.wsgi_app, so it runs before Werkzeug touches the pathKeep routing case-sensitive
Section titled “Keep routing case-sensitive”Firewall rules match paths case-sensitively, so /ADMIN is not /admin. If your origin routes case-insensitively (IIS, a case-folding proxy or framework), /ADMIN can reach the /admin handler while a rule on /admin never sees it. Make the origin case-sensitive, or write a rule for each spelling it serves.