Michael Hoennig
2022-11-25 db17a2e9903e4bb3aad7c8851af4811951c0bc42
doc/rbac.md
@@ -103,7 +103,7 @@
    enum RbacOperation {
        add-package
        add-domain
        add-unixuser
        add-domain
        ...
        view
        edit
@@ -220,18 +220,51 @@
The admin-role is granted to a role of those subjects who manage the business object.
E.g. a 'package' is manged by the admin of the customer.
Whoever has the admin-role assigned, do everything with the related business-object, including deleting (or deactivating) it.
Whoever has the admin-role assigned, can usually edit the related business-object but not deleting (or deactivating) it.
In most cases, the permissions to the 'view' operation is granted through the 'tenant' role.
By this, all roles ob sub-objects, which are assigned to the 'tenent' role, are also granted to the 'admin'.
The admin-role also comprises lesser roles, through which the view-permission is granted.
#### agent
The agent-role is not used in the examples of this document, because it's for more complex cases.
It's usually granted to those roles and users who represent the related business-object, but are not allowed to edit it.
Other than the tenant-role, it usually offers broader visibility of sub-business-objects (joined entities).
E.g. a package-admin is allowed to see the related debitor-business-object,
but not its banking data.
#### tenant
The tenant-role is granted to everybody who needs to be able to view the business-object.
The tenant-role is granted to everybody who needs to be able to view the business-object and (probably some) related business-objects.
Usually all owners, admins and tenants of sub-objects get this role granted.
Some business-objects only have very limited data directly in the main business-object and store more sensitive data in special sub-objects (e.g. 'customer-details') to which tenants of sub-objects of the main-object (e.g. package admins) do not get view permission.
#### guest
Like the agent-role, the guest-role too is not used in the examples of this document, because it's for more complex cases.
If the guest-role exists, the view-permission is granted to it, instead of to the tenant-role.
Other than the tenant-role, the guest-roles does never grant any roles of related objects.
Also, if the guest-role exists, the tenant-role receives the view-permission through the guest-role.
### Referenced Business Objects and Role-Depreciation
A general rule is, if one business object *origin* references another object *target* (in other words: one database table joins another table),
**and** a role for *origin* needs also access to *target*,
then usually the *target* role is granted to the *origin* role which is one level lower.
E.g. the admin-role of the *origin* object gets granted the agent-role (or, if it does not exist, then the tenant-role) of the *target* object.
Following this rule, also implies, that the number of indirections to which visibility can be granted is limited.
The admin-role of one object could be granted visibility to another object through at maximum 3 joins (agent->tenant->guest).
But not in all cases role-depreciation takes place.
E.g. often a tenant-role is granted another tenant-role,
because it should be again allowed to view sub-objects.
The same for the agent-role, often it is granted another agent-role.
## Example Users, Roles, Permissions and Business-Objects
@@ -359,7 +392,7 @@
        SELECT c.prefix, p.name as "package", ema.localPart || '@' || dom.name as "email-address"
          FROM emailaddress_rv ema
          JOIN domain_rv dom ON dom.uuid = ema.domainuuid
          JOIN unixuser_rv uu ON uu.uuid = dom.unixuseruuid
          JOIN domain_rv uu ON uu.uuid = dom.domainuuid
          JOIN package_rv p ON p.uuid = uu.packageuuid
          JOIN customer_rv c ON c.uuid = p.customeruuid;
    END TRANSACTION;
@@ -387,11 +420,11 @@
entity Domain
Domain o-- "*" EMailAddress
entity UnixUser
UnixUser o-- "*" Domain
entity domain
domain o-- "*" Domain
entity Package
Package o.. "*" UnixUser
Package o.. "*" domain
entity Customer
Customer o-- "*" Package
@@ -461,12 +494,12 @@
As you can see, there something special:
From the 'Role customer#xyz.owner' to the 'Role customer#xyz.admin' there is a dashed line, whereas all other lines are solid lines.
Solid lines means, that one role is granted to another and followed in all queries to the restricted views.
The dashed line means that one role is granted to another but not automatically followed in queries to the restricted views.
Solid lines means, that one role is granted to another and automatically assumed in all queries to the restricted views.
The dashed line means that one role is granted to another but not automatically assumed in queries to the restricted views.
The reason here is that otherwise simply too many objects would be accessible to those with the 'administrators' role and all queries would be slowed down vastly.
Grants which are not followed are still valid grants for `hsadminng.assumedRoles`.
Grants which are not automatically assumed are still valid grants for `hsadminng.assumedRoles`.
Thus, if you want to access anything below a customer, assume its role first.
There is actually another speciality in the customer roles:
@@ -497,7 +530,7 @@
    entity "Perm package#xyz00 *" as permPackageXyzAll
    permPackageXyzAll --> boPacXyz00
    
    entity "Perm package#xyz00 add-unixuser" as permPacXyz00AddUser
    entity "Perm package#xyz00 add-domain" as permPacXyz00AddUser
    permPacXyz00AddUser --> boPacXyz00
    entity "Perm package#xyz00 edit" as permPacXyz00Edit
@@ -591,7 +624,7 @@
         WHERE target.uuid IN (
            SELECT uuid
              FROM queryAccessibleObjectUuidsOfSubjectIds( 
                'view', 'customer', currentSubjectIds()));
                'view', 'customer', currentSubjectsUuids()));
This view should be automatically updatable.
Where, for updates, we actually have to check for 'edit' instead of 'view' operation, which makes it a bit more complicated.
@@ -609,7 +642,7 @@
        SELECT DISTINCT target.*
          FROM customer AS target
          JOIN queryAccessibleObjectUuidsOfSubjectIds( 
                'view', 'customer', currentSubjectIds()) AS allowedObjId
                'view', 'customer', currentSubjectsUuids()) AS allowedObjId
            ON target.uuid = allowedObjId;
This view cannot is not updatable automatically,
@@ -632,4 +665,47 @@
Both variants a viable option, depending on other needs, e.g. updatable views. 
## Access Control to RBAC-Objects
Access Control for business objects checked according to the assigned roles.
But we decided not to create such roles and permissions for the RBAC-Objects itself.
It would have overcomplicated the system and the necessary information can easily be added to the RBAC-Objects itself, mostly the `RbacGrant`s.
### RbacUser
Users can self-register, thus to create a new RbacUser entity, no login is required.
But such a user has no access-rights except viewing itself.
Users can view themselves.
And any user can view all other users as long as they have the same roles assigned.
As an exception, users which are assigned to global roles are not visible by other users.
At least an indirect lookup of known user-names (e.g. email address of the user) is possible
by users who have an empowered assignment of any role.
Otherwise, it would not be possible to assign roles to new users.
### RbacRole
All roles are system-defined and cannot be created or modified by any external API.
Users can view only the roles to which they are assigned.
## RbacGrant
Grant can be `empowered`, this means that the grantee user can grant the granted role to other users
and revoke grants to that role.
(TODO: access control part not yet implemented)
Grants can be `managed`, which means they are created and deleted by system-defined rules.
If a grant is not managed, it was created by an empowered user and can be deleted by empowered users.
Grants can be `assumed`, which means that they are immediately active.
If a grant is not assumed, the grantee user needs to use `assumeRoles` to activate it.
Users can see only grants of roles to which they are (directly?) assigned themselves.
TODO: If a user grants an indirect role to another user, that grant would not be visible to the user.
But if we make indirect grants visible, this would reveal too much information.
We also cannot keep the granting user in the grant because grants must survive deleted users,
e.g. if after an account was transferred to another user.