Who Guard Core is actually for
Most "why you need security middleware" posts lead with the same pitch: WAF, rate limiting, OWASP Top 10, check. Fine. But that pitch skips over the people who actually reach for Guard Core first, and the reasons they pick it aren't always the generic ones.
Here's who we actually see using it, and what feature solves their specific problem.
1. The stealth-mode builder
You're pre-launch. The API lives on the public internet because your dev team needs to hit it from laptops, CI, and a half-dozen preview environments, but the product isn't announced. You don't want it indexed, probed, or added to someone's scanner corpus before you're ready.
Edge products assume you want traffic. They're tuned for protecting public surfaces. That's the opposite of what you need.
What helps: IP allowlists + country allowlists + passive mode for the endpoints you're still debugging.
from guard import SecurityMiddleware, SecurityConfig
config = SecurityConfig(
whitelist=["203.0.113.0/24"],
whitelisted_countries=["US", "AR"],
passive_mode=True,
)
app.add_middleware(SecurityMiddleware, config=config)
Passive mode logs everything that would have been blocked, so you can tune rules against real traffic before flipping the switch to active.
2. The gaming / casino operator with hard limits
You have business rules that have to hold. Max $X won per user per hour. Max N bets per session. No session reopens within M minutes of a big win. These aren't WAF rules. They're application-layer invariants, and if they break, you're losing real money or tripping a regulator.
Generic rate limiters don't care about your user identity or session state. They see IPs and count them. That's not what you need here.
What helps: per-endpoint rate limits scoped to an identity key you define (user ID, session, license, whatever), plus custom validators for the business logic.
@app.post("/bet")
@guard.rate_limit(times=30, seconds=60, key_func=lambda req: req.state.user_id)
@guard.custom_validator(check_session_cooldown)
async def place_bet(request: Request):
...
The key_func means "rate-limit per authenticated user, not per IP", which is the right primitive when users connect from phones, laptops, and corporate VPNs in the same session.
3. The game backend running anti-cheat-adjacent checks
Your multiplayer server has endpoints that legitimate clients hit in predictable patterns. Scoring, loadout saves, leaderboard pushes. When a client is hammering /score/submit 100x faster than the game loop allows, it's a modded client. You want to drop the request and flag the account, not just rate-limit.
What helps: behavioral detection + honeypot endpoints + custom validators that know your protocol.
@app.post("/login")
@guard.honeypot_detection(trap_fields=["captcha_token_v1", "legacy_client_id"])
async def login(payload: LoginRequest):
...
captcha_token_v1 looks like a real field to a bot scraping your form. Real clients never send it. They use the current field. Any request that includes it is lying about being a real client.
4. The honeypot / threat researcher
You're deliberately running exposed endpoints to collect scanner traffic. You want every probe logged with full request context, but you don't want the honeypot server itself to get knocked over by the scans you're trying to study.
What helps: passive mode + telemetry agent + per-path dynamic rules you can update at runtime when a campaign escalates.
config = SecurityConfig(
enable_agent=True,
agent_api_key=...,
agent_project_id=...,
agent_buffer_size=2000,
passive_mode=True,
)
app.add_middleware(SecurityMiddleware, config=config)
The agent buffers events locally and ships them to the cloud dashboard. When a scanner comes through at 500 req/s, you don't want each event to incur a synchronous network call. The buffer absorbs the burst and flushes periodically. The middleware drives the agent lifecycle automatically - no lifespan hook required.
5. The "I don't want to run fail2ban and Cloudflare" developer
You're shipping a small-to-medium API. You've read enough threat reports to know you need something. You don't want to:
- learn iptables
- keep a fail2ban config in sync with your rate limit logic
- pay for a Pro Cloudflare plan
- debug why a WAF rule is eating your legitimate
POST /api/v1/upload
You want middleware. You want it to do 80% of what those tools do, from inside your app, in a place you can debug with the same tools you already debug with.
config = SecurityConfig(
rate_limit=100,
auto_ban_threshold=5,
blocked_countries=["CN", "RU"],
enable_penetration_detection=True,
)
app.add_middleware(SecurityMiddleware, config=config)
Four lines. Rate limiting, IP auto-ban on repeat offenders, geo-blocking, and SQL-injection / XSS / path-traversal detection. You can harden later. Most people don't need to.
What this doesn't replace
To be honest: if you're running a high-traffic public product and you're not behind a CDN with DDoS protection, you have a different problem. Guard Core runs inside your app. It can't absorb a 400 Gbps SYN flood. Your upstream provider has to.
So: run Cloudflare if you want edge DDoS protection. Run fail2ban if you want OS-level SSH protection. And run Guard Core for everything those two can't see: per-endpoint business rules, per-user rate limits, decorator-level honeypots, behavioral patterns against your specific routes, and passive-mode shadow-testing before you touch production.
The Cloudflare + fail2ban post has the data on why all three layers matter.
How to start
Install:
pip install fastapi-guard
Add the middleware, ship. Three lines minimum, the config above if you want the full starter set. MIT licensed, no account needed for the library itself. The cloud dashboard is optional and free up to 10K events/month if you want the telemetry and weekly threat reports.
If you want to see features live before you install anything, the playground has interactive demos for blocking, decorators, honeypots, rate limits, passive mode, and the rest.
Questions, feedback, war stories - GitHub issues, always.