fastapi-guard
AGENTS.md825 starsChanged 24 days agoMITView on GitHub
Guidance for AI agents (including Claude Code) working in this repository. FastAPI Guard is a production-ready security library for FastAPI applications that provides: As of v5.0.0, fastapi-guard is a thin adapter over guard-core. All security logic (models, handlers, decorators, detection engine, protocols, utilities) lives in the guard_core package. This repo contains only the FastAPI/Starlette integration layer. Because FastAPI/Starlette is async, this adapter imports guard_core.* directly (the sync adapter siblings import the unasync-generated guard_core.sync.* mirror instead). All public imports go through…
We split this AGENTS.md into the rules it gives an agent
6 rules. About 0 are common, 3 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 48
All public imports go through guard:
- Very specific: line 61
This repo MUST: keep SecurityMiddleware as a thin orchestrator that delegates to SecurityCheckPipeline.
- Very specific: line 273
All run via uv run commands
- Distinctive: line 278
Run tests: before committing
- Distinctive: line 290
Use Redis for distributed rate limiting
- Distinctive: line 293
Never expose sensitive data in logs
≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
Guidance for AI agents (including Claude Code) working in this repository.
Project Overview
FastAPI Guard is a production-ready security library for FastAPI applications that provides:
- IP control and rate limiting
- Request logging and monitoring
- Penetration attempt detection
- Security headers management
- Redis-based distributed caching
- PyPI Package:
fastapi-guard - Import Name:
guard - Python Support: 3.10, 3.11, 3.12, 3.13, 3.14
- Package Manager: uv (modern Python package manager)
- Build System: Docker + Make
Ecosystem Position
As of v5.0.0, fastapi-guard is a thin adapter over guard-core. All security logic (models, handlers, decorators, detection engine, protocols, utilities) lives in the guard_core package. This repo contains only the FastAPI/Starlette integration layer.
guard-core (engine, PyPI dependency) <- all security logic
└── fastapi-guard (this repo) <- ASGI middleware adapter for FastAPI/Starlette
├── flaskapi-guard <- sibling adapter (Flask extension, sync mirror)
├── djapi-guard <- sibling adapter (Django middleware, sync mirror)
└── tornadoapi-guard <- sibling adapter (Tornado handler/middleware)Because FastAPI/Starlette is async, this adapter imports guard_core.* directly (the sync adapter siblings import the unasync-generated guard_core.sync.* mirror instead).
Package Components
guard/__init__.py- Re-exports 20+ items fromguard_coreso users canfrom guard import SecurityConfig, SecurityDecorator, ...without knowing about guard-core. Also exportsSecurityMiddlewarefromguard.middleware.guard/middleware.py-SecurityMiddlewareextends Starlette'sBaseHTTPMiddleware. It wraps StarletteRequest/Responseobjects via adapters, delegates all security checks to guard-core's pipeline, and orchestrates initialization, event dispatch, metrics, and response processing using guard-core modules (core.checks,core.events,core.initialization,core.responses,core.routing,core.validation,core.bypass,core.behavioral).guard/adapters.py- Protocol adapters that bridge Starlette types to guard-core's framework-agnostic protocols:StarletteGuardRequest(adaptsstarlette.requests.RequesttoGuardRequest),StarletteGuardResponse(adaptsstarlette.responses.ResponsetoGuardResponse),StarletteResponseFactory(creates response adapters), and the lifecycle helperswrap_call_next()/unwrap_response().guard/lifespan.py-guard_lifespan,make_lifespan, andguard_startupwarm guard-core's shared-state registry at app startup so initialization does not happen on the first request.guard/_middleware_state.py-MiddlewareStateregistry keyed on theSecurityConfiginstance and the resolved decorator handler, so two middleware instances sharing one config only share a pipeline when they resolve the same decorator handler.guard/_decorator_adoption.py- Resolves and adopts the app's registeredguard_decorator(resolve_app_state_decorator,adopt_app_state_decorator) so the pipeline can be derived from the registered route config.guard/status.py-add_status_routehelper exposing a guard status endpoint.guard/websocket.py- WebSocket support (WebSocketCloseReason, a_WebSocketGuardRequestadapter for WebSocket connections).
Public API
All public imports go through guard:
from guard.middleware import SecurityMiddleware
from guard import SecurityConfig, SecurityDecorator, RouteConfig
from guard import IPBanManager, RateLimitManager, RedisManager
from guard import GeoIPHandler, RedisHandlerProtocolBoundary Rules
- This repo MUST NOT contain security logic (checks, handlers, models, detection patterns). Those belong in guard-core. A change that looks like a security fix belongs upstream in guard-core, not here.
- This repo MUST wire Starlette/FastAPI native types to guard-core's
GuardRequest,GuardResponse, andGuardResponseFactoryprotocols viaguard/adapters.py. - This repo MUST keep
SecurityMiddlewareas a thin orchestrator that delegates toSecurityCheckPipeline; do not fork or reimplement pipeline behavior. - This repo MUST re-export new guard-core public surface from
guard/__init__.pywhen it becomes part of the adapter's user-facing API. - This repo should only change when:
- The Starlette/FastAPI adapter layer needs updates
- New guard-core exports need to be re-exported from
guard/__init__.py - FastAPI-specific middleware orchestration changes
Quick Start
# Install dependencies with uv
make install-dev
# Run tests locally
make local-test
# Start example application
make start-example
# Run linting and formatting
make fixDevelopment Commands
Package Management (uv)
make install- Install core dependenciesmake install-dev- Install with dev dependenciesmake lock- Update lock filemake upgrade- Upgrade lock dependencies and installuv sync- Sync dependencies from lock fileuv sync --extra dev- Sync with dev extrasuv run <command>- Run command in virtual environment
Testing
make test- Run tests in Docker (Python 3.10)make test-all- Test all Python versions (3.10-3.14)make test-3.11- Test specific Python versionmake local-test- Run tests locally with uvmake stress-test- Run standard stress testmake high-load-stress-test- Run high-load stress testmake live-smoke- Run the live smoke suite against a real stack
Code Quality
make lint- Run all linters in Docker (ruff, mypy)make fix- Auto-fix formatting issues with ruffmake vulture- Find dead codemake bandit- Security scanmake safety- Check dependency vulnerabilitiesmake pip-audit- Audit dependenciesmake radon- Analyze code complexitymake xenon- Check complexity thresholdsmake deptry- Analyze dependenciesmake semgrep- Static analysismake security- Run all security checks (bandit, safety, pip-audit)make quality- Run all quality checks (lint, vulture, radon, xenon)make check-all- Run everything (lint, security, quality, analysis)uv run ruff check guard/ tests/- Check with ruffuv run ruff format guard/ tests/- Format codeuv run mypy guard/- Type checking
Documentation
make serve-docs- Serve MkDocs locallymake lint-docs- Lint markdown filesmake fix-docs- Fix markdown issues
Docker Operations
make start-example- Start example app with Dockermake run-example- Build and run examplemake stop- Stop all containersmake restart- Restart servicesmake prune- Clean Docker resourcesmake clean- Clean Python cache files
Environment variables:
PYTHON_VERSION- Python version (3.10-3.14)REDIS_URL- Redis connection stringREDIS_PREFIX- Key prefix for RedisIPINFO_TOKEN- IPInfo API token
Services: fastapi-guard-example (example application), fastapi-guard (test runner), redis (cache).
Version Management
make bump-version VERSION=x.y.z- Bump package version
Project Structure
fastapi-guard/
├── guard/ # Adapter package (thin layer over guard-core)
│ ├── __init__.py # Re-exports 20+ items from guard_core + SecurityMiddleware
│ ├── middleware.py # FastAPI/Starlette SecurityMiddleware adapter
│ ├── adapters.py # Starlette request/response protocol adapters
│ ├── lifespan.py # guard_lifespan / make_lifespan / guard_startup
│ ├── _middleware_state.py # MiddlewareState registry (config + decorator keyed)
│ ├── _decorator_adoption.py # resolve/adopt the app's registered guard_decorator
│ ├── status.py # add_status_route helper
│ ├── websocket.py # WebSocket support
│ ├── .agents/skills/fastapi-guard/ # Package skill (SKILL.md + references)
│ └── py.typed # PEP 561 marker
├── tests/ # Test suite
├── examples/ # Example implementations
├── docs/ # MkDocs documentation
├── Makefile # Build automation
├── compose.yml # Docker Compose config
├── Dockerfile # Docker image definition
├── pyproject.toml # Project metadata & config
├── uv.lock # Locked dependencies
├── setup.py # Minimal (package discovery only, no version)
└── .pre-commit-config.yaml # Pre-commit hooksConfiguration Files
- pyproject.toml - Project metadata and dependencies; tool configurations for ruff, mypy, pytest; Python 3.10+ requirement
- uv.lock - Locked dependency versions for reproducible builds, updated with
make lockoruv lock - compose.yml / Dockerfile - Multi-version Python support (3.10-3.14), Redis service for testing, volume mounts for development
- .pre-commit-config.yaml - ruff format, ruff check, mypy
Technology Stack
Core Dependencies
- FastAPI - Modern async web framework
- guard-core - Framework-agnostic security engine (all security logic)
- Starlette - ASGI toolkit (FastAPI's foundation)
- uvicorn - ASGI server
Development Tools
- uv - Fast Python package manager
- pytest - Testing framework
- pytest-asyncio - Async test support
- pytest-cov - Coverage reporting
- pytest-mock - Mock fixtures
- ruff - Fast Python linter/formatter
- mypy - Static type checker
- vulture - Dead code detection
- bandit - Security linter
- radon/xenon - Complexity analysis
- deptry - Dependency analysis
- semgrep - Static analysis
- pre-commit - Git hooks
- mkdocs - Documentation generator
- mkdocs-material - MkDocs theme
- pymarkdownlnt - Markdown linter
Testing Guidelines
Running Tests
# Local testing with coverage
make local-test
# Docker testing (default Python 3.10)
make test
# Test all Python versions
make test-all
# Specific Python version
make test-3.12Test Configuration (pyproject.toml)
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
python_files = ["test_*.py"]
addopts = "--cov=guard --cov-report=term-missing"Run Specific Tests
# Run specific test file
REDIS_URL=redis://localhost:6379 uv run pytest tests/test_security_headers/test_middleware_coverage.py -v
# Run with pattern matching
REDIS_URL=redis://localhost:6379 uv run pytest -k "security_headers" -vCode Quality Standards
Ruff Configuration
- Target Python 3.10+
- Selected rules: E, F, UP, B, I
- Auto-fixable issues
MyPy Configuration
- Strict type checking enabled
- No implicit Optional
- Warn on unused configs
- Check untyped definitions
Pre-commit Workflow
- Automatic formatting with ruff
- Linting checks
- Type checking with mypy
- All run via
uv runcommands
Best Practices
- Always use uv for package management
- Run tests before committing
- Use Make commands for consistency
- Test multiple Python versions for compatibility
- Keep dependencies updated with
make upgrade - Use type hints and run mypy
- Follow ruff formatting standards
- Document changes in appropriate docs/
Security Considerations
- This is a security library - all code must be defensive
- Validate all inputs with Pydantic
- Use Redis for distributed rate limiting
- Implement proper error handling
- Log security events appropriately
- Never expose sensitive data in logs
Related Projects
- guard-core - Framework-agnostic security engine (the engine this adapter wraps): https://github.com/Guard-Core/guard-core
- flaskapi-guard - Flask extension adapter (sync mirror): https://github.com/Guard-Core/flaskapi-guard
- djapi-guard - Django middleware adapter (sync mirror): https://github.com/Guard-Core/djapi-guard
- tornadoapi-guard - Tornado handler/middleware adapter: https://github.com/Guard-Core/tornadoapi-guard
- guard-agent - Telemetry and monitoring agent: https://github.com/Guard-Core/guard-agent
- guard-core-mcp - MCP server for config validation and docs search: https://github.com/Guard-Core/guard-core-mcp
- guard-core-app - SaaS platform (API, dashboard, playground): https://github.com/Guard-Core/guard-core-app
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository2 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- docs/llms.txtllms.txt
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

