Authentication and consent
Authentication and consent
Authentication in this backend has two entrypoints and two acceptance gates:
api/views/auth_views.pyhandles classic username/password login and token refresh.api/views/ms_auth_views.pyhandles Microsoft bearer-token exchange, user creation, tenant binding, and token issuance.api/views/consent_view.pystores and revokes user consent.api/views/license_view.pystores license acceptance.
Login and token refresh
CustomLoginAPIView validates the request body, authenticates the Django user, and returns a custom JWT access/refresh pair. The response also includes user metadata and a has_consented flag derived from UserConsent.
Important invariants:
- The login endpoint is public but throttled when
LOGIN_THROTTLE_ENABLEDis set. - Invalid credential formats fail before authentication is attempted.
- Inactive accounts are rejected explicitly.
- JWT creation failures are surfaced as a server error rather than as a generic auth failure.
TokenRefreshAPIView validates the refresh token and issues a new access token using the custom JWT wrapper.
Microsoft auth
MicrosoftAuthView is the primary federated login path. It:
- validates the Microsoft access token via JWKS
- resolves or creates a Django
User - stores the Microsoft tenant ID on the user’s profile
- resolves or creates the internal tenant for that Microsoft directory
- creates tenant membership if needed
- returns backend tokens plus tenant/profile information
This is the route that couples authentication to tenancy. The response shape includes tenant, tenant_id, ms_profile, and ms_tenant_id so the frontend can initialize the workspace context immediately.
Consent and license gates
UserConsentAPIView and LicenseAcceptAPIView both gate downstream user flows.
- Consent can be queried, created, and revoked.
- System/application accounts bypass consent checks.
- License acceptance is recorded as a separate user-level flag.
These checks are not cosmetic: document upload and other protected flows depend on them through permission classes such as HasUserConsent.
Cross-cutting dependencies
api.authentication.jwt_utilsissues and refreshes tokens.api.utils.auth_utilsvalidates Microsoft tokens and resolves Azure tenant IDs.api.models.consent.UserConsentandapi.models.license_acceptance.UserLicenseAcceptancepersist user acceptance state.api.tenancy.models.TenantMembershipis used to bind Microsoft users to internal workspaces.
Lifecycle ordering
sequenceDiagram participant Client participant Login as CustomLoginAPIView participant MS as MicrosoftAuthView participant JWT as jwt_wrapper participant Consent as UserConsentAPIView participant Tenant as TenantMembership
Client->>Login: username/password Login->>JWT: create_token_pair(user) Login-->>Client: access/refresh + has_consented Client->>MS: Microsoft access token MS->>MS: validate token, resolve user, resolve tenant MS->>Tenant: get_or_create membership MS->>JWT: create_token_pair(user, tenant_id) MS-->>Client: access/refresh + tenant/profile Client->>Consent: POST /api/v1/consent/ Consent-->>Client: consent persistedRepresentative tests
tests/unit/auth/test_auth.py— login success and failure branches.tests/unit/auth/test_login_throttle.py— rate limiting for login.tests/unit/auth/test_ms_tenant_org.py— Microsoft tenant/org binding.tests/unit/auth/test_auth_and_tenancy_contracts.py— auth and tenant-contract boundaries.tests/integration/test_authentication.py— end-to-end auth flows.
Scope boundary
This page covers authentication and user-acceptance state only. For tenant resolution and membership enforcement after login, read Tenancy. For upload gates that require consent, read Document processing.