Cloud Foundry includes a component called the User Account and Authentication (UAA) service which was introduced about a year ago. It provides user account management and authentication for developers that push applications to cloudfoundry.com, including single signon with support.cloudfoundry.com, micro.cloudfoundry.com, and more on the way. It also provides delegated authorization capabilities to partner sites so that they can interact with Cloud Foundry on a user’s behalf without access to user credentials.
An introduction and details of the UAA from a developer perspective can be found in earlier blog posts. In this post I will focus on the UAA’s integration of three emerging identity standards and what that implies for some specific Cloud Foundry deployment patterns.
The goal of the UAA is to make it easier, simpler, more secure and more convenient for users to get to the features of Cloud Foundry. The value is in the open PaaS and the applications it enables. So the identity services provided by the UAA should not only be useful for cloudfoundry.com and applications on it, but for pure open source deployments, managed private clouds, and even the micro cloud running on a thumb drive.
To achieve this goal, we have implemented and integrated new standards in a way that supports various deployment scenarios, such as multiple identity providers and external authentication mechanisms.
Fusing Identity Standards for a Stronger Platform
We have woven identity services into the platform using three standard protocols: OAuth2 for delegated authorization, OpenID Connect for session and authentication information, SCIM for user and group management. Of course we provide support for other standards as well, such as JSON Web tokens (JWT), SAML2, and OpenID 2.0. Even support for the legacy identity stalwart LDAP is in process. But what is particularly interesting is how we have combined the three primary protocols.
- OAuth2 — this is the foundational protocol and provides delegated authorization. It provides a way for web applications to ask users to allow access to cloudfoundry on the user’s behalf. It provides authentication and SSO as a side effect. The app gets one or more secure tokens — some that the app can use to identify the user, and some that it can present to the cloudfoundry API to act on behalf of the user. But OAuth2 does not specify the token format. We chose another standard, JWT, for that.
- OpenID Connect — provides identity information for the authenticated user. OAuth2 does not specify how the user’s information can be obtained by an app, just an opaque token. OpenID connect adds the ability for an app to efficiently and safely get authenticated user attributes like user name or email address.
- SCIM — User and group provisioning. User account management is out of scope for OAuth2, but SCIM specifies simple user provisioning as well as groups, and it’s extensible to new types. Since OAuth2 requires that web applications preregister with the authorization server (UAA), but does not specify how these registrations are done, we use a SCIM extension for that.
Imagine two web applications: – one manages users and groups for access to cloudfoundry.com – one displays results of monitors a user’s running applications as a service — like our partner Appsecute provides.
The three protocols complement each other well so far, but there is a piece still missing.
Connecting the Missing Link
For delegated authorization to work, the user needs a unit of delegation — some handle so they can say: I want to allow application X to read my application list on cloudfoundry.com, but not actually modify anything. This notion of specifying names for roles or permissions is called the token ‘scope’ in OAuth2. We needed some way to support management of these scopes, their existence, what users have access to them, what web applications can ask for them — and do it all in a way that naturally supports their use in authorization decisions.
Therefore, we mapped SCIM groups to OAuth2 scopes. In other words, you can create a group in the UAA and register a web app with that group name as a scope. When a user logs into the web app, it’s redirected to the UAA. If the user is in the group and they choose to authorize the web app with that scope, the web app gets a signed token that contains that scope.
We use this in our own cloudfoundry dashboard application. The system reliability engineers access the dashboard app, which is a UAA client app and always requests a token with dashboard.user scope. The UAA denies the scope unless the user is in the dashboard.user group.
What this gets us is that the dashboard app does not have any user account code, and it never gets the user’s credentials. It merely redirects to the UAA if there is no access token in the authorization header. If there is an access token it validates the token, and then checks if it has dashboard.user in the scope. For the system monitors, this means no need for shared accounts or passwords and better control of which users have access.
This is particularly useful when there are multiple such applications. Users get SSO among the applications, the applications are each more secure, access can be easily controlled by groups in the UAA.
Extensible Authentication Services
A somewhat recent addition is that we have separated the authentication service from the rest of the UAA. In OAuth2 terms this is separating the authorize and token endpoints. We can have different implementations of the authentication service for different needs. So far implementations are available for username and password (on cloudfoundry.com), for various flavors of openid2, and for SAML2 identity providers.
Why this is Cool
This is all quite useful, but how it can be used in a cloudfoundry deployment is best illustrated by some examples:
Suppose cloudfoundry is running in a managed instance for an enterprise. The enterprise has a suite of apps that can use the full advantage of the PaaS — easy deployment, scale up, scale down, with a myriad of frameworks and services. All the apps can use the UAA at the core for SSO and role (group) based authorization. Add a user to a group via SCIM, and the corresponding scope will be available at next login to all apps.
Cloudfoundry.com includes various web apps to help developers. Some of them only need to know who the user is for SSO. The openid scope is perfect for them. Suppose a new site wants to also provide personalized content based on the user’s running apps. We can create a registration for that app that restricts its scope to listing the user’s apps. If that app is compromised, nothing in the data of the user’s apps can be changed.
Suppose you are a developer running a private cloud in an enterprise. With Cloud Foundry you get these features:
- You can create and deploy applications exactly the same as apps on cloudfoundry.com with access to the multitude of frameworks and services, exactly the same as apps on cloudfoundry.com.
- Your apps can register with the UAA in your cloudfoundry instance, which means they don’t have to manage users or authentication. All apps in your instance can have SSO and common groups for authorization.
- Further, you can configure the UAA in your instance to include a SAML Login server, which gets user authentication from the corporate SAML IdP in front of an Active Directory instance. All apps now have SSO with the corporate IdP.
- Eventually you’d like a user’s AD group membership for be available to your app as an OAuth2 scope. Put the group membership in the SAML assertion and it can be mapped to a scope by the SAML Login Server — this part isn’t actually implemented yet, but is here to show future possibilities.
Cloud Foundry identity services are built on open standards and open source. They increase security and reduce friction so users can take advantage of the open PaaS.