Two-Point Authorization Engine with Revocable Sharing for Multitenant Environments
Abstract
Multi-tenant software-as-a-service (SaaS) platforms that contain tenant-partitioned data require authorization systems which cover scenarios where classic flat role-based access control (RBAC) fails. Specifically, these systems need to provide access to individual resources rather than whole sets of resources, controlled cross-tenant sharing, and account-less share links which can be revoked at any time. We present access-kit, an in-process authorization engine for the .NET platform built on an explicit model: principals, “area:verb” actions, composable deny-wins policy statements with inheritance, and a resource hierarchy. Enforcement is a co-designed pair of mechanisms which consist of an application-pipeline gate that rejects unauthorized actions outright and an object-relational mapper (ORM) row filter that filters the data to only include rows which are permitted to the current principal. The gate publishes per-request scope which is consumed by row filter, and this scope keeps the two mechanisms in agreement and therefore keeping error reporting consistent. As a result, a write on a readable-but-not-writable resource is refused as a forbidden action rather than disguised as a missing resource, preventing the existence of the resource from being leaked. In the developed framework, each request acts in a single active tenant, so access resolves to one flat statement set. Cross-tenant access is achieved by pulling the grants the active tenant owns, and a caller switches workspace (re-minting its token) to act in another permitted tenant. Account-less sharing is implemented by issuing a revocable, table-backed capability token. We give an analytic cost model and an evaluation measured on PostgreSQL: a batch chain-walk resolves effective access in a number of database round trips that is independent of how many grants a principal holds, and we compare it with a naive baseline and a single-query recursive-CTE alternative. The per-request cost is dominated by this resolution, while the in-memory gate adds negligible overhead; the cost model and measurements are given in Section 5. The engine is implemented as a generalized reference implementation with adapters for Entity Framework Core, MediatR, and ASP.NET Core.