-
Notifications
You must be signed in to change notification settings - Fork 2
Authorization Mechanism
This document details the inputs, behaviour, and outputs of the FAM Runtime Authorization Lookup.
The FAM Runtime Authorization Lookup component is a Lambda function that receives an event each time AWS Cognito is required to create a JSON Web Token as part of an OIDC authentication flow.
In order to successfully query the FAM data model, the Lambda must extract three pieces of information from the event.
- The user_type in order to identify whether the user belongs to IDIR or BCeID Business. (Source: "request"->"userAttributes"->"custom:idp_name")
- The user_guid which is the unique identifier of the user within the domain of the identity provider (IDIR or BCeID Business). (Source: "request"->"userAttributes"->"custom:idp_user_id")
- The cognito_client_id which identifies the application on behalf of which Cognito facilitated the authentication event. (Source: "callerContext"->"clientId")
These three attributes should be in every event received by the Lambda.
{ "callerContext": { "awsSdkVersion": "aws-sdk-unknown-unknown", "clientId": "3u3vm7ehhaj2iqkm851t8fl6gp" }, "region": "ca-central-1", "request": { "groupConfiguration": { "groupsToOverride": [ "ca-central-1_ixb69p4hq_IDIR" ], "iamRolesToOverride": [], "preferredRole": null }, "userAttributes": { "cognito:user_status": "EXTERNAL_PROVIDER", "custom:idp_display_name": "Gustafson, Conrad CITZ:IN", "custom:idp_name": "idir", "custom:idp_user_id": "B5ECDB094DFB4149A6A8445A01A96BF0", "custom:idp_username": "COGUSTAF", "email": "[email protected]", "email_verified": "false", "family_name": "Gustafson", "given_name": "Conrad", "identities": "[{\"userId\":\"b5ecdb094dfb4149a6a8445a01a96bf0@idir\",\"providerName\":\"IDIR\",\"providerType\":\"OIDC\",\"issuer\":null,\"primary\":true,\"dateCreated\":1664399277929}]", "name": "Conrad Gustafson", "preferred_username": "b5ecdb094dfb4149a6a8445a01a96bf0@idir", "sub": "f7e49325-3796-4663-8745-4161745e358c" } }, "response": { "claimsOverrideDetails": null }, "triggerSource": "TokenGeneration_HostedAuth", "userName": "idir_b5ecdb094dfb4149a6a8445a01a96bf0@idir", "userPoolId": "ca-central-1_ixb69p4hq", "version": "1" }
The primary behaviour of the Lambda function is to query the FAM database to find out the list of user role assignments the client application needs to be aware of. For MVP, only directly assigned roles are taken into account (future versions will support role groups as well). User role assignments that do not apply to the current application are filtered out.
SELECT user_id FROM app_fam.fam_user WHERE user_type = {custom:idp_name} AND user_guid = {custom:idp_user_id};
SELECT application.application_id FROM app_fam.fam_application application JOIN app_fam.fam_application_client client ON application.application_id = client.application_id WHERE client.cognito_client_id = {clientId};
The following query will find all the roles that apply to the given user within the context of the current application.
SELECT role.role_name, role.client_number_id, parent_role.role_name FROM app_fam.fam_role role LEFT JOIN app_fam.fam_role parent_role ON role.parent_role_id = parent_role.role_id JOIN app_fam.fam_application application ON role.application_id = application.application_id JOIN app_fam.fam_application_client client ON application.application_id = client.application_id JOIN app_fam.fam_user_role_xref role_assignment ON role.role_id = role_assignment.role_id JOIN app_fam.fam_user user_assigned ON role_assignment.user_id = user_assigned.user_id WHERE user_assigned.user_guid = {custom:idp_user_id} AND user_assigned.user_type = {custom:idp_name} AND client.cognito_client_id = {clientId};
Ideally, users would be input into the FAM database with their user_guid as their identifier. For version 1.0, FAM does not include the lookup function to find the user_guid by searching for the user with the IDIM web service. The FAM customers will input a new user, if necessary, using the "user name" and "user_type" (for example: "COGUSTAF", "idir").
When the user subsequently logs in through Cognito, the Authorization service will populate the "user_guid" and "cognito_user_id" fields.
INSERT INTO app_fam.fam_user (user_type, user_guid, cognito_user_id, user_name) VALUES( {custom:idp_name}, {custom:idp_user_id}, {sub}, {custom:idp_username}) ON CONFLICT ON CONSTRAINT fam_usr_uk DO UPDATE SET user_guid = {custom:idp_user_id}, cognito_user_id = {sub};
The output from the function is a simple list of roles that apply to the user for the current application context.
For simple roles that do not have a "parent" role, the convention for the role identifier will be: <role_name>
.
For example, if the logged-in user is assigned to a role called "FOM-MINISTRY", and that role does not relate to a specific forest client or have a parent role, then the Authorization function will translate the role into a Cognito override group called "FOM-MINISTRY" (no change).
For "forest client" roles (roles that require a forest client identifier for further context), the convention for the role identifier will be:
<parent role_name>.<forest client ID>
For example, in the scenario:
- The logged-in user is assigned to a role called "FOM-SUBMITTER456787"
- Role FOM-SUBMITTER456787 is associated with a forest client with the ID "000478HH"
- Role FOM-SUBMITTER456787 has a parent role with a name "FOM-SUBMITTER"
In this scenario, the Authorization function will translate the role into a Cognito override group called "FOM-SUBMITTER.000478HH".
{ "callerContext": { "awsSdkVersion": "aws-sdk-unknown-unknown", "clientId": "3u3vm7ehhaj2iqkm851t8fl6gp" }, "region": "ca-central-1", "request": { "groupConfiguration": { "groupsToOverride": [ "ca-central-1_ixb69p4hq_IDIR" ], "iamRolesToOverride": [], "preferredRole": null }, "userAttributes": { "cognito:user_status": "EXTERNAL_PROVIDER", "custom:idp_display_name": "Gustafson, Conrad CITZ:IN", "custom:idp_name": "idir", "custom:idp_user_id": "B5ECDB094DFB4149A6A8445A01A96BF0", "custom:idp_username": "COGUSTAF", "email": "[email protected]", "email_verified": "false", "family_name": "Gustafson", "given_name": "Conrad", "identities": "[{\"userId\":\"b5ecdb094dfb4149a6a8445a01a96bf0@idir\",\"providerName\":\"IDIR\",\"providerType\":\"OIDC\",\"issuer\":null,\"primary\":true,\"dateCreated\":1664399277929}]", "name": "Conrad Gustafson", "preferred_username": "b5ecdb094dfb4149a6a8445a01a96bf0@idir", "sub": "f7e49325-3796-4663-8745-4161745e358c" } }, "response": { "claimsOverrideDetails": { "groupOverrideDetails": { "groupsToOverride": ["FOM-MINSTRY", "FOM-SUBMITTER.000478HH"], "iamRolesToOverride": [], "preferredRole": "" } } }, "triggerSource": "TokenGeneration_HostedAuth", "userName": "idir_b5ecdb094dfb4149a6a8445a01a96bf0@idir", "userPoolId": "ca-central-1_ixb69p4hq", "version": "1" }
- Environment Management
- Release Management
- Creating a Release
- Database Backups and Restores
- OIDC Client Testing
- FAM Onboarding Ops Guide
- Setup AWS CloudWatch
- Setup AWS EC2 instance to connect to RDS Postgres Database
- Technical Troubleshooting
- Managing Terraform State
- Enable Cloudwatch Logs for API Gateway
- Update AWS CloudFront Certificate
- Verify IDIM BCeID Client SOAP Web Service