See: auth/README.md Permissions.md
The FOAM authorization system is built around four primary models: User, Group, Permission, and Capability. These models are connected through junction tables that enable many-to-many relationships while storing additional metadata.
GroupPermissionJunction: Manages many-to-many relationships between groups and permissionsUserCapabilityJunction: Manages many-to-many relationships between users and capabilities, storing additional data like status and expiry informationCapabilities can grant permissions through their permissionsGranted property. The authorization system uses these relationships to determine user permissions through both group membership and granted capabilities.
The @GroupName pseudo-permission creates a permission inheritance relationship between groups. When a group is assigned a permission with the @ prefix, it gains all permissions from the referenced target group.
@ are treated as special group references@ and looks up that group’s permissions@ prefix is reserved for this special functionality and shouldn’t be used for regular permission namesSee SPID.md for comprehensive documentation on the SPID system.
ServiceProvider is a subclass of Capability that extends the core capability functionality. This provides multi-tenancy by isolating data and permissions per service provider.
Each ServiceProvider automatically grants two specific permissions based on its ID:
serviceprovider.read.<spid> - Permission to read objects associated with this SPIDserviceproviderdao.read.<spid> - Permission to read ServiceProvider objects in the DAOEach User has a spid property that references their home ServiceProvider. When a user’s SPID is set or changed, the system automatically creates or updates UserCapabilityJunctions to grant the ServiceProvider capability.
The authorization system checks SPID permissions through:
serviceprovider.read.<spid> and serviceproviderdao.read.<spid>serviceprovider.read.<spid>, serviceprovider.update.<spid> and serviceprovider.remove.<spid> can be created for every existing ServiceProvider by running the createPermissions script by handThe fundamental difference between Groups and Capabilities lies in their relationship with Users:
Capabilities have a unique prerequisite system that Groups lack:
getPrereqsChainedStatus which evaluates the entire prerequisite chainThe prerequisite system enables powerful SPID-level feature control:
invalidateDependents method ensures all dependent UserCapabilityJunctions are updated when a SPID capability is removedThis design pattern allows for:
Additionally, sub-classes of Capability can be greated which offer specialized functionality. The ServiceProvide class is a sub-class Capability. The inherentPermissions Property is meant to be used by Capability sub-classes.
Roles are Groups that follow a specific naming convention and usage pattern in the FOAM authorization system. This is purely a convention, not enforced by the software architecture.
Roles are Groups whose IDs contain “Role”, conventionally as a prefix (e.g. OpsRole).
By convention, Roles:
Groups can inherit all permissions from a Role by assigning the pseudo-permission @RoleName. This creates a clean separation between:
The permission table view (PermissionTableView) uses its ROLE_PREFIX constant ('Role'). In roles-only mode it drops groups whose ID contains “Role” from the columns and filters the rows to the @Role... pseudo-permissions, so the matrix shows which groups inherit which roles.
This convention reduces maintenance overhead by:
RELATIONSHIP DSL which handles the underlying DAO configurations@ prefix for pseudo-permissions enables the role inheritance pattern