March 15, 2023

Implementing Role-Based Access Control (RBAC) with Flask and JWT

Security isn't optional when you're handling business data for 50+ companies.

The Requirements

Different users need different permissions:

  • Admins can do everything
  • Managers can approve and view reports
  • Staff can create and edit records
  • Viewers can only read

And it needs to work across multiple tenants without leaking data.

The Architecture

We use JWT tokens with embedded role claims. Each request validates the token and checks permissions before executing.

@require_permission('inventory.create')
def create_item():
    # Only users with inventory.create permission reach here
    pass

The decorator checks the JWT, extracts the user's roles, and verifies they have the required permission.

Multi-Tenancy

Every database query includes a tenant filter. Every JWT includes a tenant_id claim.

This makes it impossible (or at least very hard) to accidentally query another tenant's data.

Lessons

  1. Don't roll your own crypto. Use established libraries.
  2. Log everything. Security incidents are easier to investigate with good logs.
  3. Test negative cases. Make sure unauthorized requests fail correctly.

RBAC is complex, but it's worth getting right.