We use machine learning technology to do auto-translation. Click "English" on top navigation bar to check Chinese version.
Control access to Amazon OpenSearch Service Dashboards with attribute-based role mappings
Federated users of
This post shows how you can implement custom role mappings with an Amazon Cognito pre-token generation
Overview of solution
The provided solution intercepts the OICD-based login process to OpenSearch Dashboards with a pre-token generation Lambda function. The login to OpenSearch Dashboards with a third-party IdP and Amazon Cognito as an intermediary consists of several steps:
- First, the initial user request to OpenSearch Dashboard is redirected to Amazon Cognito.
- Amazon Cognito redirects the request to the IdP for authentication.
- After the user authenticates, the IdP sends the identity token (ID token) back to Amazon Cognito.
- Amazon Cognito invokes a Lambda function that modifies the obtained token. We use an
Amazon DynamoDB table to perform role mapping lookups. The modified token now contains the IAM role mapping information. - Amazon Cognito uses this role mapping information to map the user to the specified IAM role and provides the role credentials.
- OpenSearch Service maps the IAM role credentials to OpenSearch roles and applies fine-grained permission checks.
The following architecture outlines the login flow from a user’s perspective.
On the backend, OpenSearch Dashboards integrates with an Amazon Cognito user pool and an Amazon Cognito identity pool during the authentication flow. The steps are as follows:
- Authenticate and get tokens.
- Look up the token attribute and IAM role mapping and overwrite the Amazon Cognito attribute.
- Exchange tokens for Amazon Web Services credentials used by OpenSearch dashboards.
The following architecture shows this backend perspective to the authentication process.
In the remainder of this post, we walk through the configurations necessary for an authentication flow in which a Lambda function implements custom role mapping logic. We provide sample Lambda code for the mapping of multivalued OIDC attributes to IAM roles based on a DynamoDB lookup table with the following structure.
OIDC Attribute Value | IAM Role |
["attribute_a","attribute_b"] |
arn:aws:iam:: <aws-account-id> :role/ <role-name-01> |
["attribute_a","attribute_x"] |
arn:aws:iam:: <aws-account-id> :role/ <role-name-02> |
The high-level steps of the solution presented in this post are as follows:
- Configure Amazon Cognito authentication for OpenSearch Dashboards.
- Add IAM roles for mappings to OpenSearch Service roles.
- Configure the Okta IdP.
- Add a third-party OIDC IdP to the Amazon Cognito user pool.
- Map IAM roles to OpenSearch Service roles.
- Create the DynamoDB attribute-role mapping table.
- Deploy and configure the pre-token generation Lambda function.
- Configure the pre-token generation Lambda trigger.
- Test the login to OpenSearch Dashboards.
Prerequisites
For this walkthrough, you should have the following prerequisites:
- An
Amazon Web Services account with anOpenSearch Service domain . - A third-party IdP that supports OpenID Connect and adds a multivalued attribute in the authorization token. For this post, we use
attributes_array
as this attribute’s name andOkta as an IdP provider. You can create anOkta Developer Edition free account to test the setup.
Configure Amazon Cognito authentication for OpenSearch Dashboards
The modification of authentication tokens requires you to configure the OpenSearch Service domain to use Amazon Cognito for authentication. For instructions, refer to
The Lambda function implements custom role mappings by setting the cognito:preferred_role
claim (for more information, refer to
cognito:preferred_role
claim to select the correct IAM role. The following screenshot shows the required settings in the Amazon Cognito identity pool that is created during the configuration of Amazon Cognito authentication for OpenSearch Service.
Add IAM roles for mappings to OpenSearch roles
IAM roles used for mappings to OpenSearch roles require a trust policy so that authenticated users can assume them. The trust policy needs to reference the Amazon Cognito identity pool created during the configuration of Amazon Cognito authentication for OpenSearch Service. Create at least one IAM role with a custom trust policy. For instructions, refer to
Configure the Okta IdP
In this section, we describe the configuration steps to include a multivalued attribute_array
attribute in the token provided by Okta. For more information, refer to
The first step is adding the attributes_array
attribute to the Okta user profile.
- Use Okta’s Profile Editor under Directory , Profile Editor .
- Select User (default) and then choose Add Attribute .
- Add an attribute with a display name and variable name
attributes_array
of type string array .
The following screenshot shows the Okta default user profile after the custom attribute has been added.
- Next, add
attributes_array
attribute values to users using Okta’s user management interface under Directory , People . - Select a user and choose Profile .
- Choose Edit and enter attribute values.
The following screenshot shows an example of attributes_array
attribute values within a user profile.
The next step is adding the attributes_array
attribute to the ID token that is generated during the authentication process.
- On the Okta console, choose Security , API and select the
default
authorization server. - Choose Claims and choose Add Claim to add the
attributes_array
attribute as part of the ID token. - As the scope, enter
openid
and as the attribute value, enteruser.attributes_array
.
This references the previously created attribute in a user’s profile.
- Next, create an application for the federation with Amazon Cognito. For instructions, refer to
How do I set up Okta as an OpenID Connect identity provider in an Amazon Cognito user pool .
The last step assigns the Okta application to Okta users.
- Navigate to Directory , People , select a user, and choose Assign Applications .
- Select the application you created in the previous step.
Add a third-party OIDC IdP to the Amazon Cognito user pool
We are implementing the role mapping based on the information provided in a multivalued OIDC attribute. The authentication token needs to include this attribute. If you followed the previously described Okta configuration, the attribute is automatically added to the ID token of a user. If you used another IdP, you might have to request the attribute explicitly. For this, add the attribute name to the Authorized scopes list of the IdP in Amazon Cognito.
For instructions on how to set up the federation between a third-party IdP and an Amazon Cognito user pool and how to request additional attributes, refer to
After requesting the token via OIDC, you need to map the attribute to an Amazon Cognito user pool attribute. For instructions, refer to
Map IAM roles to OpenSearch Service roles
Upon login, OpenSearch Service maps users to an OpenSearch Service role based on the IAM role ARN set in the cognito:preferred_role
claim by the pre-token generation Lambda trigger. This requires a role mapping in OpenSearch Service. To add such role mappings to IAM backend roles, refer to
Create the attribute-role mapping table
For this solution, we use DynamoDB to store mappings of users to IAM roles. For instructions, refer to
Key
of type String
. You need the table name in the subsequent step to configure the Lambda function.
The next step is writing the mapping information into the table. A mapping entry consists of the following attributes:
- Key – A string that contains attribute values in comma-separated alphabetical order
- RoleArn – A string with the IAM role ARN to which the attribute value combination should be mapped
For details on how to add data to a DynamoDB table, refer to
For example, if the previously configured OIDC attribute attributes_array
contains three values, attribute_a
, attribute_b
, and attribute_c
, the entry in the mapping table looks like table line 1 in the following screenshot.
Deploy and configure the pre-token generation Lambda function
A Lambda function implements the custom role mapping logic. The Lambda function receives an Amazon Cognito event as input and extracts attribute information out of it. It uses the attribute information for a lookup in a DynamoDB table and retrieves the value for cognito:preferred_role
. Follow the steps in
The Lambda function expects three environment variables. Refer to
- TABLE_NAME – The name of the previously created DynamoDB table. This table is used for the lookups.
- UNAUTHORIZED_ROLE – The ARN of the IAM role that is used when no mapping is found in the lookup table.
- USER_POOL_ATTRIBUTE – The Amazon Cognito user pool attribute used for the IAM role lookup. In our example, this attribute is named
custom:attributes_array
.
The following screenshot shows the final configuration.
The Lambda function needs permissions to access the DynamoDB lookup table. Set permissions as follows: attach the following policy to the Lambda execution role (for instructions, refer to
The configuration of the Lambda function is now complete.
Configure the pre-token generation Lambda trigger
As final step, add a pre-token generation trigger to the Amazon Cognito user pool and reference the newly created Lambda function. For details, refer to
This step completes the setup; Amazon Cognito now maps users to OpenSearch Service roles based on the values provided in an OIDC attribute.
Test the login to OpenSearch Dashboards
The following diagram shows an exemplary login flow and the corresponding screenshots for an Okta user user1
with a user profile attribute attribute_array
and value: ["attribute_a", "attribute_b", "attribute_c"]
.
Clean up
To avoid incurring future charges, delete the OpenSearch Service domain, Amazon Cognito user pool and identity pool, Lambda function, and DynamoDB table created as part of this post.
Conclusion
In this post, we demonstrated how to set up a custom mapping to OpenSearch Service roles using values provided via an OIDC attribute. We dynamically set the cognito:preferred_role
claim using an Amazon Cognito pre-token generation Lambda trigger and a DynamoDB table for lookup. The solution is capable of handling dynamic multivalued user attributes, but you can extend it with further application logic that goes beyond a simple lookup. The steps in this post are a proof of concept. If you plan to develop this into a productive solution, we recommend implementing
The post highlights just one use case of how you can use Amazon Cognito support for Lambda triggers to implement custom authentication needs. If you’re interested in further details, refer to
About the Authors
The mentioned AWS GenAI Services service names relating to generative AI are only available or previewed in the Global Regions. Amazon Web Services China promotes AWS GenAI Services relating to generative AI solely for China-to-global business purposes and/or advanced technology introduction.