Every agency-panel surface asks for a capability (tenants.view, billing.view, tenants.impersonate, staff.manage…), never for a person or a role. A single module maps role to capabilities and answers the question once. The owner is resolved from source code before the database is consulted at all.
Also called: who can see my data · vendor access control · support permissions · platform roles · least privilege
- 1A route calls requirePlatformCapability('tenants.manage') — it never compares an email itself.
- 2The resolver short-circuits for the owner from code, then reads platform_staff for everyone else.
- 3Roles are presets, not per-person checkbox grids, so 'who can see customer billing?' stays a glance instead of a query.
- 4Admins deliberately do NOT hold billing.view: platform revenue is the owner's alone.
- 5Support holds tenants.view and tenants.impersonate — they can come into an account to help, and cannot change what anyone pays.
- 6The UI hides what a role cannot use; the server refuses it regardless.
The file opens with the incident: 'Before this, "may this person administer the platform?" was answered by ~40 route handlers each holding their own copy of the same email comparison. That is exactly the shape the July SEV-1 took: an authorization rule spread thin enough that widening it in one place looked local and turned out not to be.' The narrowing of admin is quoted too — 'the admins don't need to be able to see the money either.'
- An authorization rule copied into forty handlers cannot be audited or safely widened.
- A sales rep could otherwise read a customer's billing history while qualifying them.
- The owner could be locked out of his own platform by a bad query or an empty table.
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →