Skip to content
tezvyn:

Implement RBAC in FastAPI with a JWT role dependency

Source: fastapi.tiangolo.comMediumHow cards are made

Implement RBAC in FastAPI with a JWT role dependency
Summary

FastAPI dependency composition for JWT role validation.

Key points

build a dependency that decodes the JWT, checks the role, raises 403 if not admin, and inject via Depends.

Watch out for

parsing headers inside route not using dependencies.

What's really being asked

This tests your understanding of FastAPI dependency injection and your ability to separate cross-cutting concerns like authentication and authorization from business logic. The interviewer wants to see that you know how to compose dependencies, handle security schemes, and return semantically correct HTTP status codes. They also care whether you treat roles as claims inside the JWT rather than querying a database on every request.

The full answer

Four things in order. First, a base dependency that extracts the bearer token from the Authorization header, decodes the JWT, and returns a user object or dictionary containing at least the role field. Second, a parameterized authorization dependency that depends on the first one, accepts a list of allowed roles, compares the user's role against that list, and raises an HTTPException with status code 403 when the role is missing. Third, wiring the dependency into the path operation using FastAPI Depends, keeping the route handler clean and focused on its core task. Fourth, explaining why 403 is returned for forbidden roles versus 401 for missing or invalid authentication, and noting that dependencies are cached per request so nested dependencies do not re-run.

The mistakes people make

Parsing the Authorization header manually inside the route handler instead of using a reusable dependency. Hardcoding the string admin inside the route rather than parameterizing allowed roles. Returning 401 Unauthorized when the token is valid but the role is insufficient; that should be 403 Forbidden. Attempting to query a user database inside the route to fetch roles when the role is already encoded in the JWT. Writing the JWT verification logic inline for every protected route instead of composing shared dependencies.

What usually comes next

How would you handle multiple roles or hierarchical permissions like editor versus admin? What happens if the JWT is expired or malformed, and where do you catch that? How would you test this dependency in isolation using FastAPI dependency overrides? Would you store roles in the JWT payload or only a user ID, and what are the trade-offs? How do you handle route-level versus router-level versus global dependency application?

A concrete example

Imagine a route DELETE /users/{user_id}. You define async def get_current_user which decodes the JWT and returns a User object with a role attribute. Then you define require_admin which depends on get_current_user, checks if current_user.role is not admin, and raises HTTPException with status code 403 and detail Admin access required. Finally, the route is declared with dependencies set to Depends require_admin in the decorator or function signature. This keeps the delete logic free of authorization boilerplate.

Interview question

When implementing JWT-based RBAC in FastAPI, how should you handle a request with a valid token but an insufficient role claim?

  • a.Raise 401 from a shared dependency that hardcodes the string 'admin' for role checks
  • b.Use a parameterized dependency that depends on a base JWT decoder and raises 403 ForbiddenCorrect
  • c.Query the user database inside the route to fetch the role before processing
  • d.Decode the JWT inline inside the route handler and return 401 Unauthorized
Why?

A parameterized dependency composed on a base JWT decoder keeps routes clean and correctly raises 403 because the token is valid but the user lacks permission. Returning 401 is wrong for valid tokens, and querying a database or hardcoding 'admin' violates the pattern of extracting roles from JWT claims.

Just read this? Test yourself on what you have been reading.

Read the original → fastapi.tiangolo.com

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on fastapi — each one lists the topics its interview covers.

See open roles