Secure AWS Kibana with AWS Cognito

In this blog post, we’ll look at how we can secure access to our AWS Elasticsearch service, including Kibana, using AWS Cognito. This setup will allow us to control who has access to our Kibana instance, as a username/password will be required for access.

Notes:

  • We’ll be using the GUI for deploying and configuring the services in AWS in this guide but we’d always recommend using automation tools to configure them from code in a real-world scenario.
  • If you deploy your AWS Elasticsearch service in to a VPC, you will only be able to access the endpoints from an instance within the VPC (or from a machine on a network attached to the VPC possibly via something such as AWS Direct Connect). To keep this guide simple, we’ll be deploying our AWS Elasticsearch instance using the “publicly accessible” mode instead. It’s possible to control access to specific IPs using the publicly accessible mode, but we’d recommend always deploying resources in to a VPC for systems containing sensitive data.

Deploy an AWS Elasticsearch Domain

Deploying an Elasticsearch Domain isn’t covered in this how-to guide but you can refer to this helpul guide on deploying an instance of the AWS Elasticsearch service. Remember, for simplicity, we’re going to use a “publicly accessible” domain for the rest of this post.

Once you have an Elasticsearch domain deployed, we can begin…

Deploy AWS Cognito Resources

“Amazon Cognito provides authentication, authorization, and user management for your web and mobile apps. Your users can sign in directly with a user name and password, or through a third party such as Facebook, Amazon, or Google.
The two main components of Amazon Cognito are user pools and identity pools. User pools are user directories that provide sign-up and sign-in options for your app users. Identity pools enable you to grant your users access to other AWS services. You can use identity pools and user pools separately or together.”

https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html

In AWS Cognito, we’ll need to deploy both a user pool and identity pool for our solution to work. Firstly, let’s deploy the User Pool.

Create A Cognito User Pool

Go to AWS Cognito -> Manage User Pools -> Create User Pool.  
Enter a “Pool Name” and then click on “Review Defaults”.

AWS Cognito -> Manage User Pools -> Create New User Pool

Confirm the defaults and click “Create Pool” on the next screen to create your User Pool.

Next, click “Domain Name” from the left hand-side menu and enter a unique domain name that will be used during the sign-in process.

Once you have decided what domain to use, click “Save Changes”.

AWS Cognito -> Manage User Pools -> [Your User Pool] -> Domain Name

It’s possible to add your company logo to the sign-in page too. Click on the “UI Customisation” on the left hand-side menu and upload your logo file to the User Pool. This will be displayed on your sign-in page.

Add A User To The User Pool

For the purpose of this demo, we’ll add a user to our Cognito User Pool for testing access. To do this, click on ‘Users and Groups’ from the left hand side menu. Click on ‘Create User’.

AWS Cognito -> Manage User Pool -> [Your User Pool] -> Users and Groups.

Fill in the required details, leaving the phone number box blank. Untick the ‘Verified Phone Number’ box. Click ‘Create User’. We’ll test access with this user later so keep the username and password handy.

Create A Cognito Identity Pool

Next, we need to create an Identity Pool.

Click on ‘Federated Identities’ button in the top-left of the screen to jump straight to Identity Pools, or go back to the AWS Cognito service landing page and click on ‘Manage Identity Pools’.

Click on ‘Create new Identity Pool’ and enter an Identity pool name. Next, check the ‘Enable access to unauthenticated identities’ box and then click on ‘Create Pool’.

AWS Cognito -> Manage Identity Pools -> Create new Identity Pool (Step 1)

On the next screen, you’ll be asked to create some IAM roles that will be used by Cognito, one each for authenticated and unauthenticated identities.

Ensure ‘Create a new IAM Role’ is selected in each drop-down, give the Roles a name in the ‘Role Name’ box and then click ‘Allow’ to complete the creation process.T

AWS Cognito -> Manage Identity Pools -> Create new Identity Pool (Step 1)

Update our AWS Elasticsearch Domain

Head back to the AWS Elasticsearch service, select your domain and click on ‘Configure Cluster’.

AWS Elasticsearch -> [Your Domain]

Scroll Down the configuration page until you get to the ‘Kibana Authentication’ section and check the ‘Enable Amazon Cognito for authentication’ box.

Select your User Pool from the ‘Cognito User Pool’ dropdown and your Identity Pool from the ‘Cognito Identity Pool’ dropdown.

Enter an IAM Role Name in to the ‘IAM Role Name’ box. This is an IAM Role that the AWS Elasticsearch service will use to assume permissions in the Cognito service. The permissions are pre-configured and can be viewed by clicking on the ‘AmazonESCognitoAccess’ link next to ‘Role Policy’.

AWS Elasticsearch -> [Your Domain] -> Configure Cluster (Kibana Authentication section)

Scroll to the bottom of the screen and click on ‘Submit’ to save the new configuration.

When we save these settings, AWS Elasticsearch will automatically populate our AWS Cognito User Pool with the correct settings

Your Elasticsearch cluster will now go in to ‘Modifying…’ status whilst the new settings are applied. It’s OK to continue with the next steps whilst waiting for this modification to complete.

Modify AWS Elasticsearch Access Policy

We now need to edit the Access Policy of our domain to allow AWS Cognito to interact with it.

Click on ‘Modify Access Policy’ on your domain page.

AWS Elasticsearch -> [Your Domain]

The access policy screen should now be visible. We’ll use a simple access policy in this how-to guide so click on ‘Select a template’ and select ‘Allow or deny access to one of more AWS accounts or IAM Users’ from the drop-down.

AWS Elasticsearch -> [Your Domain] -> Modify Access Policy

A pop-up will appear with some example configuration items displayed. As you can see, our Cognito Identity Pool IAM Role that we created earlier is displayed as the last item in the list.

Copy the full ARN next to ‘Cognito Identity Pool IAM role’ and paste it into the ‘Account ID or ARN*’ box.

Click on ‘OK’ to save the cofiguration.

AWS Elasticsearch -> [Your Domain] -> Modify Access Policy -> Select a template

The following JSON policy should be automatically generated and visible on the access template screen.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::XXXXX:role/Cognito_XXXXXAuth_Role"
        ]
      },
      "Action": [
        "es:*"
      ],
      "Resource": "arn:aws:es:eu-west-1:XXXXX:domain/XXXXX/*"
    }
  ]
}

As shown on the access policy screen:

AWS Elasticsearch -> [Your Domain] -> Modify Access Policy

Login!

Now, when we hit out Kibana URL in a browser, we will now be redirected to a Cognito login page. Sign in with the user you created earlier. After logging in, you’ll be re-directed to your Kibana service.

AWS Cognito Login Page
AWS Elasticsearch Kibana Service

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.