Managing SSO for applications is a complex task, and since TAP 1.4, we have had a great feature called AppSSO, which is aimed at helping make the story of SSO integration much easier for developers and operators.
In TAP 1.6, a major effort was put into AppSSO to make it even more streamlined, and simple to use, while also exposing some more new advanced features, which can be very handy when needed.
In TAP 1.6 the main changes in AppSSO include:
- Cluster Workload Registration Class
- Cluster Unsafe Test Login
- Custom Claim Mappings
- Configurable token expiry settings
Lets go over what each of these improvement entails and what use cases they can help with.
Cluster Workload Registration Class
This integration is extremely exciting to see. With this new API, we can easily integrate AppSSO with Crossplane and the Services Toolkit components to allow for dynamic service provisioning of OIDC clients from an auth server!
It exposes an
AuthServer as a ready-to-claim AppSSO service offering, making it really easy for developer to create new clients for an auth server on demand!
When you create a ClusterWorkloadRegistrationClass (cwrc) resource, this will create behind the scenes a Crossplane
Composition and a Services Toolkit
The composition itself templates out a new CRD which is also part of this new offering caller a WorkloadRegistration.
While in the past we had the ClientRegistration API, the new API, is more portable, and easily can be promoted between environments without changes to the spec, supporting a GitOps approach which is always the preferred approach in the Kubernetes world.
As we have the ability via the service toolkit to limit permissions to users, for specific classes, and each cwrc creates a new class which is tied to a specific auth server, we can easily manage RBAC and permission boundaries for different IDPs we use, in multi tenant scenarios, while still providing a simple and clean UX for a self service offering to our developers which is awesome!
While more complex and advanced feature can be added, lets take a look at a simple example of what this could look like:
apiVersion: sso.apps.tanzu.vmware.com/v1alpha1 kind: ClusterWorkloadRegistrationClass metadata: name: dev-sample spec: base: spec: authServerSelector: matchLabels: env: dev
Creating a new client
apiVersion: services.apps.tanzu.vmware.com/v1alpha1 kind: ClassClaim metadata: name: dev-sample-01 spec: classRef: name: dev-sample parameters: workloadRef: name: my-workload redirectPaths: - /redirect/uri
As you can see, the new API is extremely simple to use and understand, and can open up some amazing opportunities for offering a truly self service SSO offering to your end users.
While this is great for production, and more advanced setups, in dev environments or POCs, we often simply want something that just works. The above APIs are simple, but still require configuring the auth server and understanding more low level details than we want to deal with in dev environments. This is where the next new feature comes in.
Cluster Unsafe Test Login
This new API is the recommended way to get started with AppSSO in non production environments.
The new CRD ClusterUnsafeTestLogin (cutl) is so simple, it does not even have a spec!
the only element which is configurable is the name.
apiVersion: sso.apps.tanzu.vmware.com/v1alpha1 kind: ClusterUnsafeTestLogin metadata: name: demo
When you apply the above resource to a cluster, a few things will be created for you. First an Auth Server with an internal unsafe IDP will be deployed. next a token signing key will be generated, and finally a ClusterWorkloadRegistrationClass (cwrc) will be created, which will in turn create a ClusterInstanceClass and a Composition as mentioned above.
The auth server is configured in this setup with an http only issuer URI and allows all CORS origins. While this is definitely not a production setup, it makes integrating into your apps much easier, and removes all of the auxiliary issues from the time of development, making it much easier to get started, and to make sure the SSO elements are working for you as expected, and then you can switch to a more production ready setup, with a real backing IDP, more secure CORS configurations and of course TLS only communication.
The auth server which gets deployed as part of a CUTL, includes a single user with the username “user” and the password “password”.
Once you apply a CUTL resource, you can then create a class claim just like with a CWRC as seen above.
apiVersion: services.apps.tanzu.vmware.com/v1alpha1 kind: ClassClaim metadata: name: dev-sample-01 spec: classRef: name: demo parameters: workloadRef: name: my-workload redirectPaths: - /redirect/uri
This new API truly makes getting started on integrating SSO into you apps a breeze, and makes the barrier of entry to AppSSO so much lower!
While these past 2 features focused on simplifying the API and consumption of AppSSO, the next 2 improvements are for more advanced use cases, but are truly amazing to see, and actually can be game changers in certain environments.
Lets take a look at the one I am most excited about which is custom claim mappings support!
Custom Claim Mappings
With this new capability, service operators can control which claims appear in an Auth Server issued ID Token, and how to obtain this value from an upstream identity provider.
Recently when working on a project where i needed to test 4 different OIDC providers, i learned that the 4 claims which this specific app needed, only one of them was the same accross the different OIDC providers. While all data was there, every provider named their claims differently (group / groups / group_names / Groups), (full_name, name, fn, Full_Name) and so on.
While this may seem like a simple issue to solve, it actually is not easy, as within an application i need to look at a specific field in an ID Token to extract the data i need to know who this user is, and what permissions they should have.
This issue gets even more complex when working with an upstream IDP which is not OIDC based, such as LDAP or SAML.
With this new feature, we can now at the Auth Server level, perform mappings between upstream fields, and the claims on the Auth Server generated tokens!
for example, if i want to standardize on the name “groups” for my groups claim, yet i am using workspace one which provides this data as “group_names”, i can simply set the following in my Auth Server:
spec: identityProviders: - name: wso-idp openid: idToken: claims: - fromUpstream: "group_names" toClaim: "groups"
This simple yet extremely powerful feature is a huge boost to the AppSSO tooling which opens up awesome opportunities for integrations.
While the above works for external IDPs such as OIDC, LDAP and SAML, the configuration for internal unsafe IDPs in an auth server is a bit different, but also easy to configure.
spec: identityProviders: - name: test-users internalUnsafe: users: - username: joe password: "password" roles: - "dev" claims: given_name: "joe" family_name: "rosenberg" middle_initial: "A" email: "firstname.lastname@example.org" alt_address: "123 Awesome Street" - username: wendy password: "password" roles: - "operator" claims: alt_address: "456 Cool Street" middle_initial: "T"
As you can see here, we simply configure per user, the custom roles and claims they should have in their ID tokens. With this ability, we can easily simulate real world test cases, even when using an internal unsafe IDP!
There is one more new feature in AppSSO in TAP 1.6, which while it may sound less interesting and exciting, it makes the offering more secure and more tunable to whatever your security teams requirements are.
Token Expiry Settings
In TAP 1.6, we now have the ability to configure the token expiry settings at a per auth server level for access, id, and refresh tokens.
The default expirations set by AppSSO are 12 hours for access and id tokens, and 30 days for refresh tokens.
In order to configure these settings, you just need to add the following to your auth server manifest:
spec: token: accessToken: expiry: "5m" idToken: expiry: "5m" refreshToken: expiry: "8h"
The time durations can be provided in seconds (s), minutes (m), or in hours (h). this means that for example the default 30 days for refresh tokens is actually set as “720h”.
As can be seen, a lot of effort was put into AppSSO in this release, making the integration tasks easier and more streamlined, and also improving on the capability set, and adding new and improved functionality to help all personas involved.
I’m really excited about these new features and can’t wait to see them being used in the wild!