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 deactivate 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.

    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.

    kubectl describe secret/sso-credentials
    
    Name:         sso-credentials
    Namespace:    api-portal
    
    Data
    ====
    client-id:            14 bytes
    client-secret:        14 bytes
    issuer-uri:           43 bytes
    scope:                6 bytes
    user-name-attribute:  9 bytes
    

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

If SSO is enabled and the apiPortalServer.replicaCount is set to a value greater than 1, we recommend the usage of a session management server.

API portal offers integration with an existing Redis server. The user only needs to provide the credentials for API portal to connect to the server by creating a kubernetes secret in the same namespace in which API portal is deployed. Here's an example of the structure that the secret needs to have:

kubectl create secret generic my-redis-credentials \
    -n ${INSTALLATION_NAMESPACE} \
    --type="servicebinding.io/redis" \
    --from-literal=type=redis \
    --from-literal=host="${redis-host}" \
    --from-literal=port=${redis-port} \
    --from-literal=password="${redis-password}" \
    --from-literal=ssl="true|false"

The ssl key in the secret is optional. It indicates if TLS is used to secure the redis connection. When using TLS you will need to ensure API Portal is configured to trust the root CA being used. (See Using TLS with a custom Certificate Authority) for details.

The property that needs to be specified to include these credentials into the integration is the following:

  • sso.session.redis.redisCredentialSecret (Default: ""): Name of the K8s secret which holds the credentials for the Redis server

Example:

sso:
  session:
    redis:
      redisCredentialSecret: my-redis-credentials

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.

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 deactivate any alternative session sharing mechanism provided by API portal, 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

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