Skip to content
Sarj Code Standards

fastapi-route-declares-security

Declare each FastAPI route access decision, including inherited router dependencies.

Why

A route without a visible access declaration makes reviewers infer its policy from unrelated code. A Security dependency records the decision at the route or an effective router ancestor. This contract does not establish the strength of the check or replace middleware review.

Fix

Wrap the dependency that authenticates or authorizes callers in Security(...), in the decorator's dependencies=, on the router, or as an Annotated parameter. For a route that is public on purpose, declare a no-op marker dependency such as Security(public_route).

Examples

Before — flagged A route whose only access dependency uses `Depends`
app/routes.py
from fastapi import APIRouter, Depends
router = APIRouter()
@router.get("/items", dependencies=[Depends(require_user)])
def items() -> Items: ...
After — preferred The decorator declares a `Security` dependency
app/routes.py
from fastapi import APIRouter, Security
router = APIRouter()
@router.get(
"/items", dependencies=[Security(require_permission(Permission.ITEMS_READ))]
)
def items() -> Items: ...
Before — flagged An included router has no inherited Security declaration
app/routes.py
from fastapi import APIRouter, FastAPI
router = APIRouter()
@router.get("/items")
def items(): ...
app = FastAPI()
app.include_router(router)
After — preferred An included router inherits the application's Security declaration
app/routes.py
from fastapi import APIRouter, FastAPI, Security
router = APIRouter()
@router.get("/items")
def items(): ...
app = FastAPI(dependencies=[Security(require_user)])
app.include_router(router)