Configure Single Sign-On (SSO)

Authentication via Single Sign-On (SSO), using an OpenID Connect identity provider, is set to enabled by default. You will need to provide the proper configuration in the form of a K8s secret (See Configure secret to be used for SSO) or disable sso.enabled flag.

To configure it:

  1. Create a file called sso-credentials.txt, including the following properties:

    scope=openid,profile,email
    client-id={your_client_id}
    client-secret={your_client_secret}
    issuer-uri={your_issuer_uri}
    user-name-attribute={optional_user_name_attribute_key}
    

    For the client-id, client-secret, and issuer-uri values, use values from your OpenID Connect identity provider. For the scope value, use a list of scopes to include in JWT identity tokens (if left empty, openid will be used). This list should be based on the scopes allowed by your identity provider. issuer-uri configuration should follow Spring Boot convention, as described in the official Spring Boot documentation.

    The user-name-attribute config is optional and is only used to display the username on the top right corner of API portal UI after a user logs in. By default, we use the subject from the OIDC token. If you'd like to choose a different user info claim to load from, you may set it to the name of that claim, otherwise you don't need to provide this setting. Please note that this configuration is applicable to the claims in the UserInfo response, NOT the claims in the ID Token, as described in the official Spring Security documentation#client-registration.

    The provider needs to be configured with an issuer-uri which is the URI that it asserts as its Issuer Identifier. For example, if the issuer-uri provided is "https://example.com", then an OpenID Provider Configuration Request will be made to "https://example.com/.well-known/openid-configuration". The result is expected to be an OpenID Provider Configuration Response.

    Note: Only authorization servers supporting OpenID Connect Discovery protocol can be used.

  2. Configure external authorization server to allow redirects back to the gateway. Refer to your authorization server's documentation on how to add redirect URIs and add https://<gateway-external-url-or-ip-address>/login/oauth2/code/sso to the list of allowed redirect URIs.

  3. Configure secret to be used for SSO. In this guide, the secret name used is sso-credentials.

  4. Create the API portal installation namespace if it doesn't already exist

    kubectl create ns ${INSTALLATION_NAMESPACE}
    
  5. In the API portal installation namespace, create a Kubernetes secret named sso-credentials using the sso-credentials.txt file created in the previous steps:

    kubectl create secret generic sso-credentials --from-env-file=./sso-credentials.txt -n ${INSTALLATION_NAMESPACE}
    
  6. Examine the secret using the kubectl describe command. Verify that the Data column of the secret contains all of the required properties listed above.

Configure secret to be used for SSO

API portal for VMware Tanzu searches for a secret named sso.secretName in the values.yaml file. The secret must exist in the same namespace as the API portal instance in order to be used by API portal.

An example using a secret named "sso-credentials" in its namespace:

sso:
  enabled: true # Can be omitted because SSO is enabled by default
  secretName: sso-credentials

Configure session store for SSO

When SSO is enabled and the apiPortalServer.replicaCount is set to a value greater than 1, the installer will deploy an Apache Geode cluster alongside the API portal application to store end user authentication sessions between replicas.

However, if you'd like to skip Geode deployment and rely on sticky session to ensure that each user is only connected to single instance, you may skip this section and follow Configure session affinity routing section instead.

If Geode deployment is not skipped, then the cluster is consist of a statefulset of Geode servers and a statefulset of Geode locators. When the Geode cluster is not available, the end users may have issue logging into the API portal app or loading the page. To ensure high availability of the Geode cluster, we create 2 locator nodes and 3 server nodes by default.

Note: In order to ensure sessions are persisted through restarts and upgrades, it is important to have more than 1 instance of each of the locator and server nodes.

You may configure the Apache Geode cluster by setting the following properties:

sso:
  session:
    geode:
      server:
        replicaCount: 3
        resources:
          requests:
            memory: "512Mi"
            cpu: "200m"
          limits:
            memory: "1024Mi"
            cpu: "1"
      locator:
        replicaCount: 2
        resources:
          requests:
            memory: "512Mi"
            cpu: "1"
          limits:
            memory: "1024Mi"
            cpu: "2"

Additionally, if you are using tanzu cli, you need to create the geode-auth generic secret with your choice of Geode Admin username and password.

kubectl create secret generic geode-auth --from-literal "username=${GEODE_ADMIN_USERNAME}" --from-literal "password=${GEODE_ADMIN_PASSWORD}"

Then, you can rerun the install/update command with the updated properties in values.yaml.

If you encounter any errors installing/scaling Geode, check the troubleshooting section for more details.

