# Multi-Tenancy & Access Reference (Current State) ## Purpose Authoritative map of tenant isolation, role access, and payment/API-key handling across the stack. Built from code as of Dec 2025. ## Core Enforcement Points (backend) - Middleware: - `backend/igny8_core/auth/middleware.py` (`AccountContextMiddleware`, ~L1-L220): resolves `request.account` from JWT/API key; blocks inactive/suspended accounts. - `backend/igny8_core/middleware/request_id.py` (~L1-L70): request ID (not tenancy). - `backend/igny8_core/middleware/resource_tracker.py` (~L1-L170): metrics (not tenancy). - Base viewsets: - `backend/igny8_core/api/base.py` (`AccountModelViewSet`, ~L1-L240): filters by `request.account`; admin/developer/system overrides; sets account on create. - `backend/igny8_core/api/base.py` (`SiteSectorModelViewSet`, ~L238-L430): additionally filters by site/sector and user’s accessible sites (SiteUserAccess) unless admin/developer/system. - Permissions: - `backend/igny8_core/api/permissions.py`: - `IsAuthenticatedAndActive`, `HasTenantAccess` (default in settings). - `IsViewerOrAbove`, `IsEditorOrAbove`, `IsAdminOrOwner`. - `IsSystemAccountOrDeveloper` (system/admin for integrations). - Module-specific permissions also appear in `backend/igny8_core/auth/permissions.py` (legacy IsOwnerOrAdmin, IsEditorOrAbove, IsViewerOrAbove, AccountPermission). - Settings defaults: - `backend/igny8_core/settings.py` REST_FRAMEWORK `DEFAULT_PERMISSION_CLASSES` = `IsAuthenticatedAndActive` + `HasTenantAccess`. - Auth order: APIKeyAuthentication → JWTAuthentication → CSRFExemptSessionAuthentication → BasicAuth. - Throttling: `DebugScopedRateThrottle` bypasses throttles for authenticated users/system/debug. - Models with enforced account/site/sector: - Base models `AccountBaseModel`, `SiteSectorBaseModel` in `backend/igny8_core/auth/models.py` (top of file). ## Flow (text flowchart) ``` Request -> Middleware: AccountContextMiddleware sets request.account (JWT/API key), validates account status/plan -> DRF Auth: APIKey/JWT/Session -> Permissions: IsAuthenticatedAndActive + HasTenantAccess (+ role-specific) -> ViewSet: AccountModelViewSet filters by account SiteSectorModelViewSet filters by account + site/sector + SiteUserAccess -> Action-specific role checks (IsEditorOrAbove, IsAdminOrOwner, IsSystemAccountOrDeveloper) -> Business logic (services) + credit checks (billing) -> Response ``` ## Module Access (backend ViewSets & guards) - Accounts/Users/Plans/Subscriptions: - `auth/views.py`: `UsersViewSet`, `AccountsViewSet`, `SubscriptionsViewSet`, `SiteUserAccessViewSet` (account-scoped via AccountModelViewSet + role guards). - Roles: owner/admin (or developer/system) can manage; others limited to self (UsersViewSet get_queryset). - Sites/Sectors: - `auth/views.py` (`SiteViewSet`, `Sector` actions): SiteSectorModelViewSet enforces account + site/sector + SiteUserAccess; public slug read is AllowAny for active site slug only. - Planner: - `modules/planner/views.py` (KeywordViewSet, ClusterViewSet, ContentIdeasViewSet) inherit SiteSectorModelViewSet; require site_id/sector_id; role: typically editor+ for writes. - Writer: - `modules/writer/views.py` (TasksViewSet, ContentViewSet, ImagesViewSet, ContentTaxonomyViewSet) inherit SiteSectorModelViewSet; site/sector scoping; editor+ for writes. - Automation: - `business/automation/views.py` (AutomationViewSet) inherits AccountModelViewSet/SiteSectorModelViewSet patterns; requires site_id for run/config; role: editor+ for mutate. - System settings (non-integrations): - `modules/system/views.py` / `settings_views.py`: AccountModelViewSet; role usually admin/owner; authenticated + tenant required. - Integrations (OpenAI/Runware API keys): - `modules/system/integration_views.py`: guarded by `IsSystemAccountOrDeveloper` (system account or developer only); tenant-scoped but effectively system-only for keys. - Billing: - `modules/billing/views.py`: AccountModelViewSet; `IsAdminOrOwner` for credit transactions/payment methods; balance/usage requires auth + tenant. - Payments/Payment Methods: - Payment methods: `AccountPaymentMethodViewSet` account-scoped; IsAuthenticated; default selection per account; admin/owner should manage. - Payments: `PaymentViewSet` account-scoped; IsAuthenticated; list/available_methods/manual payment for current account only. ## Frontend Guards - Route protection: `ProtectedRoute` (auth required, checks account/plan/payment methods), `ModuleGuard` (module enabled), `AdminGuard` (integration/admin pages only for system account or developer). - Sidebar hides Integration for non-system/developer; admin section shown only for system/developer. ## AI Key Resolution - `ai/ai_core.py` `_load_account_settings`: tries tenant IntegrationSettings → system account IntegrationSettings (`aws-admin`/`default-account`/`default`) → Django settings (`OPENAI_API_KEY`, `RUNWARE_API_KEY`). All users run AI with shared keys if tenant keys absent. ## Throttling - `api/throttles.py` `DebugScopedRateThrottle`: bypass for authenticated users/system/debug; per-scope rates in `settings.py`. Prevents 429s for normal users. ## Payment / Billing Workflow (happy path) 1) User authenticates (JWT) → request.account set. 2) Payment methods (account-scoped) fetched via `/v1/billing/payment-methods/available/`; admin/owner can CRUD `/v1/billing/payment-methods/`. 3) Invoices/Payments via billing endpoints (account-scoped; admin/owner). 4) Credits used via CreditService on AI/automation calls (backend). ## Access Summary by Role (runtime enforcement) - Viewer: read-only where viewsets allow `IsViewerOrAbove`; no writes. - Editor: can write planner/writer/automation; cannot manage billing/integration. - Admin/Owner: manage account/team/billing/payment methods; full module writes. - Developer/System account: cross-tenant overrides in some base filters; integration settings and admin menus. ## Key Files (with line bands) - Middleware: `auth/middleware.py` (~L1-220) - Base viewsets: `api/base.py` (~L1-430) - Permissions: `api/permissions.py` (~L1-200), `auth/permissions.py` (~L1-120) - Settings (REST/Throttle): `settings.py` (REST_FRAMEWORK block, ~L200-360) - AI core key loading: `ai/ai_core.py` (~L1-120) - Integration settings views: `modules/system/integration_views.py` (~L1-300 main guards; actions throughout) - Planner views: `modules/planner/views.py` (all ViewSets inherit SiteSectorModelViewSet) - Writer views: `modules/writer/views.py` - Automation: `business/automation/views.py`, `services/automation_service.py` - Billing: `modules/billing/views.py`, `business/billing/services/credit_service.py` - Payment methods: `modules/billing/views.py` AccountPaymentMethodViewSet - Frontend guards: `src/components/auth/ProtectedRoute.tsx`, `src/components/auth/AdminGuard.tsx`, `src/components/common/ModuleGuard.tsx` - Sidebar gating: `src/layout/AppSidebar.tsx` ## Open Items / Risks - Ensure public endpoints explicitly override default permissions (e.g., auth register/login, site slug read). - Validate all viewsets still inherit AccountModelViewSet/SiteSectorModelViewSet after future changes. - Add automated tests for cross-tenant denial, role gates, plan limits, and integration access.***