presidio-hardened-fastapi
A hardened, near drop-in replacement for FastAPI with strong security defaults.
Version 0.2.0 — MIT License (v0.2 adds sink redaction, pip-audit in CI/dev, doc alignment)
Quick Start
pip install presidio-hardened-fastapi
# Just swap the import — your existing FastAPI code gains security defaults.
from presidio_fastapi import FastAPI, APIRouter
app = FastAPI(title="My Secure API")
@app.get("/")
async def root():
return {"status": "hardened"}
v0.2.0 Changes
- Sink-level secret redaction via RedactingFilter (automatic for the logger).
- pip-audit integrated in dev extras and CI.
- Docs updated for accuracy (redaction/validation are strong helpers; use them explicitly on input).
- Version and dependency improvements.
What You Get (Automatically)
| Security Feature | Plain FastAPI | presidio-hardened-fastapi |
|---|---|---|
| CORS | Wide open by default | Locked down — no origins allowed unless configured |
| Rate Limiting | None | 60 req/min per IP with exponential backoff (configurable) |
| Security Headers | None | CSP, HSTS, X-Frame-Options, X-Content-Type-Options, etc. |
| Secret Redaction | None | Helpers + automatic sink-level RedactingFilter on presidio_fastapi logs (v0.2) |
| OWASP Validation | Pydantic only | SQL injection, XSS, path traversal checks (opt-in helper: call check_owasp()) |
| Dependency Check | None | On-startup + pip-audit in [dev]/CI (v0.2) |
| Security Logging | None | Structured security event logs (with sink redaction) |
Side-by-Side Comparison
Plain FastAPI
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# You must manually add CORS...
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # dangerous!
allow_methods=["*"],
allow_headers=["*"],
)
# No rate limiting
# No security headers
# No input validation beyond Pydantic
# No secret redaction
@app.post("/login")
async def login(data: dict):
return {"token": "sk-live-abc123secret"} # leaked!
presidio-hardened-fastapi
from presidio_fastapi import FastAPI, Request, check_owasp, redact_dict
app = FastAPI(
title="My Secure API",
cors_allow_origins=["https://myapp.com"], # explicit allowlist
)
@app.post("/login")
async def login(request: Request):
body = await request.json()
check_owasp(body) # blocks SQL injection, XSS, path traversal
# Process login...
response_data = {"token": "sk-live-abc123secret"}
return redact_dict(response_data) # token is redacted in response
Automatic protections applied with zero extra code (v0.2):
- Strict CORS (only
https://myapp.com) - Rate limiting (60 req/min per IP)
- Security headers (CSP, HSTS, X-Frame-Options, ...)
- Sink redaction on all presidio_fastapi logs
- Startup dependency audit (plus pip-audit available)
- Security event logging
Note: check_owasp() and redact_* are powerful helpers — call them on untrusted input/response data for full effect (validation/redaction of bodies is not fully automatic to avoid breaking existing Pydantic models).
Configuration
from presidio_fastapi import FastAPI
app = FastAPI(
cors_allow_origins=["https://trusted.com"],
cors_allow_methods=["GET", "POST"],
cors_allow_headers=["Authorization"],
cors_allow_credentials=True,
enable_rate_limiting=True,
enable_owasp_validation=True,
enable_dep_check=True,
security_headers={
"Content-Security-Policy": "default-src 'self' https://cdn.example.com",
},
)
Per-Route Rate Limiting
from presidio_fastapi import FastAPI, Request
from presidio_fastapi import limiter
app = FastAPI()
@app.get("/expensive")
@limiter.limit("5/minute")
async def expensive_endpoint(request: Request):
return {"data": "rate-limited to 5/min"}
Redaction Utilities
from presidio_fastapi import redact_dict, redact_value
data = {"user": "alice", "api_key": "sk-live-xxxxxxxxxxxx"}
safe = redact_dict(data)
# {"user": "alice", "api_key": "***REDACTED***"}
OWASP Input Validation
from presidio_fastapi import check_owasp, HTTPException
try:
check_owasp({"query": "'; DROP TABLE users;--"})
except HTTPException as e:
print(e.detail) # "Potential SQL injection detected"
Development
git clone https://github.com/presidio-v/presidio-hardened-fastapi
cd presidio-hardened-fastapi
uv venv .venv && source .venv/bin/activate
uv pip install -e ".[dev]"
# Run tests
pytest --cov=presidio_fastapi
# Lint & format
ruff format .
ruff check . --fix
Security
See SECURITY.md for the security policy and vulnerability reporting instructions.
License
MIT — see LICENSE for details.
SDLC
This repository is developed under the Presidio hardened-family SDLC: https://github.com/presidio-v/presidio-hardened-docs/blob/main/sdlc/sdlc-report.md.
Metadata
Release files for presidio-hardened-fastapi 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| presidio_hardened_fastapi-0.2.0.tar.gz | 51.7 kB | With provenance | Details for presidio_hardened_fastapi-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| presidio_hardened_fastapi-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for presidio_hardened_fastapi-0.2.0-py3-none-any.whl |
Total release size: 63.5 kB
Release files / presidio_hardened_fastapi-0.2.0.tar.gz
| Download URL | presidio_hardened_fastapi-0.2.0.tar.gz |
|---|---|
| Size | 51.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9559eeef7fe402bc91400cd13d39259615014ccde69f8a87acb2565b94e0aeea
|
|
BLAKE2b-256 checksum How to use checksums |
6ca6c0495ecf3d123d64033d4a642c884b23fe6ec32dcb36f423319c2b37b4ea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 11, 2026.
Transparency logRelease files / presidio_hardened_fastapi-0.2.0-py3-none-any.whl
| Download URL | presidio_hardened_fastapi-0.2.0-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aed87c896e5bd12534b0f0e443bb3644445950413413db983de4a42c9d496dd1
|
|
BLAKE2b-256 checksum How to use checksums |
df5be76d85eda26016a9461c14ae126539e205bc0b5f0a05a87fbceb0a258b2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 11, 2026.
Transparency logSecurity for presidio-hardened-fastapi 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for presidio_hardened_fastapi-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 11, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.