For a business requirements see User management.
There are two dimensions of access control in the backoffice
Every user is part of a team (group), granting them permissions to access some features
Every user has a role, which further affects what they can do
The access control is defined in Okta identity manager.
The Person responsible for onboarding into Okta and giving BOFE access is Lucky La Torre (Unlicensed)
1. Groups and permissions
The backoffice teams are modelled in Okta as “groups”, so going forward they will be called “groups” here.
The source of truth for groups and their permissions is call Access Matrix and is in Lark
Technical matrix, replicated also in permission-migration-generator/access_matrix.csv
Stored also in the
user_group_permissions
table in thebackoffice-manager
The info from the Business matrix is converted into the Technical matrix by hand. Make sure the business people know that and do not edit the matrix without telling the devs.
Also the mapping is not 1-to-1 but attributes with same right are grouped to keep the permissions system simpler.
Team name | Technical group name |
---|---|
Developers | developers Important: we presumably don’t want to have this role in production (?). |
Payments and Card OPS Team | payments-cards |
CDD Team | customer-due-diligence |
CC Team | call-center |
Telesales Team | telesales |
Sales Team | sales |
Collections Team | collections |
Risk - Underwriting Team | risk-underwriting |
Risk - AntiFraud Team | risk-antifraud |
Okta has separate groups for each environment with the group names in format
bofe-{environment}-{technical group name}
For example: bofe-brave-developers
, bofe-brave-risk-underwriting
, bofe-stage-sales
In the day-to-day bank operation it is expected that each user will belong to one team/group.
However, the system allows users to belong to any number of groups (gaining permission of all the groups).
Permissions
As seen in the access matrix, each group gives certain permissions to its users.
In the (real-world) example below:
Everyone can view customer profile and customer address
Only Customer due diligence (CDD) team can edit the customer profile
Only CDD, Call center and Sales teams can edit the customer address
These permissions strings are used in both BE and FE to restrict what users can see and do.
Adding/removing/updating permissions
To update permissions use the Permission migration generator to generate a migration for the user_group_permissions
table. First. you should export the technical access matrix tab as a CSV.
Checking for permission in backoffice-manager BE
To check the permission use @BankUserOnly
to get the bank user that is calling the endpoint and verifyUserHasPermission
to test for certain permission.
In this example, we check if the user can view details of the “main account” of a customer:
@Get(uri = "/main-account/by-customer/{ownerId}", produces = ["application/json"]) @BankUserOnly fun getMainAccountByCustomer(ownerId: UUID, bankUser: BankUserAuthentication): AccountV2Dto { val bankUserDto = iamDefaultApiClient.getUser(bankUser.uid) userAuthorizationService.verifyUserHasPermission( bankUserDto, UserPermission.MAIN_ACCOUNT_VIEW ) return mainAccountApiClient.getMainAccountByCustomer(ownerId) ?: throw AccountNotFoundException("Account for owner id $ownerId not found") }
Checking for permission in app-bo FE
To check if the current user has certain permission use the usePermission
hook.
It has two modes of use
To check just single permission
const { isAllowed } = usePermission('CUSTOMER_EMPLOYEE_FLAG_UPDATE')
To check multiple permissions
const { allows } = usePermission() cosnt isAllowed = allows('CUSTOMER_EMPLOYEE_FLAG_UPDATE') // synchronous
Frequently you want to hinder some component(s) when the user does not have some permission, for this PermissionGuard component can be used like so:
<PermissionGuard permission="DOCUMENT_UPLOAD"> <CustomButton onClick={handleOpen}> {t('uploadButton')} </CustomButton> </PermissionGuard>
Another notable helper is getRoutePermission
.
The access matrix is changing very rarely, so once the FE fetches the permissions for the first time it caches them forever (until the page is closed or refreshed).
2. Roles
The user’s role is determined by how the user’s profile is set up directly in Okta (see https://safibank.atlassian.net/wiki/spaces/ITArch/pages/122322947/IAM+for+Back+Office#Specifying-checkers). Every user can have 1 other user set as “Checker” in Okta.
The user is considered to have a “Maker role” if he/she has a Checker set
The user is considered to have a “Checker role” if he/she is set as Checker of somebody
This means that a user can be both or neither.
The single attribute on Okta is really all there is, there is no “role” attribute anywhere.
There is a getUser endpoint that contains his resolved into isMaker
and isChecker
attributes.
There is also getCheckersForUser endpoint to all checkers for a user (i.s. user’s checker, that checker’s checker (if present) etc.)
There is no simple way to find the reverse - all users someone is checker of.
For more info about the maker-checker process see Maker-checker flows
In the day-to-day bank operation it is expected there will be in each team
Several “makers”, standard employees
One team supervisor as their direct checker, but also maker
Section head, direct checker of the team supervisor (but able to check also employees)
However the system is build to support also longer and bigger hierarchies.
Also nothing prevents the maker and his/her checker to be in different teams/groups, but in correct setup this is not supposed to happen.
The distinction behind the two roles is as follows:
Maker | Checker | None | |
---|---|---|---|
Can view customer data | Yes | Yes | Yes |
Can modify customer data | Yes | No | No |
Can approve/reject customer data modifications | No | Yes | No |
This is on top of the permissions granted by groups!
So to modify X, a user need to have both “Maker role” AND be in agroup that grants X_UPDATE
permission.
So in this example
Everyone can view the customer profile, regardless of group or role
Customer due diligence (CDD) users that have “Maker role” can edit customer profile
Other CDD users (“Checker” or no role) cannot edit customer profile (permitted by the group but, not by role)
No Call center users can edit customer profile (even “Makers”, as their group does not permit it)
Adding/removing the role
As mentioned this, is done in Okta
To add “Marker role” to a user, set Checker in the profile of that user
Unset to remove
To add “Checker role” to a user, set that user as Checker os someone else
Unset the user from all makers to remove
Checking for roles in backoffice-manager BE
For makers use
UserAuthorizationService.verifyUserIsMaker
helperFor checkers we only check if they can approve/reject a change and for that a
Change.allowedCheckerIds
is used directly (see Maker-checker flows)
Checking for roles in backoffice-manager FE
For makers, this is done automatically by the
usePermission
hook which allows only the permissions that matchNON_MAKER_SUFFIXES
for users that are not makers.For checkers, we use a more fine-grained check as every
Change
includes an explicit list ofallowedCheckerIds
and only if the current user is one of them the approve/reject change buttons are shown. (see Maker-checker flows)
The isMaker
and isChecker
attributes are present in the user produced by useUserInfo()
hook if needed for other purposes or some special checks.
Attachments:
Screenshot from 2022-11-22 15-24-36.png (image/png)
Screenshot from 2022-11-22 16-15-47.png (image/png)
Screenshot from 2022-11-22 16-15-47.png (image/png)