We are building a multi-tenant platform and I am struggling with structuring OAuth2 scopes. I want to use the built-in Security dependencies in FastAPI to restrict access based on tenant-specific roles. Is it better to bake the tenant ID into the scope string, or should I handle tenant validation in a separate dependency injected after the OAuth2 password flow?
3 answers
For multi-tenancy, I highly recommend keeping scopes generic (like read:data) and handling the tenant isolation via a separate dependency. In FastAPI, you can create a get_current_tenant dependency that extracts the tenant_id from the JWT claims or a header. Then, your endpoint uses both Security(get_current_user, scopes=["read:data"]) and Depends(get_current_tenant). This keeps your scope logic clean and prevents an explosion of scope names. If you put tenant IDs in scopes, managing permissions becomes a nightmare as your client base grows.
If we use a separate dependency for tenant validation, does that add significant latency to the request? Would caching the tenant metadata in Redis be a requirement for a high-concurrency FastAPI setup?
I prefer using sub-dependencies in FastAPI to chain the user and tenant checks. It makes the code very readable and reusable.
Chaining dependencies is exactly why I love this framework; it makes complex logic feel like simple LEGO blocks!
It definitely adds a few milliseconds if you hit the DB every time. Caching tenant settings in Redis is a pro move here. It allows your FastAPI middleware to validate the tenant context almost instantly, ensuring your security layer doesn't become a bottleneck during peak traffic periods.