You prompted an AI, got a working FastAPI app in twenty minutes, and deployed it the same afternoon. Three days later someone dumped your entire user table because the AI never added authentication to that one admin endpoint. This happens constantly to vibe-coded projects, and the fix is not to stop using AI. The fix is to bolt security guardrails onto your workflow before the code reaches production.

Photo by Took A Snap from Pexels

TL;DR:
  • AI-generated FastAPI code routinely ships without input validation, proper auth, or rate limiting.
  • You can catch most of these gaps with five concrete guardrails: dependency checks, Pydantic validation, OAuth2/JWT auth, CORS lockdown, and automated scanning in CI.
  • None of this requires a security degree. It requires a checklist and ten minutes of configuration per project.
Security in vibe-coded FastAPI projects breaks down to one core problem: the AI optimizes for "it works" and skips everything that only matters when someone attacks it. That gap between "works on localhost" and "survives the internet" is where your data leaks, your API gets abused, and your users lose trust. The guardrails below close that gap without slowing you down. Each one takes minutes to add, and together they cover the vulnerabilities that hit AI-generated Python APIs most often.
0%
AI-generated endpoints missing rate limiting

Why AI skips security by default

code on computer screen
Photo by Nemuel Sereti from Pexels

Large language models generate code that satisfies the prompt. If you ask for "a FastAPI endpoint that returns all users," you get exactly that. No authentication middleware. No pagination. No rate limiter. The model did its job. The problem is yours.

This is not a flaw in the AI. It is a flaw in how we use it. Vibe coding moves fast because you skip the boilerplate, but security is boilerplate. It is the boring, repetitive code that protects every route, validates every input, and restricts every caller. When you skip it, you ship an open door.

Three patterns show up in almost every AI-generated FastAPI project:

  1. No input validation beyond type hints. The AI uses str or int parameters but never constrains length, format, or range.
  2. Hardcoded secrets. Database URLs, API keys, and JWT secrets appear as string literals in main.py.
  3. Missing CORS configuration. The default CORSMiddleware with allow_origins=[""] shows up in nearly every generated snippet.
"Now clearly this guy saw AI generating code and thought now he doesn't need any programmers, and AI would build the entire thing on his own and he's going to make money from it."
>,
Medium

That quote captures the mindset that leads to breaches. The AI builds the thing. You still own the security.

Vibe-coded projects with proper auth before launch
0%

Common mistakes that create vulnerabilities

startup team programming
Photo by cottonbro studio from Pexels

Here are the specific mistakes I see repeated across vibe-coded FastAPI repos, along with what actually goes wrong.

Trusting Pydantic defaults. Pydantic v2 validates types, but it does not enforce business rules unless you tell it to. An AI-generated User model with email: str accepts "not-an-email" without complaint. You need EmailStr from pydantic[email], plus Field(max_length=255) on every string field.

Skipping dependency injection for auth. FastAPI's Depends() system exists specifically for this. Instead of checking tokens inside each route function, you create a single get_current_user dependency and attach it at the router level. AI-generated code often puts auth checks inline, which means one forgotten route equals one open endpoint.

Using SQLAlchemy raw queries. When the AI builds a search feature, it sometimes concatenates user input into SQL strings. FastAPI + SQLAlchemy's ORM prevents SQL injection by default, but only if you use the ORM. The moment you drop to text() with f-strings, you are back to 2005.

No rate limiting. A single while True loop from an attacker can exhaust your server. The slowapi library wraps FastAPI routes with rate limits in two lines of code. The AI never adds it.

Warning: If your FastAPI app accepts file uploads, check that the AI added size limits. The default UploadFile has no max size. A 10 GB upload to your free-tier server will crash it.

Five guardrails, step by step

This is the core workflow. Each guardrail addresses one of the gaps above, and they stack. You do not pick one. You add all five.

Security guardrails for vibe coding in Python FastAPI process
Figure 1: Security guardrails for vibe coding in Python FastAPI at a glance.

Guardrail 1: Dependency audit. Run pip-audit against your requirements.txt or pyproject.toml before every deploy. This catches known CVEs in your dependencies. Add it to your CI pipeline so it blocks merges automatically.

Guardrail 2: Strict Pydantic models. Every request body and query parameter gets a Pydantic model with Field() constraints. Minimum lengths, maximum lengths, regex patterns for emails and slugs, and conint(ge=0) for IDs. This is your first line of defense against malformed input.

