@PortalSecurity — access control
Class-level annotation — configures JWT role-based access control for portal entities.
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class PortalSecurity(
val viewRoles: Array<String> = [],
val editRoles: Array<String> = [],
val deleteRoles: Array<String> = [],
val actionRoles: Array<String> = [],
val ownerField: String = "",
val ownerRoles: Array<String> = []
)Parameters
| Parameter | Description |
|---|---|
viewRoles | Roles allowed to view/list. Empty array = no restriction |
editRoles | Roles allowed to create and update |
deleteRoles | Roles allowed to delete |
actionRoles | Roles allowed to execute @PortalAction |
ownerField | Entity field storing the JWT sub of the owner. Enables row-level security |
ownerRoles | Roles restricted to their own records (via ownerField) |
Role names must match the values in the JWT token configured by portal.ui.security.roles-attribute
(default: realm_access.roles).
Row-level security
When ownerField + ownerRoles are set:
- Listing/export — users with a role in
ownerRolessee only records whereownerField == JWT.sub - Create —
ownerFieldis automatically set toJWT.sub - Update/delete — only the owner can modify their own records
Examples
Full security configuration:
@PortalSecurity(
viewRoles = ["user", "editor", "admin"],
editRoles = ["editor", "admin"],
deleteRoles = ["admin"],
actionRoles = ["admin"]
)
@PortalEntity(label = "Customer", module = "CRM")
@Entity
class Customer { ... }Admin-only entity:
@PortalSecurity(
viewRoles = ["admin"],
editRoles = ["admin"],
deleteRoles = ["admin"],
actionRoles = ["admin"]
)
@PortalEntity(label = "System Configuration", module = "System")
@Entity
class SystemConfig { ... }Read-only entity (audit log):
@PortalSecurity(
viewRoles = ["user", "admin"],
editRoles = ["admin"],
deleteRoles = ["admin"],
actionRoles = ["admin"]
)
@PortalEntity(label = "Audit Log", module = "System", allowCreate = false, allowEdit = false)
@Entity
class AuditLog { ... }Row-level security (salesperson sees only their own leads):
@PortalSecurity(
viewRoles = ["sales", "manager", "admin"],
editRoles = ["sales", "manager", "admin"],
deleteRoles = ["manager", "admin"],
actionRoles = ["manager", "admin"],
ownerField = "createdBySub", // entity field storing JWT.sub of the owner
ownerRoles = ["sales"] // "sales" role sees only their own records
)
@PortalEntity(label = "Sales Leads", module = "CRM")
@Entity
class SalesLead {
@Column(length = 100)
@PortalField(label = "Owner (sub)", hidden = true)
var createdBySub: String = "" // automatically set from JWT on create
}Last updated on