Skip to content

Roles & Permissions

AuthFort includes a simple, flexible role system. Roles are strings (e.g., "admin", "editor", "moderator") stored in a join table and embedded in every access token.

# Add a role
await auth.add_role(user_id, "admin")

# Remove a role
await auth.remove_role(user_id, "editor")

# Get all roles for a user
roles = await auth.get_roles(user_id)
# ["admin", "editor"]
# Add a role
await auth.add_role(user_id, "admin")

# Remove a role
await auth.remove_role(user_id, "editor")

# Get all roles for a user
roles = await auth.get_roles(user_id)
# ["admin", "editor"]

By default, role changes bump the user’s token_version, which invalidates all existing access tokens immediately:

# Immediate — existing tokens are invalidated
await auth.add_role(user_id, "admin", immediate=True)  # default

# Deferred — takes effect on next token refresh
await auth.add_role(user_id, "admin", immediate=False)
# Immediate — existing tokens are invalidated
await auth.add_role(user_id, "admin", immediate=True)  # default

# Deferred — takes effect on next token refresh
await auth.add_role(user_id, "admin", immediate=False)

Use immediate=False when adding non-sensitive roles where you don’t need instant enforcement.

Use has_role() for a quick single-role check:

# Quick check for a single role
is_admin = await auth.has_role(user_id, "admin")
if is_admin:
    # do admin stuff
    pass
# Quick check for a single role
is_admin = await auth.has_role(user_id, "admin")
if is_admin:
    # do admin stuff
    pass

Or fetch all roles at once:

roles = await auth.get_roles(user_id)
if "admin" in roles:
    # do admin stuff
    pass
roles = await auth.get_roles(user_id)
if "admin" in roles:
    # do admin stuff
    pass

Roles are embedded in the JWT roles claim:

{
  "sub": "user-uuid",
  "email": "user@example.com",
  "roles": ["admin", "editor"],
  "ver": 3,
  "exp": 1234567890
}
{
  "sub": "user-uuid",
  "email": "user@example.com",
  "roles": ["admin", "editor"],
  "ver": 3,
  "exp": 1234567890
}

When immediate=True, bumping the token version means any token with ver < 3 is rejected. The user’s next request triggers a token refresh, which issues a new token with the updated roles.

Emits role_added and role_removed events. See Events & Hooks for all events and their payloads.