There are six main components of the Cloud Foundry User Accounts and Authentication (UAA) architecture:
UAA is built to support a multi-tenant architecture. Each tenant is referred to as an identity zone.
Identity zones are configured with JSON payloads using a REST API. For examples, see Creating an identity zone in the UAA API documentation.
An identity zone is a logical boundary around the entities UAA manages. The entities in a zone include, but are not limited to:
Having two identity zones is equivalent to standing up two separate UAA deployments, but using fewer resources. This type of resource management can reduce operational and maintenance overhead.
An identity zone is uniquely identified by a subdomain identifier in UAA. If a UAA deployment is hosted on the URL https://login.EXAMPLE-CF-DOMAIN.com
, identity zones are hosted as subdomains of that same deployment.
For example:
zone1
: https://ZONE1.login.EXAMPLE-CF-DOMAIN.com
zone2
: https://ZONE2.login.EXAMPLE-CF-DOMAIN.com
A UAA deployment always has one zone referred to as the default zone. You configure and bootstrap a default zone using a YAML configuration file.
A user is the central domain object of the UAA server. Because UAA acts as both an account store and an authorization server, many different types of information are linked to users and can be accessed through user-centric API calls.
In its capacity as a user account store, UAA can provide unique attributes that describe an individual user, such as email, name, phone number, and group memberships. In addition to these attributes, UAA also tracks some dynamic user metadata, such as the last successful logon time and last updated time.
You can make additional attributes available if UAA is configured to use custom attribute mappings from an external IDP, such as an existing LDAP or SAML provider. For more information about IDP options, see Identity Providers in UAA.
External IDPs are read-only, as are attributes from those providers. Any change to the external user account should be performed on the external IDP directly. These read-only attributes are refreshed each time the user authenticates with the external IDP.
UAA can be used as an authorization server, which allows client apps to interact with resources on a user’s behalf using the four standard OAuth2 authorization grant flows for obtaining access tokens:
A UAA user is the resource owner of the OAuth2 protocol. Access tokens issued to the user contain scopes at the intersection of the requesting client’s allowed scopes and a user’s group memberships.
A user.id
is a string used to identify a user in APIs. This universally unique identifier is randomly generated at the time of user creation and does not change. It is guaranteed to be unique across all identity zones in the UAA deployment. The user.id
is a 128-bit number formatted as a UUID. This is also expressed as a “sub” claim in the tokens generated by UAA.
A user in UAA always belongs to a user store with an alias called an origin
. For example, users that are authenticated by the UAA itself with a username and password have their origin set to the value uaa
.
The fixed origin values are:
uaa
for users that are authenticated by the UAA deploymentldap
for users that are authenticated by the LDAP providerUsers that are authenticated with an external IDP are often referred to as shadow users in UAA. For more information, see Shadow Users.
A user.userName
is a user-readable string that refers to the user, typically an email address. The user enters their username when authenticating against UAA.
If the user authenticates against an external IDP, the username is transferred from that IDP to the shadow user in UAA. An individual user can be uniquely identified by the combination of the username and the origin values.
The username alone is not a unique value. Because usernames can change, UAA provides user IDs as unchanging references to a single user. For more information, see user.id.
Users that create accounts through the UAA UI use their email address as their username. The administrative API can create user accounts that specify arbitrary usernames.
For external IDPs, the username is mapped from the assertion received by UAA.
SAML: UAA retrieve the username from the nameID
claim. For example:
<saml2:NameID> Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">
SAML-USERNAME
</saml2:NameID>
Where SAML-USERNAME
is the username UAA retrieves.
LDAP: UAA derives the username from user input.
OIDC1.0/OAuth2: UAA derives usernames from OpenID Connect and OAuth2 providers from the id_token
, userinfo endpoint, or the access token. The usernames are returned in JSON Web Token (JWT) format. The name of the claim holding the username value can be configured and defaults to preferred_username
.
A user can belong to one or more groups. A group is a way to express a common group-based or role-based access control model. A group has a display name. This name is an arbitrary string that corresponds directly to a scope in a JWT access token and is used for access control by OAuth2 resource servers.
The common group attributes are:
type
: This can be one of two membership types, DIRECT
and INDIRECT
. DIRECT
means that the user is directly associated with the group. INDIRECT
means that the membership has been inherited from the nested membership of groups.
display
: The displayName
of the group the user or the group belongs to. The displayName
is an identifier that is unique to a given identity zone and is a representation of the access given to the user.
Note: To create a group, see Groups in the UAA API documentation. To add a user or group to a group, see Add Member in the UAA API documentation.
You can configure UAA to have one or more default groups. These are groups that every user in the system is a member of, even if there is no direct relationship between user and group in the database.
Users that have authenticated through an external IDP still get assigned a record in the users table in the UAA database. These users are frequently called shadow users.
UAA internal users have a user.origin
of uaa
. Shadow users are differentiated from internal users with a different origin corresponding to the external IDP. Each time an external user is authenticated and the assertion is passed to UAA, UAA refreshes the user information. This means that the information about a shadow user in UAA is accurate up to the last time UAA received an assertion with user information.
Shadow users have a different type of group membership. A shadow user can be associated with a group through its origin. This membership may also change each time a new assertion is received.
A shadow user can also have a group membership defined using group_membership.origin='uaa'
. These are memberships that remain persistent and do not change when assertions report a change in external group memberships. It also allows UAA operators to assign privileges to users that are not known by external providers or cannot be mapped to external groups.
UAA is an OAuth2 authorization server. Before apps can obtain access tokens, developers must perform a one-time registration process to create a client in the UAA.
A client usually represents an app with its own set of permissions and configurations. Clients are protected by simple credentials, such as client ID and secret, that apps use to authenticate themselves to the UAA in order to obtain tokens.
There are two types of clients:
Clients are created in UAA through client registration. You can define clients in UAA using the UAA configuration files or create them using the UAA API.
To create a client, the developer must specify which grant types should be permitted using their client. The grant type determines how your client can interact with UAA. Each grant types corresponds to one of the four different authorization flows defined in the OAuth2 2.0 Authorization Framework. For more information, see the Authorization Code section of the OAuth2 2.0 Authorization Framework.
The available grant types on UAA include:
authorization_code
password
implicit
client_credentials
For increased security, use only the grant types your app requires. However, you can assign multiple grant types to one client if necessary.
To help you choose a grant type for your use case, see the table below:
Grant type | User | Details |
---|---|---|
authorization_code |
Developers building web apps | In the authorization code grant flow, the user is directed to a UAA page where they grant approvals to the client. After the user approves the requested scopes, they are redirected back to the client app with an authorization code in the URL parameters. The client app may then exchange the authorization code with UAA to obtain an access token. |
password |
Developers building native desktop or mobile apps | The name password refers to the resource owner password grant type. The user provides their username and password to the client app, which may then use them to obtain an access_token . |
implicit |
Developers building a single page web app with no server back end | The user is taken to a page on UAA where they are asked to grant approvals to the client. After doing so, they are redirected to the redirect_uri with the access token in the URI fragment. |
client_credentials |
Developers when the client app needs to perform actions in UAA on its own behalf | Actions where a client_credentials grant type might be appropriate include creating or destroying user groups, managing user group membership, or creating or destroying other clients. The client_credentials grant can be likened to service accounts in legacy app ecosystems. |
refresh_token |
Developers must use the refresh_token grant type with either the authorization_code or password grant type. refresh_token cannot be used by itself. |
Clients typically use the refresh_token to obtain a new access token without the need for the user to authenticate again. They do this by calling /oauth/token with grant_type=refresh_token . A refresh token is only issued to clients that have refresh_token in their list of authorized_grant_types . |
A client is identified with a value up to 255 characters, called the client_id
. Unlike the user.id
, the client_id
is often a human-readable identifier. For example, an app’s name could be its client_id
. This identifier is unique within the identity zone.
Client authentication occurs through a password mechanism called a client_secret
.
UAA allows client credentials to be asserted in two different ways:
With an HTTP authorization header using Basic authentication.
By passing the client_id
and client_secret
as request parameters as part of an HTTP POST body using content type application/x-www-form-urlencoded
.
For more information, see the Client Password section of the OAuth 2.0 Authorization Framework.
The authorization_code
and implicit grant types rely on a user agent. A user agent like a web browser is responsible for performing HTTP redirects to UAA and receiving a response from UAA. That response can be in the form of an access token or a code that is exchanged for an access token later.
A client that supports either of these two flows must have at least one URL in the client configuration. Alternatively, you can use multiple URLs and wildcards (*) for ant path matching. For more information, see the Class AntPathMatcher section of the Spring Framework documentation.
URLs are registered using a comma-separated string.
UAA validates access tokens up to the time those tokens expire. Clients do the same, if they can validate tokens offline. The access token validity is the value in seconds from the time the token was created to when it expires.
UAA validates refresh tokens up to the time those tokens expire. Clients do the same, if they can validate tokens offline. The refresh token validity is the value in seconds from the time the token was created to when it expires.
Client scopes are used to populate the scope claim when constructing an access token where the client acts on behalf of the user.
When an access token is created, UAA takes the user groups and intersects them with the client scopes. The intersection of these two fields are scopes that are eligible to be populated in the access token. There are two more validations that can further limit the scopes that get populated in the access token after the intersection has been decided:
The token can never contain more scopes than the intersection between client scopes and user groups.
Scopes in an access token must be approved by the granting entity.
During a client_credentials
grant, the client itself is the granting entity and automatically assumes the client authorities are approved.
During a password grant, the user shares their password with the client app. The client app assumes this sharing to be implicit approval of the scopes that the client wants to be populated in the access token.
Two grant types, authorization_code
and implicit
, require specific user approval for the scopes to populate in the access token. UAA provides a UI that lets the user approve or deny scopes from being populated in the access token.
During client registration, the operator can configure the client to bypass this approval process by setting the auto-approve values to a single string with its value set to true
. This results in any requested scope being approved automatically.
The value can also be a comma-separated list of selected scopes that do not require user approval.
Clients can store custom attributes in a field called additional_information
. This is a simple key value store. The table below describes these custom attributes:
Key | Value |
---|---|
allowed providers |
You can limit which users can use which apps. For example, in a Ops Manager deployment, you may have set up multiple IDPs. Or, you could be using Facebook and your organization's LDAP system. You can limit UAA to only issue an app tokens if the users are from a certain provider. To do this, configure the app's client with allowed providers="ldap" . The value is a comma-separated string of Identity Provider.origin values. |
created with |
UAA stores the scope zones.write in this field if the client was created using the /identity-zones endpoint. UAA uses this field to allow clients to be deleted by the same endpoint. This is not a configurable field. |
name |
Various tooling in the Ops Manager ecosystem creates clients with generated Client.client_id values. These tools often store a human-readable name in this field. For more information, see client.client_id. |
approvals_deleted |
Contains a boolean value if performing an operation on the client resulted in all the client's user approvals were deleted. For example, changing the client.client_secret value causes UAA to delete all the approvals. UAA then stores a value of true in this field. |
token_salt |
Tokens, even stateless JWT, can be revoked. Revoked tokens do not pass a UAA token validation when the token is passed to the /introspect endpoint. UAA revokes a token if the client's secret has changed. There may be occasions to revoke all tokens for a certain client without having to change the client secret. You can do this by changing the token_salt . token_salt is an arbitrary string value that is used to generate a hash. |