RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /AI-Powered SaaS Products
  6. /Ch. 6
AI-Powered SaaS Products

06. Authorization

Chapter 6 of 24 · 15 min
KEY INSIGHT

Authorization in multi-tenant SaaS requires checking tenant membership AND permission scope at every data access point—missing checks at either level creates security vulnerabilities. Authorization answers "what can this user do?" Authentication answers "who is this user?" Both are necessary, neither is sufficient. A common mistake is authenticating users but skipping authorization checks, allowing users to access data outside their permissions. Role-Based Access Control (RBAC) defines permissions by role. Permissions are granular actions: `billing:read`, `api_keys:create`, `users:invite`. Roles are collections of permissions. ```python from enum import Enum from functools import wraps class Permission(Enum): BILLING_READ = "billing:read" BILLING_MANAGE = "billing:manage" API_KEYS_CREATE = "api_keys:create" API_KEYS_READ = "api_keys:read" API_KEYS_DELETE = "api_keys:delete" USERS_INVITE = "users:invite" USERS_MANAGE = "users:manage" MODELS_READ = "models:read" ROLE_PERMISSIONS = { "owner": [p for p in Permission], # All permissions "admin": [ Permission.BILLING_READ, Permission.API_KEYS_CREATE, Permission.API_KEYS_READ, Permission.API_KEYS_DELETE, Permission.USERS_INVITE, Permission.USERS_MANAGE, Permission.MODELS_READ, ], "member": [ Permission.API_KEYS_CREATE, Permission.API_KEYS_READ, Permission.MODELS_READ, ], "viewer": [ Permission.API_KEYS_READ, Permission.MODELS_READ, ], } def require_permission(permission: Permission): """Decorator that checks permission before allowing access.""" def decorator(func): @wraps(func) async def wrapper(tenant_id: str, user_id: str, *args, **kwargs): # First: verify user belongs to this tenant membership = db.query(OrganizationMembership).filter_by( user_id=user_id, organization_id=tenant_id ).first() if not membership: raise PermissionError("User does not belong to this organization") # Second: check permission user_permissions = ROLE_PERMISSIONS.get(membership.role, []) if permission not in user_permissions: raise PermissionError(f"Missing permission: {permission.value}") return await func(tenant_id, user_id, *args, **kwargs) return wrapper return decorator ``` Using the decorator: ```python @require_permission(Permission.API_KEYS_CREATE) async def create_api_key(tenant_id: str, user_id: str, name: str): # Implementation only runs if authorization passes return api_key_service.generate_api_key(tenant_id, name) ``` The two-step check—membership verification then permission check—prevents both cross-tenant access and unauthorized actions within a tenant. Skipping the membership check allows users to manipulate resources by guessing IDs. Skipping the permission check allows users to perform admin actions.

EXERCISE

A user with the "member" role tries to delete an API key they created. Write the authorization logic that allows this. Now modify it to only allow deletion of keys the user created, not keys created by others with the same role.

← Chapter 5
Authentication
Chapter 7 →
Usage Metering