105 lines
7.2 KiB
Markdown
105 lines
7.2 KiB
Markdown
# 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.***
|
||
|