If you want to inspect on cluster status or resource usage, you may visit the dashboard at path ${GEODE_LOCATOR_URL}/pulse by exposing port 7070 of the locator service, e.g.:

kubectl port-forward service/geode-locator-${API_PORTAL_RELEASE_NAME} 7070:7070

Since the Geode cluster has security enabled, you will need to log in to the dashboard with the following username and password:

DASHBOARD_USERNAME=$(kubectl get secret geode-auth -o'jsonpath={$.data.username}' | base64 --decode)
DASHBOARD_PASSWORD=$(kubectl get secret geode-auth -o'jsonpath={$.data.password}' | base64 --decode)

Set Apache Geode image location

If the conditions of using session storage are met, API portal installation via Helm uses an Apache Geode image located in Dockerhub by default, so it's publicly accessible. However, if you want to pull your own image from a personal image registry, you can set the following parameters so they will be used during installation:

sso:
  session:
    geode:
      image: myregistry.com/geode:latest
      registryCredentialsSecret: my-custom-image-pull-secret-name

Both registry and image will be used to set Apache Geode servers and locators.

The optional parameter registryCredentialsSecret is used in case the registry is private and needs credentials to pull from it. You need to specify the name of the k8s secret created with the correct credentials for that registry. The process to create the secret is the same as creating the image pull secret during Helm installation:

kubectl create secret docker-registry my-custom-image-pull-secret-name -n ${INSTALLATION_NAMESPACE} \
--docker-server=${REGISTRY_HOSTNAME} \
--docker-username=${REGISTRY_USERNAME} \
--docker-password=${REGISTRY_PASSWORD}

Configure session affinity routing

API portal can be configured with SSO scaled out to more than 1 instance without sharing session data among instances. You may rely on session affinity routing, also known as sticky sessions, to make sure each user is only connected to a single API portal instance.

Note: You will lose your session data when the pods get restarted or upgraded. You may be redirect to the login page when that happens.

To disable Apache Geode deployment, you may set the following property in your installation values file:

sso:
  session:
    distributed: false  # Default value is `true`

If you have more than 1 replica of API portal, you may find the login flow broken because the default routing strategy is round robin among the instances. You will need to configure session affinity following the documentation of your ingress controller. Here are examples for some common ingress controllers:

  1. Example Ingress definition using Nginx ingress sticky sessions:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-portal-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/affinity: cookie
spec:
  rules:
  - host: api-portal.somedomain.example.spring.io
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: api-portal-server
            port:
              number: 8080
  1. Example HttpProxy definition using Contour session affinity routing:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: api-portal-ingress
spec:
  virtualhost:
    fqdn: api-portal.somedomain.example.spring.io
  routes:
    - conditions:
      - prefix: /
      services:
        - name: api-portal-server
          port: 8080
      loadBalancerPolicy:
        strategy: Cookie

After applying the session affinity routing rules, you should be able to log into API portal smoothly even when there are multiple replicas.

Setting SSO to identify roles [Optional]

API portal leverages the authentication done by the OIDC identity provider to identify and categorize users and their roles when they log in.

In order to have users with enhanced permissions managing different aspects of API portal, you have to set accordingly the mapping of the API Manager role. Please review the section Configure API Manager role in order to know more about setting API Manager roles configuration.

Configure API Manager role

To provide management of API details for the entire organization, API portal offers the possibility of identifying API managers via SSO. The role of API Manager has enhanced capabilities inside API portal.

The authentication of any user with the API Manager role is done by providing a claim inside the ID Token (managed by the OIDC identity provider). Leveraging the SSO configuration, you can specify which claim and what value(s) it can have in order to identify a user with the API Manager role. The following options are available:

K8s Installation Yaml Property Key Environment Variable Key Description Default value
sso.apiManager.roles SSO_API_MANAGER_ROLES (Optional) List of comma-separated values to identify an API manager. If left empty or undefined, API portal will never authenticate a user as an API manager. Any of the values provided in this option will be used to identify the user as an API manager (logical OR). empty
sso.apiManager.rolesAttributeName SSO_API_MANAGER_ROLES_ATTRIBUTE (Optional) Name of the claim to search for API manager values. If left empty or undefined, API portal will use the claim roles to search for API manager role values. roles

The following example shows the structure you have to configure in your values.yaml file:

sso:
  enabled: true
  secretName: my-sso-credentials
  apiManager:
    roles: admin, api-manager
    rolesAttributeName: team

Note: The configuration of the API Manager role requires SSO to be enabled. The OIDC identity provider is in charge of delivering an ID token with the expected information. Claims included in the token and their values are configured there.

check-circle-line exclamation-circle-line close-line
Scroll to top icon