JWT, OAuth2, Entra ID, CORS/CSRF, and Kubernetes RBAC configured for production setups
We configured production Django APIs with OAuth2, JWT, and CORS/CSRF enforcement to match client requirements instead of the shipped defaults. SSO runs through Azure Entra ID via Django Allauth. Kubernetes clusters use RBAC and namespace isolation.

Problem
Production systems across several projects needed proper authentication and access control. The defaults that ship with Django and Kubernetes stay permissive enough to be dangerous once a system handles real users and real data.
Approach
JWT token management with correct expiry, rotation, and revocation patterns. OAuth2 flows configured per use case: client credentials for service-to-service calls, authorization code for user-facing apps. CORS and CSRF policies tightened to the origins each app needs. Azure Entra ID SSO integrated via Django Allauth. Kubernetes clusters configured with RBAC policies and namespace isolation per environment.
Architecture
Django APIs with JWT auth via djangorestframework-simplejwt, OAuth2 via Django OAuth Toolkit. Azure Entra ID as identity provider, integrated through Django Allauth social login. CORS configured with explicit allowed origins and methods. Kubernetes RBAC with role bindings per service account and namespace-scoped policies.
Outcome
Production APIs and clusters now run defence-in-depth authentication: no wildcard CORS origins, no default service account permissions, no unsigned tokens. Entra ID SSO cut credential management overhead and centralised identity under the client's existing Azure tenant.
Why defaults are not enough
Django ships permissive defaults on purpose: they speed up development and assume no specific deployment model. Kubernetes does the same, and a freshly provisioned cluster lets service accounts do more than they should. In production, against real users and real data, these defaults are unacceptable exposure. This work closes the gap between "it works" and "it's configured correctly."
JWT and OAuth2
JWT configuration covered token expiry windows, refresh token rotation, and revocation on logout, the parts that are easy to get wrong and rarely tested. We configured OAuth2 flows per use case: client credentials for internal service-to-service calls (no user context, short-lived tokens, scoped to specific endpoints), and authorization code with PKCE for user-facing web clients. We defined scopes explicitly instead of leaning on broad defaults.
CORS and CSRF
Cross-origin policies default to either blocking everything (development pain) or allowing everything (production risk). The correct configuration sets explicit allowed origins matching the frontend deployment URLs, combined with CSRF enforcement on all state-mutating endpoints. Cookie-based session auth and token-based auth carry different CSRF exposure profiles, so we configured each project to its own auth mechanism instead of applying one policy across all of them.
Azure Entra ID SSO
We integrated Azure Entra ID (formerly Azure AD) as the identity provider for client projects running within Microsoft-managed tenants. The Django Allauth integration covered the OAuth2 / OIDC flow, group-based permission mapping, and token validation against the tenant's JWKS endpoint. This puts identity management on the client's existing Azure infrastructure and removes the need for a separate user database.
Kubernetes RBAC
We configured the Kubernetes clusters with role-based access control at the service account level: each deployment runs under a dedicated service account with only the permissions it needs. Namespace isolation separates environments (staging, production) and blocks lateral movement between workloads. We reviewed the cluster roles and removed default bindings that grant broader access than any workload in the cluster needs.