AWS Cognito Authentication with Grafana Part 2: User roles

AWS Cognito Authentication with Grafana Part 2: User roles

In this second installment of the AWS Cognito IDP for the Grafana series, we will see how to assign user roles based on the Cognito groups that the user is assigned to.

In short, we will create a user group 'Admin' in AWS Cognito and assign the Admin right in Grafana to all the users that belong to that group. All other users will get 'Viewer' rights by default.

We will use the same local development environment that we spun up in Part 1.

AWS Cognito groups

First things first, AWS Cognito readily supports user groups. We will use this feature to assign our user role.

We create a new group by choosing the Groups tab from our User pool details and clicking Create group.

We give our group name "Admin".  It is good to keep in mind that the name cannot be changed later on. Other attributes are mutable. At this point, we do not worry about Precedence or IAM Role, as we are not using the user pool to assign access to any other services.

Finally, we need to add our user to the Admin group. This is by going into the corresponding user details and clicking "Add user to a group". After this, we are done with the Cognito and can move on the configuring Grafana.

Grafana role assignment

We use the same configuration as in Part 1 and just append our role assignment part to it.

The group assignment is delivered to Grafana at authentication via the id_token and the payload looks roughly something like this

{
	"at_hash": "wjMOZh_DyQHXkpPhKeWUnw",
	"sub": "a43e38cf-39ce-488a-8ad5-394763a0f918",
	"cognito:groups": [
		"Admin"
	],
	"email_verified": true,
	"iss": "https:\\/\\/cognito-idp.eu-north-1.amazonaws.com\\/eu-north-1_4YOCIIKfY",
	"cognito:username": "a43e38cf-39ce-488a-8ad5-394763a0f918",
	"origin_jti": "82 2faaad-60ea-42e3-a638-a9324a4f5380",
	"aud": "50qt5r0oqne81l852a1a3pmmv6",
	"event_id": "2d88840d-282b-4f5a-bbdb-32c7b4902423",
	"token_use": "id",
	"auth_time": 1647589797,
	"name": "Test User",
	"exp": 1647593397,
	"iat": 1647589797,
	"jti": "2afb8545-0eec-45c3-96fa-3d40e8277143",
	"email": "[email protected]"
}

What we would like to do is check whether cognito:groups contains a group Admin. If it does, assign a role Admin to the user. Otherwise, set it to Viewer.

Grafana uses JMESPath queries to handle this type of validation. A handy tool to develop your own queries can be found at jmespath.org.

The query that we are looking for goes like this

("cognito:groups" | contains([*], 'Admin') && 'Admin' || 'Viewer')

We can configure Grafana to apply this query for role assignment by setting the OAuth configuration line

GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH = ("cognito:groups" | contains([*], 'Admin') && 'Admin' || 'Viewer')

That is it, now try to log in as your user and it should be assigned the admin role.

Remember to log in and out. Otherwise, the login details will not get updated.  

What's up next?

In the upcoming parts of the series, we have a look at how to configure Cloudfront caching policies, to support OAuth session information and cookies. Finally, we will put it all together with Terraform for easy deployment.