RBAC

Role definitions, permission verbs, row-level filters, and role profiles in P9.

Access Control

P9 RBAC provides granular access control at the object, field, and row level. Roles are defined in .rbac files and profiles in .profiles.rbac files.

Role Structure

@company "{company}"

role RoleName {
	allow ObjectName
	allow ApplicationName

	allow ObjectName {
		view
		create
		update
		patch
	}

	report "report-name"
	report *
}

Company Declaration

Every RBAC file starts with a company declaration:

@company "{company}"       // Dynamic company placeholder
@company "CompanyName"     // Specific company

Permission Types

Permission Description
view View/read records
create Create new records
update Update existing records
patch Partial update
delete Delete records
list or List List view access

Permission Syntaxes

Full Access to Object:

Grants all permissions (view, create, update, patch, delete, list):

role Manager {
	allow Contract
	allow Payment
	allow Building
}

Application-Level Access:

Grant all permissions to all objects in an application:

role Admin {
	allow Finance
	allow Leasing
	allow FacilityManagement
}

Specific Permissions:

role Viewer {
	allow Contract {
		view
		list
	}

	allow Building {
		view
	}
}

Permissions with Filters:

Restrict access based on conditions:

role RegionalManager {
	allow Contract {
		view {
			filter: " Region = '{User.Region}' "
		}
		create
		update
		patch
	}

	allow Building {
		view {
			filter: " Region = '{User.Region}' "
		}
	}
}

Filter Patterns

Pattern Description Example
{User.RecordId} Current user's record ID filter: " Team = '{User.RecordId}' "
{User.xId} Current user's external ID filter: " CreatedById = '{User.xId}' "
{User.Department} User's department filter: " Department = '{User.Department}' "
{User.Building.Id} Related field value filter: " Building = '{User.Building.Id}' "

Report Permissions

role Manager {
	report *                          // All reports
	report "blanket-agreement"        // Specific report
	report "purchase-order"
}

Global Role (Wildcard)

Apply rules to all roles using role *:

role * {
	deny * {
		delete
	}
}

This denies delete permission globally across all roles.

Deny Permissions

Explicitly deny permissions:

role * {
	deny * {
		delete
	}
}

role RestrictedRole {
	deny ObjectName {
		delete
		update
	}
}

Complete RBAC Examples

Example 1: Tenant Role (External User)

@company "{company}"

role Tenant {
	allow Activity
	allow ServiceRequest
	allow Tenant
	allow WorkOrderJob
	allow WorkOrder
	allow MoveOutRequest
	allow FitOutRequest
}

Example 2: Technician Role (Filtered Access)

@company "{company}"

role Technician {
	allow Activity
	allow ServiceRequest
	allow WorkOrder

	allow EmergencyJob {
		view {
			filter: " Team = '{User.RecordId}' "
		}
		create
		update
		patch
	}

	allow WorkOrderJob {
		view {
			filter: " Team = '{User.RecordId}' "
		}
		update
		patch
	}

	allow PettyCashRequest {
		view {
			filter: " CreatedById = '{User.xId}' "
		}
		create
		update
		patch
		list
	}

	allow Employee {
		view
	}

	allow Company {
		List
	}

	allow Currency {
		List
	}
}

Example 3: Finance Manager Role

@company "{company}"

role Finance_Manager {
	allow Finance

	allow Supplier {
		view
	}

	allow Payment
	allow BankAccount
	allow PurchaseOrder
	allow PurchaseInvoice

	allow Company {
		List
	}

	report *
}

Example 4: Supervisor Role

@company "{company}"

role Supervisor {
	allow ServiceRequest
	allow WorkOrder
	allow WorkOrderJob
	allow VisualInspection
	allow MoveOutRequest
	allow PettyCashRequest
	allow PettyCash

	allow Employee {
		view
	}

	allow Building {
		view
	}

	allow Unit {
		view
	}

	allow Company {
		List
	}
}

Example 5: Supplier Role (External Portal)

@company "{company}"

role Supplier {
	allow RequestForQuotation {
		view
	}

	allow Quotation

	allow Company {
		List
	}

	allow TaxRule {
		List
	}

	allow Currency {
		List
	}
}

Example 6: Global Restrictions with Admin

@company "{company}"

role * {
	deny * {
		delete
	}
}

role Admin {
	allow Finance
	allow Leasing
	allow FacilityManagement

	report *
}

Role Profiles

Profiles combine multiple roles into reusable groups. Define profiles in .profiles.rbac files:

profile AccountantPayable {
	include Accountant_Payable
	include Petty_Cash_Approver
}

profile PayableController {
	include Payable_Controller
	include Purchase_Invoice_Approver
}

profile LeasingExecutive {
	include Leasing_Executive
	include Sales_Team
	include Contract_Officer
}

profile PropertyManager {
	include Leasing_Executive
	include Finance_Viewer
	include FM_Supervisor
}

Common Permission Patterns

Read-Only Access:

allow ObjectName {
	view
}

Create and Edit (No Delete):

allow ObjectName {
	view
	create
	update
	patch
	list
}

Full Access:

allow ObjectName

User's Own Records Only:

allow ObjectName {
	view {
		filter: " CreatedById = '{User.xId}' "
	}
	create
	update
	patch
	list
}

Team-Based Access:

allow ObjectName {
	view {
		filter: " Team = '{User.RecordId}' "
	}
	create
	update
	patch
}

Department-Based Access:

allow ObjectName {
	view {
		filter: " Department = '{User.Department}' "
	}
	update
	patch
}

Best Practices

  1. Use role * for global policies — Apply universal restrictions like delete denial
  2. Filter by user context — Use {User.RecordId} and {User.xId} for user-specific filtering
  3. Grant minimal permissions — Only provide necessary permissions
  4. Use application-level access sparingly — Prefer specific object permissions
  5. Combine with profiles — Use profiles to create reusable role combinations
  6. List permissions for lookups — Include List permission for objects used in dropdowns
  7. Include system objects — Grant access to Company, Currency, etc. for proper functionality
  8. Filter sensitive data — Restrict access to user's own records or team
  9. Document role purposes — Use clear role names that indicate responsibility
  10. Test permission combinations — Verify that role combinations don't create security gaps

Experience the Platform

See how P9 and the Tuli platform work together

Ready to Build with P9?

Get hands-on with the platform. See how P9 accelerates your development workflow and integrates seamlessly with your existing systems.