← Back to Core Domains

4.4 RBAC and Security Architecture

KMP uses CakePHP Authentication to establish an identity and CakePHP Authorization policies to decide what that identity may do. Roles and permissions are tenant data; policies remain the final authority for every controller action and query.

Evaluation model

request host → tenant context → authenticated identity
             → role/permission and active-window data
             → resource policy + branch scope
             → allowed entity or scoped query

The host-to-tenant step happens before tenant-domain authentication data is loaded. An unknown, inactive, or schema-incompatible tenant fails closed. The platform administration host uses separate platform authentication and services.

Building blocks

Component Role
KmpIdentityInterface Stable identity contract for members/service principals
PermissionsLoader Loads effective roles, permissions, and policy metadata
AuthorizationService Project extension of CakePHP’s authorization service
BasePolicy Common entity/table policy behavior
Entity policies Authorize operations on one resource
Table policies/scopes Authorize collection actions and constrain queries
ActiveWindow Applies start/end windows to roles and warrants
Warrants Satisfy formal authorization requirements for eligible grants

Controller rules

Policies commonly implement canIndex, canView, canAdd, canEdit, canDelete, canGridData, and scopeIndex, with additional domain actions where required. Follow the nearest existing policy rather than assuming every action maps to CRUD.

Defense-in-depth invariants

Multi-tenant implications

Database-per-tenant isolation is the first boundary; policy scope is the second. Both are required. A valid permission in tenant A has no meaning in tenant B. Never cache effective permissions without tenant namespacing, and never reuse a loaded entity after switching context.

Platform administration code must use platform services and the platform database explicitly. Tenant controllers must not read the tenant registry or platform secrets.

Testing authorization

For each protected feature, cover an allowed identity, denied identity, and a branch-scope edge. For collection endpoints, assert that out-of-scope rows are absent—not merely that the page returned 200. For worker flows, add a test showing that the correct tenant is entered and context is cleaned up.

Primary code