Guardrail 3: Centralized auth with Depends(). Create a single security.py file with OAuth2PasswordBearer and a get_current_user function that decodes JWT tokens. Apply it at the APIRouter level using dependencies=[Depends(get_current_user)]. Every route on that router is now protected. No exceptions, no forgotten endpoints.

Guardrail 4: Lock down CORS and headers. Replace allow_origins=[""] with your actual frontend domain. Add SecurityMiddleware or manually set X-Content-Type-Options, X-Frame-Options, and Strict-Transport-Security headers. FastAPI does not add these by default.

Guardrail 5: Rate limiting with slowapi. Install slowapi, create a Limiter instance, and decorate sensitive endpoints (login, registration, password reset) with @limiter.limit("5/minute"). This stops brute-force attacks and API abuse with minimal code.

Without GuardrailsWith Guardrails
Open endpoints, no authJWT auth on every router
allow_origins=[""]Explicit origin whitelist
No input length limitsPydantic Field() on every model
Zero rate limitingslowapi on sensitive routes
Secrets in source code.env files + pydantic-settings

Tools and workflows that help

developers collaborating
Photo by Vitaly Gariev from Pexels

You do not need to memorize OWASP. You need the right tools wired into your workflow.

  • pip-audit scans your installed packages for known vulnerabilities. Run it in CI with pip-audit --strict to fail the build on any finding.
  • bandit is a static analysis tool for Python security issues. It catches hardcoded passwords, use of eval(), and insecure random number generation. Add bandit -r app/ to your pre-commit hooks.
  • pydantic-settings loads configuration from environment variables and .env files. It replaces every hardcoded secret in your codebase with a typed, validated settings class.
  • python-jose or PyJWT handles JWT encoding and decoding. Pair it with FastAPI's OAuth2PasswordBearer for a complete auth flow.
  • slowapi wraps limits for FastAPI. Two lines of setup, then decorators on individual routes.
The workflow looks like this: write your prompt, get the AI output, run bandit and pip-audit against it, fix what they flag, then deploy. That cycle adds maybe five minutes to your process and catches the majority of AI-generated security gaps.

The Vibe Coding Bible at vibecodingbible.org covers this entire pipeline in depth, including prompt templates that tell the AI to include security from the start.

Here is an example dashboard showing what a typical security scan reveals on a freshly vibe-coded FastAPI project before applying guardrails:

🔍 Pre-Guardrail Security Scan

Unprotected endpoints7 / 9
Hardcoded secrets3 found
CORS policyallow_origins=
Input validationtypes only
Rate limitingnone
Dependency CVEs2 moderate
Security headers1 / 4 set
0 min
Average time to add all five guardrails
Key takeaway: AI-generated FastAPI code works, but it does not defend itself. Five guardrails (dependency audit, Pydantic validation, centralized auth, CORS lockdown, rate limiting) close the gap between "runs on localhost" and "survives production" in under ten minutes.

FastAPI Security Guardrails Checklist

Your progress is saved automatically in your browser.

FAQ

Frequently Asked Questions

Anyone shipping a FastAPI application built with AI assistance. You do not need a security background. If you can install a Python package and edit a decorator, you can implement every guardrail listed here. The guide is especially relevant if you are a founder, indie hacker, or non-engineer builder using tools like Cursor, Claude, or Copilot to generate your backend code.
For a typical small-to-medium FastAPI project (5 to 20 endpoints), expect 30 to 60 minutes for the first time. That includes installing pip-audit, bandit, slowapi, and pydantic-settings, creating your security.py auth module, and tightening your Pydantic models. After you have done it once, you can template the setup and apply it to new projects in under 10 minutes.
Start with bandit -r app/ on your existing codebase. It gives you an immediate list of security issues ranked by severity. Fix the high-severity findings (hardcoded secrets, use of eval, insecure imports) first. Then move to centralized auth, because unprotected endpoints are the single biggest risk in vibe-coded APIs.
You can, and you should. Prompts like "add JWT authentication to all routes" or "use Pydantic Field constraints on every model" improve the output. But the AI still misses things. Automated scanning with bandit and pip-audit catches what the prompt missed. Treat the AI as a fast first draft and the scanners as your reviewer.
Yes. FastAPI includes OAuth2PasswordBearer, OAuth2PasswordRequestForm, dependency injection via Depends(), and automatic request validation through Pydantic. The problem is that AI-generated code often ignores these features or uses them partially. The guardrails in this article ensure you actually use what FastAPI already provides.
|

Additional Resources

What is the first security gap you found in your own vibe-coded FastAPI project?