Securing Amazon OpenSearch Service Dashboards with Amazon Cognito

Angel Conde
7 min readJul 15, 2022

In this post we are going to secure OpenSearch with Cognito and providing. Remember that OpenSearch is a distributed, community-driven, Apache 2.0-licensed, 100% open-source search and analytics suite used for a broad set of use cases like real-time application monitoring, log analytics, and website search. Amazon Cognito lets you add user sign-up, sign-in, and access control to your web and mobile apps quickly and easily.

This post covers a popular fine-grained access control use case: an IAM master role with Amazon Cognito authentication for OpenSearch Dashboards with admin permissions and an IAM role with limited permissions. This will work in conjunction with Cognito assigned roles. Although these steps use the Amazon Cognito user pool for authentication, this same basic process works for any Cognito authentication provider that lets you assign different IAM roles to different users.

Amazon Cognito Setup

The first step is to configure and setup Amazon Cognito with a User pool that will contain our users and groups and an Identity provider that will be used by OpenSearch to authenticate our users against Cognito.

User pool

First we are going to setup a Cognito user pool that will be used by OpenSearch for Authentication. Go to the Cognito console and click on Create user pool.

Amazon Cognito — user pool details

For sign-in options just check Email and click next. Leave the default password policy, for the Multi-factor authentication put that No MFA and check that User account recovery is checked ( just in case you forget the password) leave recovery options by Email only and click next. For the next screen please disable the options as seen in the following image.

Amazon Cognito — sign-up experience

Click next and for Email message delivery just use Send email with Cognito option with default settings and Click Next.

Choose then a User pool name, and please use Hosted authentication pages. As we are not using a custom domain just select use the Cognito domain option. Then you will need to put a domain prefix for it ( remember that this will need to be unique in the region you are using). You can see this details on the following image.

Amazon Cognito — Hosted auth

For the Initial app client put an App client name (Public client app type), for the Allowed callback URLs just put https://example.com as URL and click Next. After reviewing your settings click Create User Pool. Remember that in a production environment you will need to customize a the settings for the user pool such as the domain for the Hosted-UI (or just disable by using your custom frontend app), enable sign-up, etc.

Identity pool

Go to Cognito console on the AWS console and click Create new identity pool. Choose a pool name, uncheck unauthenticated identities and just click on Create pool.

Users Setup

IAM Roles

For this demo we are using two roles with a different set of permissions. Go to the IAM console, click on Roles and create two roles with a Custom trust policy.

  1. Master role with admin permissions,IAMMasterUserRole.
  2. Limited role with custom permissions, IAMLimitedUserRole.

In the master add a Permissions policy for getting full permissions to OpenSearch Dashboards to this role ( you can use an inline policy):

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "es:ESHttpGet",
"Resource": "*"
}
]
}

For each of the roles you need to Edit trust relationship, and ensure that the Amazon Cognito identity pool can assume the role. You should put the following statement, please change the identity-pool-id for the one we have created in the corresponding step.

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "identity-pool-id"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}]
}

Choose Update Trust Policy. Add the same trust policy to a second IAM role (IAMLimitedUserRole).

For this second role you do not need to add a permission policy.

Please take note of the ARN for each of the roles you have created.

Users Setup

We are going to create two groups and a user for each group inside the Cognito user pool that we created in the previous step.

Click on groups inside the user pool we created. And create two groups.

admin: in this group those users with with admin permissions for OpenSearch Dashboards will live, please select as IAM Role IAMMasterUserRole.

limited: in this group those users with with limited permissions for OpenSearch Dashboards will live, please select as IAM Role IAMLimitedUserRole.

Cognito user pool groups detail

Next click on users and create two users. Please remember to mark the email as verified and to not send an invitation.

When you have created both users go to each of the groups, click on their name and click on Add user to group and assign the user you want to be the admin to the admin group and the user you want to have limited permissions to the limited group.

OpenSearch setup

Go to the Amazon OpenSearch console and click on Create domain.

  • OpenSearch 1.0 or later.
  • Uncheck custom endpoint.
  • Public access Network.
  • Fine-grained access control enabled (on Access Policy) with an IAM role as the master user (IAMMasterUserRole for the rest of this tutorial). You need to put the ARN of that role here.
  • Amazon Cognito authentication enabled for OpenSearch Dashboards.
  • Choose as Deployment type Development and testing. For Availability zones just use 1 AZ and just 1 node.
  • Amazon Cognito authentication: enable the option. Then, you need to choose the user pool we just created and the identity pool ( remember that you need to put the region where you created the Cognito User/Identity pools). For the role name just let the default. You can see the policy applied if you click on “Role Policy”.

Click on Create.

We need to wait some minutes for our OpenSearch domain to be available.

Role mapping

Go to the Cognito console and click on the user pool we created on previous steps. If you go to the App Integration you should see a new one called OpenSearch with some random characters.

The next thing is to go the identity pool we created and click on edit. You should note that Unauthenticated identities now is unchecked. If you open Authentication providers you will have a new one using Cognito. Please review that the Client ID is the same that the new App client that has been automatically created (AmazonOpenSearchService…). On the Authenticated role selection please use the settings checked on the image. With this setting, users must be in a group to receive an IAM role after authenticating.

When our search domain is accesible we are going to log-in to OpenSearch Dashboards with the admin user we have created. Choose Global tenant for this user. In this set of steps we are going to create an internal OpenSearch role with limited permissions and map it to the IAMLimitedUserRole.

  1. Choose Add sample data and add some sample flight data.
  2. Choose Security, Roles, Create role.
  3. Name the role limited-role.
  4. For index permissions, specify opensearch_dashboards_sample_data_fli* for the index pattern (kibana_sample_data_fli* on Elasticsearch domains).
  5. For the action group, choose read.
  6. For Document level security, specify the following query:
{
“match”: {
“FlightDelay”: true
}
}

7. For field-level security, choose Exclude and specify FlightNum.

8. For Anonymization, specify Dest.

9. Choose Create.

10. Choose Mapped users, Manage mapping. Then add the ARN for IAMLimitedUserRole as an external identity and choose Map.

11. Return to the list of roles and choose opensearch_dashboards_user. Choose Mapped users, Manage mapping. Add the ARN for IAMLimitedUserRole as a backend role and choose Map.

12. In a new, private browser window, navigate to Dashboards, sign in using the user with limited permissions, and then choose Explore on my own.

13. Go to Dev Tools and run the default search:

GET _search
{
“query”: {
“match_all”: {}
}
}

14. Note the permissions error. limited-user doesn't have permissions to run cluster-wide searches.

15. Run another search:

GET opensearch_dashboards_sample_data_flights/_search
{
“query”: {
“match_all”: {}
}
}

16. Note that all matching documents have a FlightDelay field of true, an anonymized Dest field, and no FlightNum field.

Search query with Limited permissions ( note that you can see the “Dest”).

17. In your original browser window, signed in as master-user, choose Dev Tools, and then perform the same searches. Note the difference in permissions, number of hits, matching documents, and included fields.

Search query with Admin permissions ( note that you can see the “Dest”).

Conclusions

In this post we have seen to enable Fine Access Permissions with Amazon Cognito. With this kind of approach you can have different Cognito groups and users mapped to the internal OpenSearch permissions mechanism.

Happy Searching!

This blog represents my own viewpoints and not of my employer, Amazon Web Services (AWS). All product names, logos, and brands are the property of their respective owners. All diagrams and illustrations are property of the author unless otherwise noted.

--

--