Middleware¶
The core.middleware layer provides lightweight request preprocessing for the backend.
Its role is to prepare request-scoped context early in the lifecycle, without embedding business logic in the middleware itself.
Purpose¶
Middleware exists to:
- initialize request-level context
- attach the active organization to the request when possible
- keep downstream permission and view logic simple
- centralize early request preparation
In the current system, middleware is intentionally minimal.
Current Middleware¶
CurrentOrgMiddleware¶
This middleware initializes organization context for the request.
It:
- sets
request.org - sets
request.organization - delegates actual resolution to the request context service
It does not perform business logic directly.
Why Middleware Is Lightweight¶
The architecture avoids putting complex behavior into middleware.
Instead:
- middleware sets up request state
- services resolve org/customer context
- permissions enforce access
- views remain thin
This keeps middleware:
- testable
- reusable
- easy to reason about
Request Flow¶
flowchart LR
A[Incoming Request] --> B[CurrentOrgMiddleware]
B --> C[attach_current_org]
C --> D[request.org set or None]
D --> E[Permission Layer]
Responsibilities¶
CurrentOrgMiddleware¶
On every request:
- Initialize:
- request.org = None
-
request.organization = None
-
Call:
-
attach_current_org(request)
-
Continue request processing
Delegation to Request Context Service¶
The middleware does not know:
- how orgs are resolved
- how headers are interpreted
- how memberships are checked
That logic is delegated to:
- core.services.request_context
This is an intentional design decision.
What Middleware Does NOT Do¶
Middleware should not:
- perform authorization logic
- decide business permissions
- query unrelated domain objects
- return feature-specific responses
- replace DRF permissions
Interaction with Permissions¶
Middleware is helpful, but permissions are still the source of enforcement.
Example:
- middleware may set request.org
- HasCurrentOrg confirms the request is valid
- if resolution failed, permission denies access
This means the system remains safe even if middleware does not resolve an org.
Why Both Middleware and Permissions Exist¶
Middleware¶
- improves ergonomics
- attaches org early
- simplifies downstream code
Permissions¶
- enforce access
- guarantee endpoint safety
- prevent accidental bypass
This combination provides both convenience and security.
Request Attributes¶
After middleware runs, the request may contain:
request.org¶
The resolved internal organization, or None
request.organization¶
Alias for request.org
This alias exists for compatibility and readability.
Failure Behavior¶
If middleware cannot resolve an org:
- request.org remains None
- request continues
- permissions later reject access if org is required
Middleware itself does not block the request.
Security Notes¶
Middleware is part of the multi-tenant infrastructure.
However, security does not rely on middleware alone.
Always use:
- HasCurrentOrg
- HasCurrentCustomerOrg
for protected endpoints.
Benefits¶
This middleware design provides:
- early request setup
- minimal coupling
- clean layering
- safer multi-tenant behavior
Future Extensions¶
Potential future middleware additions could include:
- request correlation IDs
- audit tracing context
- locale/timezone resolution
- feature flag bootstrap context
These should follow the same principle:
- lightweight setup
- delegate complex logic elsewhere
Summary¶
The middleware layer prepares request-scoped context without owning business logic.
CurrentOrgMiddleware is intentionally small and works together with:
- request context services
- permissions
- policies
to support safe and predictable multi-tenant request handling.