AWS — User federation using Keycloak & OpenId

Karanbir Singh
7 min readJun 5, 2020
AWS OpenID based User federation

Previously, I had shared the article where one could federate the user to AWS using SAML IDP flow.
And this article focuses on federating the user to AWS using OpenID Connect.
This solution is little complex than the previous as it requires a broker, between Keycloak and AWS

Prerequisites

  1. You should have the real urge to do federation between an identity provider and AWS using OpenID.
  2. Have some knowledge of — AWS, AWS IAM, OpenID, Access and Identity Management as general topic, Keycloak, etc.
  3. Keycloak version 10 or later, already running separately. I used patchy keycloak version 10 while doing all this. And could not wait for version 11.0.0’s release as there was an important blocker issue in version 10.0.1.
  4. Basic knowledge of Java(and Spring boot), required for the Broker application.

Scope

  1. Configuration setup of OpenID Identity Provider on the AWS side.
  2. Role management on the AWS IAM side.
  3. Configuration setup on the Keycloak side.
  4. And mapping of the users/ groups/ roles etc. on the Keycloak side.

Things Out of Scope

  1. Setting up Keycloak server is strictly out of scope!
  2. Setting up AWS account is also out of scope! 😃

Components

  1. AWS account(services)
  2. Keycloak Server 10.0.1 or Greater.
  3. Spring boot based Broker application.

Flow Diagram GIF (for interactive understanding)

This diagram will help you understand the requirement we want to achieve in here.

1. User goes to the custom open id broker application.

2. User redirected to the login page on Keycloak.

3. User authenticated using Keycloak using code grant.

4. User redirected to manage credentials dashboard.

5. User requests for credentials or console link for a role.

6. The broker application requests for the STS token.

7. The AWS IAM returns the Assumed Credentials.

8. Based on user’s selection Broker redirects to console or downloads credentials.json

Keycloak — Setup a new client(and Realm)

Step 1. It’s better to start by creating a new Realm on Keycloak. Here I am naming it as demo, you may still use the default master realm(you may still use existing realm, that’s up to the requirements and understanding).

create realm

Step 2. Hit the Clients tab on left and hit create, as below

create client

Step 3. Enter the desired Client ID, aws-open-id in my case here and select the protocol as openid-connect

Step 4. Change few Client settings
-
Change the Access Type to confidential (required for supporting code grant)
- Toggle various flow, grant, other toggles & settings as highlighted by 2.
- Add Valid Redirect URIs = http://localhost:38153/sso/login NOTE - This value is related to the broker application.

Step 5 Go to the Credentials tab for generating client secret
- Note: Credentials tab
shows up only if settings tab has confidential Access type is selected
-
Make sure it shows up like below (by default it should show up)
- Copy the secret
required for configuring in the broker application

AWS — Setup OpenID Identity Provider in IAM

Step 1. Sign in to the AWS web console using admin privileges and go to IAM console.

  • Then hit identity providers link
  • Hit Create provider button
  • Configure the provider
    - Provider Type = OpenID Connect
    -
    Provider URL = https://<keycloak host>/auth/realms/<realm name>
    - Note: Keycloak(IDP) has to be exposed on https as AWS requires to have CA thumbprint to verify certificate
    - Change the value of the host <keycloak host> accordingly
    - Also the <realm name> needs to be configured, it is demo in my case
    -
    Audience = aws-open-id (Client’s Id that was configured above on Keycloak)

Step 2 Click the Roles link on IAM console and click on Create role

  • Follow the order as below
    - Select Web identity
    - Select Identity provider that was created previously
    - Select Audience (is equal to the client id)
    - Hit Next for permissions
  • Attach permissions, policies etc.
    - For demo purpose I selected ReadOnlyAccess.
  • Add tags if required(you can skip the tags page also) and click next.
    Enter role name like — DEMO_OPEN_ID_READ_ONLY
    And click Create role button
  • After the role is successfully created, click on the role and copy the role’s ARN (required for later use, for configuring the user’s role in keycloak)
    - example —
    arn:aws:iam::<AWS_ACCOUNT_NUMBER>:role/DEMO_OPEN_ID_READ_ONLY

Keycloak Role mapping, Group, user setup, etc.

Step 1 Create a new role in the already created client which is aws-open-id from the previous steps.

- role name = arn:aws:iam::<AWS_ACCOUNT_NUMBER>:role/DEMO_OPEN_ID_READ_ONLY
- AWS_ACCOUNT_NUMBER
= AWS account’s number
- DEMO_OPEN_ID_READ_ONLY
= role that was created above in AWS

Step 2 Go to the Mappers section in the client details view and click on Create

And then fill the fields as below:-

Name = User role Mapper
Mapper Type = User Client Role
Client ID = aws-open-id
Multivalued = ON
Token Claim Name = roles
Claim JSON Type = String

And then hit Save button

Step 3 Create a group for managing users, and their access

  • Click on the Groups in the Manage section
    Create a group name example READ_ONLY_AWS_USERS.
  • Go to Role Mappings Tab
    - Search for the aws-open-id client in the Client Roles
    - Select the role(s)
    - Click Add selected

Step 4 Add User, Detailed screenshots are below

  • After saving the user, add the user to the previously created group.
  • Click Credentials Tab and add credentials(if required) as below

Setup Spring Boot based broker application

Prerequisites
- JDK 11
- Maven (3.6 or latest)
- Text Editor(Only for configuration)
- Intellij or Eclipse (if want to develop further)

Source Code

The link of the source code is herehttps://github.com/krnbr/aws-keycloak-openid-broker

Will focus more on the actual integration flow rather than details of code.

Step 1 Pull the code
Step 2 Configure the endpoint and AWS credentials

  • Change the properties in application.properties
    - change keycloak.realm to the name of realm
    - change keycloak.resource to the client id(aws-open-id in my case) created in Keycloak for AWS
    - change keycloak.auth-server-url to the auth url https://KEYCLOAK_DOMAIN/auth
    - KEYCLOAK_DOMAIN = hostname of your server. https is the only option on AWS front
    - change keycloak.credentials.secret to the client secret for client created in keycloak
    - aws.accessKeyId = the aws access key id for the aws user
    - aws.secretAccessKey = the aws secret access key for the aws user

NOTE — for the AWS Access keys in previous step, create a user with IAMFullAccess (arn:aws:iam::aws:policy/IAMFullAccess) policy. Access is not required for the web console, though only required for the sdk, cli, etc.

Step 3 Run the following command

mvn clean spring-boot:run

Broker Application Access

After the broker application is deployed go to http://localhost:38153

  • It will take you to a page/view like below
  • Hit Login using Keycloak - that will take you to the Keycloak login page as per the client Id, realm and other configurations.
  • Enter Credentials and Log In.
  • Post login you will be redirected back to the broker application for selecting option to download credentials or redirecting to the AWS web console.
  • Hit Get Credentials to download credential’s json file and you will be prompted to save the files as below
  • For AWS console, click on the Open Web Console Link and you will be redirected as below
  • Once the Session expires, the screen shows up as below(as per role’s session duration)

For any issues while running the code or understanding the code, please feel free to contact me on LinkedIn or reply on this article

For SAML based user federation, you can refer to my other article herehttps://medium.com/@karanbir.tech/aws-connect-saml-based-identity-provider-using-keycloak-9b3e6d0111e6

--

--

Karanbir Singh

API developer + Web Application developer + Devops Engineer = Full Stack Developer