Set up an IdP
Set up a supported OIDC IdP to use with Gloo Portal.
You can use the OpenID Connect (OIDC) Identity Provider (IdP) to enforce OAuth policies for several important use cases, such as securing the login to your portal frontend app.
About
You can use an IdP to enforce authentication for several use cases in Gloo Portal, such as protecting APIs with external auth policies, the portal frontend app, and IdP Connect. It is recommended to use the same IdP for all your Gloo Portal use cases. The following IdPs have been successfully set up with Portal: Amazon Cognito and Keycloak. If you use another IdP, you might need to modify the steps for your setup.
Step 1: Install Keycloak
You might want to test how to restrict access to your applications to authenticated users, such as with external auth or JWT policies. You can install Keycloak in your cluster as an OpenID Connect (OIDC) provider.
The following steps install Keycloak in your cluster, and configure two user credentials as follows.
- Username:
user1, password:password, email:user1@example.com - Username:
user2, password:password, email:user2@solo.io
Install and configure Keycloak:
Create a namespace for your Keycloak deployment.
kubectl create namespace keycloakCreate the Keycloak deployment.
kubectl -n keycloak apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/oidc/keycloak.yamlWait for the Keycloak rollout to finish.
kubectl -n keycloak rollout status deploy/keycloakSet the Keycloak endpoint details from the load balancer service.
export ENDPOINT_KEYCLOAK=$(kubectl -n keycloak get service keycloak -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}'):8080 export HOST_KEYCLOAK=$(echo ${ENDPOINT_KEYCLOAK} | cut -d: -f1) export PORT_KEYCLOAK=$(echo ${ENDPOINT_KEYCLOAK} | cut -d: -f2) export KEYCLOAK_URL=http://${ENDPOINT_KEYCLOAK} echo $KEYCLOAK_URLSet the Keycloak admin token. If you see a parsing error, try running the
curlcommand by itself. You might notice that your internet provider or network rules are blocking the requests. If so, you can update your security settings or change the network so that the request can be processed.export KEYCLOAK_TOKEN=$(curl -d "client_id=admin-cli" -d "username=admin" -d "password=admin" -d "grant_type=password" "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" | jq -r .access_token) echo $KEYCLOAK_TOKENUse the admin token to configure Keycloak with the two users for testing purposes. If you get a
401 Unauthorizederror, run the previous command and try again.# Create initial token to register the client read -r client token <<<$(curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"expiration": 0, "count": 1}' $KEYCLOAK_URL/admin/realms/master/clients-initial-access | jq -r '[.id, .token] | @tsv') export KEYCLOAK_CLIENT=${client} echo $KEYCLOAK_CLIENT # Register the client read -r id secret <<<$(curl -k -X POST -d "{ \"clientId\": \"${KEYCLOAK_CLIENT}\" }" -H "Content-Type:application/json" -H "Authorization: bearer ${token}" ${KEYCLOAK_URL}/realms/master/clients-registrations/default| jq -r '[.id, .secret] | @tsv') export KEYCLOAK_SECRET=${secret} echo $KEYCLOAK_SECRET # Add allowed redirect URIs curl -k -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X PUT -H "Content-Type: application/json" -d '{"serviceAccountsEnabled": true, "directAccessGrantsEnabled": true, "authorizationServicesEnabled": true, "redirectUris": ["*"]}' $KEYCLOAK_URL/admin/realms/master/clients/${id} # Add the group attribute in the JWT token returned by Keycloak curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"name": "group", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "config": {"claim.name": "group", "jsonType.label": "String", "user.attribute": "group", "id.token.claim": "true", "access.token.claim": "true"}}' $KEYCLOAK_URL/admin/realms/master/clients/${id}/protocol-mappers/models # Create first user curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"username": "user1", "email": "user1@example.com", "firstName": "Alice", "lastName": "Doe", "enabled": true, "attributes": {"group": "users"}, "credentials": [{"type": "password", "value": "password", "temporary": false}]}' $KEYCLOAK_URL/admin/realms/master/users # Create second user curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"username": "user2", "email": "user2@solo.io", "firstName": "Bob", "lastName": "Doe", "enabled": true, "attributes": {"group": "users"}, "credentials": [{"type": "password", "value": "password", "temporary": false}]}' $KEYCLOAK_URL/admin/realms/master/usersOpen the Keycloak frontend.
open $KEYCLOAK_URLLog in to the admin console, and enter
adminas the username andadminas your password.In the Keycloak admin console, go to Users, and verify that the users that created earlier are displayed. You might need to click on View all users to see them.
In the Keycloak admin console, go to Clients, and verify that you can see a client ID that equals the output of
$KEYCLOAK_CLIENT.
Step 2: Configure Keycloak
Configure your Keycloak client with the appropriate settings for the developer portal frontend authentication.
From the Keycloak sidebar menu options, click Clients.
Click the Client ID that matches the
$KEYCLOAK_CLIENTthat you previously set.From the client Settings tab, find the Access settings and update the following fields.
- Valid redirect URIs field with
*wildcard or the domain that you want to use for redirects. - Valid post logout redirect URIs field with
*wildcard or the domain that you want to use for logout redirects. - Web origins field with
*wildcard to allow all origins.
- Valid redirect URIs field with
Scroll down to the Capability config section and update the following sections:
- Toggle the Client authentication setting to
On. - Toggle the Authorization setting to
On. - In the Authentication flow section, enable the Standard flow and Direct access grants options.
- Toggle the Client authentication setting to
At the bottom of the form, click Save. The
Client successfully updatedmessage pops up to confirm your settings are saved.Set up the client with the required
manage-clientsrole. This way, you can use the Keycloak client to let users self-service the creation of their own OAuth credentials through the portal frontend app.- From the client Service accounts roles tab, click Assign role.
- Find or search for the
manage-clientsrole, check the row, and then click Assign. - Verify that you see the
manage-clientsrole in the Service accounts roles tab.
Step 3: Add custom claims
Optionally, you can add custom claims to the ID tokens that Keycloak generates for a user. For example, you might want to create policies that grant access based on custom claims. If you use Gloo Portal, you can use custom claims to authorize users to ApiProducts by creating a PortalGroup.
Gloo Portal includes a sample React frontend app for a developer portal. To protect the frontend app with an OAuth login, the OIDC provider must return access and ID tokens with the following claims. Keep in mind that your OIDC provider might also require the users to have values for these claims in order to return the claim (such as a first and last name, not just a username, configured in the user profile).
Claims required to log in:
emailnamepreferred_usernamesub
Claims required for admin tasks such as managing subscriptions:
group: admin, note that this claim cannot be returned as an array. If your IdP cannot provide thegroupclaim, such as whengroupis a reserved claim in Okta, you can customize this claim key name. For an example, see Customize the admin group claim name.
Some OIDC providers do not return all of these claims by default. In the AuthConfig, you might be able to request additional scopes, such as openid, profile, and email to get back tokens with these claims. Otherwise, create custom claims and claim mapping for these tokens in your OIDC provider.
In Keycloak, the name and group:admin claims are not returned by default. The following steps set up these custom claims. The steps also create a group called Users and assign user1 to this group, but not user2. The group membership is mapped to an X-groups claim in the ID token. The X-groups custom claim is later used as an example for PortalGroups. For more information about claim mapping, see the Keycloak docs.
If you are not already, log in to the Keycloak console as the
adminuser with theadminpassword.open $KEYCLOAK_URLConfigure the required
groupclaim for admins in the client.From the menu, click Manage > Clients.
From the list of clients, click the client ID that you use, such as
1234567-1aa1-1a11-2bb2-cc1234567.Click the Client scopes tab, then click the assigned client scope with your client ID, such as
1234567-1aa1-1a11-2bb2-cc1234567-dedicated.Click Add mapper > By configuration.
Click User Attribute.
In the
Namefield, enter a name for the mapper, such asgroup-mapper.In the
Token Claim Namefield, enter the name for the claim in the ID token,group.Confirm that the
Add to ID tokensetting is toggled on.Confirm that the
Multivaluedsetting is toggled off. You must set this value so that the claim has only one value and is not an array. The Gloo Portal sample React frontend app does not accept an array for thegroup: adminmembership.Click Save.
Repeat the previous step to add the required
nameclaim, which is not included in Keycloak tokens by default.From the
Client details > Dedicated scopes > Mapperstab, click Add mapper > By configuration.Click User Property.
In the
Namefield, enter a name for the mapper, such asname-mapper.In the
Token Claim Namefield, enter the name for the claim in the ID token,name.Confirm that the
Add to ID tokensetting is toggled on.Scroll down and click Save.
Configure the custom
X-groupsclaim for the client.From the
Client details > Dedicated scopes > Mapperstab, click Add mapper > By configuration.Click Group Membership.
In the
Namefield, enter a name for the mapper, such asgroup-mapper.In the
Token Claim Namefield, enter the name for the claim in the ID token, such asX-groups.Confirm that the
Add to ID tokensetting is toggled on.Scroll down and click Save.
Create the
adminandUsersgroup.From the menu, click Manage > Groups.
Click Create group.
Enter the name
Users, then click Create.Click Create group again, enter
admin, then click Create.In the list of groups, click Users.
Click the Members tab, then click Add member.
Select
user1, then click Add.In the list of groups, click admin.
Click the Members tab, then click Add member.
Select
user1andadmin, then click Add.Click the Attributes tab, then click Add attribute.
Enter
groupfor the key andnamefor the value, and then click Save.
Send a request to the Keycloak token endpoint to get back an ID token.
curl -X POST \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "client_id=$KEYCLOAK_CLIENT" \ -d "client_secret=$KEYCLOAK_SECRET" \ -d "grant_type=password" \ -d "username=user1" \ -d "password=password" \ -d "scope=openid" \ $KEYCLOAK_URL/realms/master/protocol/openid-connect/tokenExample response:
{ "access_token": "eyJhb...", "expires_in": 60, "refresh_expires_in": 1800, "refresh_token": "eyJhbG...", "token_type": "Bearer", "id_token": "eyJhbG...", "not-before-policy": 0, "session_state": "8ed...", "scope": "openid profile email" }To verify that the ID token includes the claims, decode the
id_tokenclaims by using a tool such as jwt.io oropenssl.echo '<id_token>' | awk -F. '{print $2}' | base64 -dExample output: Notice that the required
email,name,preferred_username,sub, andgroupsclaims are returned, along with theX-groupscustom claim.{ "exp": 1732140757, "iat": 1732140697, "jti": "091d4648-...", "iss": "$KEYCLOAK_URL/realms/master", "aud": "72182354-...", "sub": "d1150127-...", "typ": "ID", "azp": "72182354-...", "sid": "8ed0cbaa-...", "at_hash": "Iww...", "acr": "1", "email_verified": false, "name": "Alice Doe", "preferred_username": "user1", "email": "user1@example.com", "group": "admin", "X-groups": [ "/Users", "/admin" ] }
Next steps
Good job! Now that your IdP is set up for use with Gloo Portal, you can use OAuth policies to secure many parts of the portal. Check out the following guides.