# Dashboard RBAC Design

> Phase 1 status: **design and pure policy tests only**. No dashboard route is wired to
> this policy, and the existing authorization middlewares remain non-enforcing.

## Current State

- `authentication.js` authenticates an active dashboard admin and populates
  `req.admin.role`.
- `authorization.js` and `authorizationAjax.js` calculate an authorization result, but
  their denial branches are commented out.
- `roleModel.js` stores permissions as route-path strings. It does not store an HTTP
  method with each permission.
- The generated and legacy permission catalogues contain different path shapes. They
  must be reconciled before enforcement.

Consequently, any active dashboard admin can currently reach every dashboard route.
Phase 1 does not change that behavior.

## Policy Boundary

`src/middlewares/rbacPolicy.js` is a side-effect-free policy evaluator. It exists so the
decision rules can be reviewed and tested before any middleware starts denying traffic.

Inputs:

- authenticated admin
- HTTP method
- request path

Output:

```js
{
  allowed: false,
  reason: 'permission_missing',
  method: 'POST',
  path: '/clients/delete/123'
}
```

The evaluator:

- denies missing or inactive admins;
- permits an active `isSuperAdmin` admin;
- denies missing or deleted roles;
- supports only `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`;
- normalizes `/dashboard` and query-string prefixes;
- matches literal segments, `:parameter`, optional `:parameter?`, and `*`;
- rejects legacy regex-literal permission values instead of executing stored regex;
- denies when no stored path permission matches.

The returned decision deliberately excludes admin identifiers, role names, and the
permission list so callers can log a reason safely.

## Compatibility Constraint

HTTP method is recorded in each decision, but it is not yet part of permission matching
because the persisted role schema is path-only. Enforcing the policy now could therefore
grant or deny the wrong operation when multiple methods share a path. No schema or role
data migration is authorized in Phase 1.

## Proposed Rollout (Requires Separate Approval)

1. Reconcile the generated permission catalogue with stored role permissions.
2. Decide whether permissions become `{ method, path }` records or remain path-only.
3. Add a non-blocking shadow middleware that records only `requestId`, method, normalized
   path, decision, and reason.
4. Review shadow mismatches and define the dashboard response behavior for HTML versus
   AJAX denials.
5. Enforce a small approved route group, then expand only after access regression tests.

Global enforcement, role migration, permission regeneration, and route changes are not
part of Phase 1.

## Tests

`test/rbacPolicy.test.js` covers super-admin access, exact and parameterized path
matching, optional parameters, missing/inactive admins, missing/deleted roles,
unsupported methods, absent permissions, and rejection of stored regex literals.

