diagram.mmd — flowchart
Access Control Decision Flow flowchart diagram

The access control decision flow is the sequence of checks an application performs on every incoming request to determine whether to allow or deny it. It combines authentication (who are you?) and authorization (are you allowed to do this?) into a layered enforcement pipeline.

The first gate is authentication validation. For JWT-based systems, this means extracting the Authorization: Bearer header, verifying the token's signature, and checking that it hasn't expired. If any of these fail, the request is rejected with a 401 Unauthorized response before any application logic runs. For session-based systems, the session cookie is validated against the session store.

Once the caller's identity is established, tenant context is extracted (in multi-tenant systems) and verified — confirming that the resource being requested belongs to the same tenant as the authenticated user. This prevents cross-tenant data access even with valid tokens.

The next layer is authorization: given who the user is, can they perform the requested action on the requested resource? This typically involves loading the user's roles and expanding them to permissions (RBAC), or evaluating attribute-based policies (ABAC). The required permission for the route is compared against the user's effective permissions.

Some systems add resource ownership checks after the role check — for example, confirming that a user with the editor role is only editing their own posts, not other users' posts. This is the hybrid RBAC + ABAC approach common in practice.

If all checks pass, the request proceeds to the handler. If any check fails, the appropriate HTTP error is returned: 401 for unauthenticated, 403 for authenticated but unauthorized. This layered approach ensures security failures are caught at the earliest possible point. See RBAC Authorization Model and ABAC Authorization Model for the underlying permission structures.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

The access control decision flow is the layered sequence of checks an application performs on every incoming request to decide whether to allow or deny it. It combines authentication (verifying who the caller is) and authorization (checking what they are permitted to do) into a pipeline that runs before any business logic executes.
The first stage validates authentication — verifying the JWT signature and expiry, or looking up the session in the session store. The second stage extracts and validates tenant context (in multi-tenant systems). The third stage performs authorization — expanding the user's roles to permissions and checking whether the required permission is present. Optionally, a fourth stage performs resource ownership checks for hybrid RBAC/ABAC scenarios.
A 401 Unauthorized response means the request lacks valid authentication credentials — the user is not logged in, the token is missing, expired, or has an invalid signature. A 403 Forbidden response means the caller is authenticated but does not have permission to perform the requested action. Returning the correct code matters for clients to distinguish "please log in" from "you do not have access".
Implement each check as a middleware layer ordered from cheapest to most expensive. Token signature verification is fast and should run first. Tenant context extraction comes next. Role/permission expansion may involve a database query or JWT claim inspection. Ownership checks may require loading the resource. Short-circuit on the first failure to avoid unnecessary work and to prevent information leakage about resources the caller cannot access.
In multi-tenant systems, the tenant ID from the token must be validated against the resource being accessed. Even if a user has a valid token with `admin` permissions, they must be denied access to resources belonging to a different tenant. The tenant check is a separate, mandatory gate that sits between authentication and permission-level authorization.
mermaid
flowchart TD REQ([Incoming API request]) --> AUTH_CHECK{Token/session present?} AUTH_CHECK -- No --> R401A([401 - Authentication required]) AUTH_CHECK -- Yes --> VALIDATE{Token signature\nand expiry valid?} VALIDATE -- Invalid --> R401B([401 - Invalid or expired token]) VALIDATE -- Valid --> EXTRACT[Extract identity: user_id, roles, tenant_id] EXTRACT --> TENANT_CHECK{Resource belongs\nto user tenant?} TENANT_CHECK -- No --> R403A([403 - Cross-tenant access denied]) TENANT_CHECK -- Yes --> ROLE_CHECK{User role has\nrequired permission?} ROLE_CHECK -- No --> R403B([403 - Insufficient permissions]) ROLE_CHECK -- Yes --> OWNERSHIP{Ownership check\nrequired?} OWNERSHIP -- No --> ALLOW([Allow - pass to handler]) OWNERSHIP -- Yes --> OWN_CHECK{User owns\nthis resource?} OWN_CHECK -- No --> R403C([403 - Resource not owned by user]) OWN_CHECK -- Yes --> ALLOW
Copied to clipboard