← Help center / Account & admin
Team, roles, and permissions
Give your bookkeeper the books and your maintenance super the work orders — and nobody your whole business.
The six preset roles
Org admin, property manager, bookkeeper, maintenance supervisor, leasing agent, and read-only — built on a 16-permission catalog covering properties, units, tenants, leases, invoices, payments, maintenance, reports, and users.
Team management Standard
Invite and manage your own staff. Assignable roles are org-staff only — no privilege escalation paths — with self-delete and last-admin removal blocked. Custom roles beyond the presets are also a Standard feature.
Account isolation
Every record is scoped to your account with a fail-closed global scope: cross-account access returns nothing, by architecture, not by policy. An always-on audit log records who changed what on sensitive records.
Choosing the right preset
The six presets map to how small portfolios actually divide work. Org admin is the owner or lead manager with full account access. Property manager handles properties, units, tenants, and leases but not payments — the common arrangement when someone runs operations and the owner keeps the books. Bookkeeper inverts that: invoices, payments, and reports, with read-only visibility into properties and leases. Maintenance supervisor sees work orders and the units they belong to and nothing financial. Leasing agent covers leases and tenants for turnover work. Read-only suits an accountant or a partner who needs visibility without any ability to change a record.
Why the limits are structural, not procedural
Roles are enforced by permission checks on every controller action, not by hiding menu items. A user who guesses a URL still gets refused, because the check runs server-side before the action executes. Assignable roles are restricted to org staff, so a landlord cannot escalate anyone to platform administrator, and the system refuses to remove the last remaining admin — an account can never be locked out of itself.
Account isolation
Every record carries an account scope applied globally at the query layer, and it fails closed: a query that somehow escapes its context returns nothing rather than everything. Cross-account access does not return a permission error that confirms a record exists — it returns nothing at all, which is the behaviour that prevents probing. This is architecture rather than policy, which is why it holds even in code paths nobody thought about when the feature was written.
Related: Reports, dashboards, and exports · Integrations: email, SMS, payments, and screening providers · Plans, billing, and how support works