Skip to Content

How do you build role-and-scope RBAC with FastAPI Security?

Category: Security & Compliance

Answer

Roles are coarse (admin, customer); scopes are fine-grained permissions (messages:read, refunds:write). The JWT carries both. Security(scopes=["refunds:write"]) declares what the route needs; the route depends on get_current_user which returns the typed User with role and scopes. Missing scope = 403.

Concrete examples from the fca project context

Example 1

Token claims: {”sub”: user.id, ”role”: “customer”, "scopes": ["messages:read"]}.

Example 2

Route: @router.post(“/refunds”, dependencies=[Security(verify_scope, scopes=[“refunds:write”])]).

Example 3

verify_scope checks if any scope in the JWT contains the required string.

Data flow / flow chart

JWT scopes -> Security(scopes=[...]) -> verify_scope dependency -> route
  Missing scope -> 403

Takeaway

Scopes give per-endpoint granularity on top of role. Same JWT, different gate.