App SSO Overview
App SSO is one of the great features offered in TAP, which has received a bunch of love in TAP 1.5 App SSO provides the needed APIs for curating and consuming a "Single Sign-On as a service" offering on Tanzu Application Platform.
Through App SSO, one can easily integrate TAP based workloads with SSO, in a secure, simple, and straightforward manner.
What’s new in TAP 1.5?
In TAP 1.5, App SSO has been enhanced with a few key new sets of functionality. The ones I am extremely excited about are:
- New AuthServer CORS API
- Role claim mapping from External IDP group membership
- New default auth scopes for users
Let’s take a look at each of these features and what they bring to the table.
Auth Server CORS API
When working with SPAs and mobile apps with SSO, we need to configure CORS which is never a fun thing to deal with. Now, in TAP 1.5, we have a very simple and clean UX for defining CORS for Public Clients as part of the Auth Server CR.
With this new API, we can simply enable web apps, that utilize the PKCE authentication flow.
While TAP does support allowing all origins for CORS, it is not recommended to do so from a security perspective, and this should be done with great caution.
Let’s see what the UX looks like. The first step one would do is define the Auth Server as they would previously, just now you would add the CORS configuration:
kind: AuthServer
# ...
spec:
cors:
allowOrigins:
- "https://vrabbi.cloud"
- "https://*.vrabbi.cloud"
As can be seen, both exact matches, and wildcards are supported in the allowed origins array.
You could as mentioned allow all origins if needed as follows:
kind: AuthServer
metadata:
annotations:
sso.apps.tanzu.vmware.com/allow-unsafe-cors: ""
spec:
cors:
allowAllOrigins: true
As seen, we need to specify both in the config that we want all sources to be allowed, as well as with the allow-unsafe-cors annotation, as TAP does not want to prevent you from creating such a client, but wishes to deter you from doing so unless needed, as this is not a secure configuration and she be avoided when possible.
Once you have defined a Public Client, and an Auth Server with CORS enabled, you must set the authentication mode to none when creating the client registration as can be seen bellow:
kind: ClientRegistration
spec:
clientAuthenticationMethod: none
This is needed as the Public Client flow is without authentication, and instead the PKCE flow will be utilized.
Role claim mapping from External IDP group membership
This new feature is another great enhancement, making App SSO much more user friendly.
This feature allows us to easily map and filter groups a user is a part of that are returned from the upstream IDP at login, into a set of roles, under the roles claim in the provided JWT token to your apps, which is provided by App SSO, and the relevant Auth Server.
This new feature supports 2 types of filters, for how to find the relevant groups in order to add the relevant roles. the 2 types are exactMatch and regex.
These 2 methods, enable just enough flexibility, while still keeping the API simple in my mind, and allow for us to map credentials from our upstream IDP, into our downstream apps, in a simple manner.
This feature is configured at the Auth Server level, per IDP. For example:
spec:
identityProviders:
- name: my-ldap
ldap:
roles:
filterBy:
- exactMatch: "admin-users"
- regex: "^users-*"
- name: my-oidc
openid:
roles:
filterBy:
- exactMatch: "admin-users"
- regex: "^users-*"
- name: my-saml
saml:
roles:
filterBy:
- exactMatch: "admin-users"
- regex: "^users-*"
As can be seen, this is supported for OIDC, LDAP and SAML IDPs, making the configuration really simple and easy to integrate, no matter your setup.
Default Auth Scopes
This is a long requested feature, that is truly awesome to see being added. With this feature, you can now define authorization scopes that are automatically granted to all users from a specific IDP, regardless of their user role.
For example, given an AuthServer with an OIDC IDP configured, with defined authorization scope defaults:
kind: AuthServer
spec:
identityProviders:
- name: my-oidc
openid:
accessToken:
scope:
defaults:
- "user.read"
- "user.write"
With the above config, a client registration can be created, requesting the scopes:
kind: ClientRegistration
spec:
scopes:
- name: "roles"
- name: "user.read"
Now that the client registration is added, when a Workload is registered by using the ClientRegistration, that workload, on behalf of the user, can request and be granted with the scope user.read automatically within the issued access token, without relation to the group memberships of that user.
This allows for some pretty powerful use cases, and i am excited to see where people take this.
Spring Cloud Gateway Integration
Another great feature, which is not new in TAP 1.5, but worth noting, is the simple integration one can do between Spring Cloud Gateway (SCG) and App SSO. The reason this is worth mentioning, is that in TAP 1.5, SCG is now included as an optional package, making the possibility of utilizing SCG much greater for a wider set of customers.
This is an area i expect to see grow over the next few releases, and it will be interesting to see how customers end up implementing these integrations and configurations in real world scenarios.
Summary
As you can tell, VMware have put a lot of effort into App SSO in this release, adding in key features which simplify the UX, and make the amount of customization needed in your own app to include SSO that much smaller, and easier to cope with, bringing us all a step closer to a more secure landscape, and better protected applications, which is always a huge benefit, especially when provided by a platform, with almost no overhead to manage!