Component: User Account and Authentication (UAA) Server

Page last updated:

This topic provides an overview of the User Account and Authentication (UAA) Server, the identity management service for Cloud Foundry

The primary role of the UAA is as an OAuth2 provider, issuing tokens for client apps to use when they act on behalf of Cloud Foundry users. In collaboration with the login server, the UAA can authenticate users with their Cloud Foundry credentials, and can act as an SSO service using those, or other, credentials.

The UAA has endpoints for managing user accounts and for registering OAuth2 clients, as well as various other management functions.

Quick Start

You can deploy the UAA locally or to Cloud Foundry.

Deploy UAA Locally

Follow the instructions below to deploy and run the UAA locally.

  1. In a terminal window, clone the UAA GitHub repository.

    $ git clone git://github.com/cloudfoundry/uaa.git
    
  2. Navigate to the directory where you cloned the UAA GitHub repository, then run the ./gradlew run command to build and run all the components that comprise the UAA and the example programs, uaa, samples/api, and samples/app.

    $ cd uaa
    $ ./gradlew run
    
  3. If successful, the three apps run together on a single instance of Tomcat listening on port 8080, with endpoints /uaa, /app, and /api.

Use Local UAA

Follow the steps below to access and use a locally-deployed UAA server.

  1. Run the UAA server as described in the Deploy Locally section, above.

  2. Open another terminal window. From the project base directory, run curl -H "Accept: application/json" localhost:8080/uaa/login to query the login endpoint about the system. For example:

    $ curl -H "Accept: application/json" localhost:8080/uaa/login
    {
      "timestamp":"2012-03-28T18:25:49+0100",
      "app" : {"version":"1.8.3"},
      "commit_id":"cba0958",
      "prompts":{"username":["text","Email"],
        "password":["password","Password"]
      }
    }
    
  3. Run gem install cf-uaac to install the Cloud Foundry UAA Command Line Client (UAAC) Ruby gem.

    $ gem install cf-uaac
    
  4. Run uaac target http://localhost:8080/uaa to target the local UAA Server endpoint.

    $ uaac target http://localhost:8080/uaa
    
  5. Run uaac token get USERNAME PASSWORD to log in. Replace USERNAME with your user name, and PASSWORD with your password. For example:

    $ uaac token get marissa koala
    

    If you do not specify a username and password, the UAAC prompts you to supply them.

    The uaac token client get command authenticates and obtains an access token from the server using the OAuth2 implicit grant, similar to the approach intended for a standalone client like the Cloud Foundry Command Line Interface (cf CLI).

    UAAC stores the access token in the ~/.uaac.yml file. Open the ~/.uaac.yml in a text editor and copy this access token to use in the next step.

  6. Run uaac token decode ACCESS-TOKEN-VALUE to retrieve the token details. Replace ACCESS-TOKEN-VALUE with your access token, copied from your ~/.uaac.yml file. The UAAC should display your username and the client id of the original token grant. For example:

    $ uaac token decode abcdef0123456789ABCDEF0123456789ghijklmnopqr01234567890
    jti: e3a7d065-8514-43c2-b1f8-f8ab761791e2
    sub: f796d1a2-eca3-4079-a317-f3224f8f7832
    scope: scim.userids password.write openid cloud_controller.write cloud_controller.read
    client_id: cf
    cid: cf
    user_id: f796d1a2-eca3-4079-a317-f3224f8f7832
    user_name: marissa
    email: marissa@example.org
    iat: 1413495264
    exp: 1413538464
    iss: http://localhost:8080/uaa/oauth/token
    aud: scim openid cloud_controller password
    

Deploy UAA to Cloud Foundry

Follow the instructions below to build the UAA as an app and push it to Cloud Foundry using the Cloud Foundry Command Line Interface (cf CLI).

  1. In a terminal window, clone the UAA GitHub repository.

    $ git clone git://github.com/cloudfoundry/uaa.git
    
  2. Navigate to the directory where you cloned the UAA GitHub repository, then run the ./gradlew :cloudfoundry-identity-uaa:war command build the UAA as a WAR file.

    $ cd uaa
    $ ./gradlew :cloudfoundry-identity-uaa:war
    
  3. Run the cf CLI cf push APP-NAME -m 512M -p PATH-TO-WAR-FILE --no-start command to push the app to Cloud Foundry. Replace APP-NAME with a name for your UAA app, and PATH-TO-WAR-FILE with the path to the WAR file you created in the previous step. For example:

    $ cf push MYUAA -m 512M -p uaa/build/libs/cloudfoundry-identity-uaa-1.8.0.war --no-start
    
  4. Run cf set-env APP-NAME SPRING_PROFILES_ACTIVE default to set the SPRING_PROFILES_ACTIVE environment variable with the value default. Replace APP-NAME with the name of your app that you used in the previous step. For example:

    $ cf set-env MYUAA SPRING_PROFILES_ACTIVE default
    
  5. Run cf start APP-NAME to start your app. Replace APP-NAME with the name of your app. For example:

    $ cf start MYUAA
    

Use Remote UAA

You use a UAA server that you pushed as an app to Cloud Foundry in a similar way to one you run locally. You do not need app token encoding because you do not have the client secret.

Follow the steps below to access and use a UAA server that you pushed as an app to Cloud Foundry.

  1. Deploy UAA to Cloud Foundry as described above.

  2. From the project base directory, run curl -H "Accept: application/json" APP-FQDN/login to query the external login endpoint about the system. Replace APP-FQDN with the FQDN of your app. For example:

    $ curl -H "Accept: application/json" uaa.example.org/login
    {
      "timestamp":"2014-09-15T18:25:04+0000",
      "app":{"version":"1.8.3"},
      "commit_id":"git-metadata-not-found",
      "prompts":{"username":["text","Email"],
          "password":["password","Password"]
      }
    }
    
  3. Run gem install cf-uaac to install the Cloud Foundry UAA Command Line Client (UAAC) Ruby gem.

    $ gem install cf-uaac
    
  4. Run uaac target APP-FQDN to target the remote UAA Server endpoint. Replace APP-FQDN with the FQDN of your app.

    $ uaac target uaa.example.org
    

  5. Run uaac token get USERNAME PASSWORD to log in. Replace USERNAME with your user name, and PASSWORD with your password. For example:

    $ uaac token get marissa koala
    

    If you do not specify a username and password, the UAAC prompts you to supply them.

    The uaac token client get command authenticates and obtains an access token from the server using the OAuth2 implicit grant, similar to the approach intended for a standalone client like the Cloud Foundry Command Line Interface (cf CLI).

Integration Tests

Run the integration tests with the following command:

$ ./gradlew integrationTest

This command starts a UAA server running in a local Apache Tomcat instance. By default, the service URL is set to http://localhost:8080/uaa.

You can set the environment variable CLOUD_FOUNDRY_CONFIG_PATH to a directory containing a uaa.yml file where you change the URLs used in the tests, and where you can set the UAA server context root.

Custom YAML Configuration

Follow the steps below to modify the runtime parameters.

  1. Create a uaa.yml file in the following format:

    uaa:
      host: UAA-HOSTNAME
      test:
        username: USERNAME
        password: PASSWORD
        email: EMAIL-ADDRESS
    

    Replace the values in the above format as follows:

    • UAA-HOSTNAME: The FQDN of UAA app. Example: uaa.example.org
    • USERNAME: A valid username. Example: dev@example.org
    • PASSWORD: Password for the above username.
    • EMAIL-ADDRESS: Email address for the above user. Example: dev@example.org
  2. From the uaa/uaa directory, run CLOUD_FOUNDRY_CONFIG_PATH=/tmp ./gradlew test.

  3. The web app looks for a YAML file in the following locations when it starts, with later entries overriding earlier ones:

    classpath:uaa.yml
    file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
    file:${UAA_CONFIG_FILE}
    ${UAA_CONFIG_URL}
    

Test with PostgreSQL or MySQL

The default UAA unit tests, ./gradlew test, use HyperSQL (hsqldb).

To use a different database management system, create a uaa.yml file containing spring_profiles: default,OTHER-DBMS in the src/main/resources/ directory. Replace OTHER-DBMS with the name of the other database management system to use.

For example, run the following command to run the unit tests using PostgreSQL instead of hsqldb:

$ echo "spring_profiles: default,postgresql" > src/main/resources/uaa.yml
$ ./gradlew test integrationTest

Run the following command to run the unit tests using MySQL instead of hsqldb:

$ echo "spring_profiles: default,mysql" > src/main/resources/uaa.yml
$ ./gradlew test integrationTest

You can find the database configuration for the common and scim modules at common/src/test/resources/(mysql|postgresql).properties and scim/src/test/resources/(mysql|postgresql).properties.

UAA Projects

The following UAA projects exist:

  • common: A module containing a JAR with all the business logic. common is used in the web apps listed below.

  • uaa: The UAA server. uaa provides an authentication service and authorized delegation for back-end services and apps by issuing OAuth2 access tokens.

  • api: A sample OAuth2 resource service that returns a mock list of deployed apps. api provides resources that other apps might want to access on behalf of the resource owner.

  • app: A sample user app that uses both api and uaa. app is a web app that requires single sign-on and access to the api service on behalf of users.

  • scim: The SCIM user management module used by UAA.

UAA Server

The authentication service, uaa, is a Spring MVC web app. You can deploy it in Tomcat or your container of choice, or execute ./gradlew run to run it directly from the uaa directory in the source tree. When run with Gradle, uaa listens on port 8080 and has URL http://localhost:8080/uaa.

The UAA Server supports the APIs defined in the UAA-APIs document which include the following:

  • The OAuth2 /authorize and /token endpoints

  • A /login_info endpoint to allow querying for required login prompts

  • A /check_token endpoint to allow resource servers to obtain information about an access token submitted by an OAuth2 client

  • SCIM user provisioning endpoint

  • OpenID connect endpoints to support authentication /userinfo and /check_id

Command line clients can perform authentication by submitting credentials directly to the /authorize endpoint.

An ImplicitAccessTokenProvider exists in Spring Security OAuth to use if your client is Java.

By default, uaa will launch with a context root /uaa.

Configuration

A uaa.yml file exists in the app. This file provides defaults to the placeholders in the Spring XML.

You can override any occurrences of ${placeholder.name} in the XML by adding it to the uaa.yml file, or by providing a System property, -D to JVM, with the same name.

All passwords and client secrets in the config files are in plain text, but are inserted into the UAA database encrypted with BCrypt.

User Account Data

The default uses an in-memory RDBMS user store, pre-populated with a single test user marissa with password koala.

To use PostgreSQL for user data, activate the Spring profile postgresql.

You can configure the active profiles in uaa.yml using the following:

spring_profiles: postgresql,default

To use PostgreSQL instead of HyperSQL (hsqldb):

$ echo "spring_profiles: postgresql,default" > src/main/resources/uaa.yml
$ ./gradlew run

To bootstrap a microcloud-type environment, you need an admin client. A database initializer component that inserts an admin client exists. If the default profile is active, for example not postgresql, a cf CLI client exists so that the Gem login works with no additional configuration required. You can override the default settings and add additional clients in the uaa.yml file:

oauth:
  clients:
    admin:
      authorized-grant-types: client_credentials
      scope: read,write,password
      authorities: ROLE_CLIENT,ROLE_ADIN
      id: admin
      secret: adminclientsecret
      resource-ids: clients

You can use the admin client to create additional clients. You must have a client with read/write access to the scim resource to create user accounts. The integration tests handle this automatically by inserting client and user accounts as necessary for the tests.

Sample Apps

Two sample apps are included with the UAA: /api and /app.

Run them with ./gradlew run from the uaa root directory. All three apps, /uaa, /api, and /app, are simultaneously deployed.

API Sample App

The api sample app is an example resource server. It hosts a service that returns a list of mock apps under /apps.

APP Sample App

The app sample app is a user interface app, primarily aimed at browsers, that uses OpenID Connect for authentication and OAuth2 for access grants. app authenticates with the Auth service, then accesses resources in the API service. Run it with ./gradlew run from the uaa root directory.

The app can operate in multiple different profiles according to the location and presence of the UAA server and the login app. By default, the app looks for a UAA on localhost:8080/uaa, but you can change this by setting the UAA_PROFILE environment variable or System Property.

The app source code, samples/app/src/main/resources, contains multiple properties files pre-configured with different likely locations for those servers. The names of these properties files follow the form app-UAA_PROFILE.properties.

The naming convention for the UAA_PROFILE is as follows:

  • local: a localhost deployment

  • vcap: a vcap.me deployment

  • staging: a staging deployment

Profile names can be hyphenated to indicate multiple contexts. For example, local-vcap can be used when the login server is in a different location than the UAA server.

Use Cases
  1. See all apps:

    GET /app/apps
    

    Browser is redirected through a series of authentication and access grant steps, and then the photos are shown.

  2. See the currently logged in user details, a selection of attributes from the OpenID provider:

    GET /app
    

LOGIN App

The login app is a user interface for authentication. The UAA can also authenticate user accounts, but only if it manages them itself, and it only provides a basic UI. You can brand and customize the login app for non-native authentication and for more complicated UI flows, like user registration and password reset.

The login app is itself an OAuth2 endpoint provider, but delegates those features to the UAA server. Therefore, configuration for the login app consists of locating the UAA through its OAuth2 endpoint URLs and registering the login app itself as a client of the UAA. A login.yml for the UAA locations exists, such as for a local vcap instance:

uaa:
  url: http://uaa.vcap.example.net
  token:
    url: http://uaa.vcap.example.net/oauth/token
  login:
    url: http://uaa.vcap.example.net/login.do

An environment variable or Java System property also exists, LOGIN_SECRET, for the client secret that the app uses when it authenticates itself with the UAA. The login app is registered by default in the UAA only if there are no active Spring profiles. In the UAA, the registration is located in the oauth-clients.xml config file:

id: login
secret: loginsecret
authorized-grant-types: client_credentials
authorities: ROLE_LOGIN
resource-ids: oauth

Use Cases

  1. Authenticate:

    GET /login
    

    The sample app presents a form login interface for the backend UAA, and an OpenID widget where a user can authenticate using Google or other credentials.

  2. Approve OAuth2 token grant:

    GET /oauth/authorize?client_id=app&response_type=code...
    

    Standard OAuth2 Authorization Endpoint. The UAA handles client credentials and all other features in the back end, and the login app is used to render the UI.

  3. Obtain access token:

    POST /oauth/token
    

    Standard OAuth2 Authorization Endpoint passed through to the UAA.

Scopes

UAA covers multiple scopes of privilege, including access to UAA, access to Cloud Controller, and access to the router.

See the tables below for a description of the scopes covered by UAA:

UAA Scopes

Scope Description
uaa.user This scope indicates that this is a user. It is required in the token if submitting a GET request to the OAuth 2 /authorize endpoint.
uaa.none This scope indicates that this client will not be performing actions on behalf of a user.
uaa.admin This scopes indicates that this is the superuser.
scim.write This scope gives admin write access to all SCIM endpoints, /Users, and /Groups.
scim.read This scope gives admin read access to all SCIM endpoints, /Users, and /Groups.
scim.create This scope gives the ability to create a user with a POST request to the /Users endpoint, but not to modify, read, or delete users.
scim.userids This scope is required to convert a username and origin into a user ID and vice versa.
scim.invite This scope is required to participate in invitations using the /invite_users endpoint.
groups.update This scope gives the ability to update a group. This ability can also be provided by the broader scim.write scope.
password.write This admin scope gives the ability to change a user’s password.
openid This scope is required to access the /userinfo endpoint. It is intended for OpenID clients.
idps.read This scope gives read access to retrieve identity providers from the /identity-providers endpoint.
idps.write This scope gives the ability to create and update identity providers from the /identity-providers endpoint.
clients.admin This scope gives the ability to create, modify, and delete clients.
clients.write This scope is required to create and modify clients. The scopes are prefixed with the scope holder’s client ID. For example, id:testclient authorities:client.write gives the ability to create a client that has scopes with the testclient. prefix. Authorities are limited to uaa.resource.
clients.read This scope gives the ability to read information about clients.
clients.secret This admin scope is required to change the password of a client.
zones.read This scope is required to invoke the /identity-zones endpoint to read identity zones.
zones.write This scope is required to invoke the /identity-zones endpoint to create and update identity zones.
scim.zones This is a limited scope that only allows adding a user to, or removing a user from, zone management groups under the path /Groups/zones.
oauth.approval /approvals endpoint. This scope is required to approve or reject clients to act on a user’s behalf. This is a default scope defined in the uaa.yml file.
oauth.login This scope is used to indicate a login app, such as external login servers, can perform trusted operations, such as creating users not authenticated in the UAA.
approvals.me This scope is not currently used.
uaa.resource This scope indicates that this is a resource server, used for the /check_token endpoint.
zones.ZONE-ID.admin This scope permits operations in a designated zone, such as creating identity providers or clients in another zone, by authenticating against the default zone. This scope is used with the X-Identity-Zone-Id header.
zones.ZONE-ID.read This scope permits reading the given identity zone. This scope is used with the X-Identity-Zone-Id header.
zones.ZONE-ID.clients.admin This scope translates into clients.admin after zone switch completes. This scope is used with the X-Identity-Zone-Id header.
zones.ZONE-ID.clients.read This scope translates into clients.read after zone switch completes. This scope is used with the X-Identity-Zone-Id header.
zones.ZONE-ID.clients.write This scope translates into clients.write after zone switch completes. This scope is used with the X-Identity-Zone-Id header.
zones.ZONE-ID.clients.scim.read This scope translates into scim.read after zone switch completes. This scope is used with the X-Identity-Zone-Id header.
zones.ZONE-ID.clients.scim.create This scope translates into scim.create after zone switch completes. This scope is used with the X-Identity-Zone-Id header.
zones.ZONE-ID.clients.scim.write This scope translates into scim.write after zone switch completes. This scope is used with the X-Identity-Zone-Id header.
zones.ZONE-ID.idps.read This scope translates into idps.read after zone switch completes. This scope is used with the X-Identity-Zone-Id header.

Cloud Controller Scopes

Scope Description
cloud_controller.read This scope gives the ability to read from any Cloud Controller route the token has access to.
cloud_controller.write This scope gives the ability to post to Cloud Controller routes the token has access to.
cloud_controller.admin This admin scope gives full permissions to Cloud Controller.
cloud_controller.admin_read_only This admin scope gives read permissions to Cloud Controller.
cloud_controller.permissions

Routing Scopes

Scope Description
routing.routes.read This scope gives the ability to read the full routing table from the router.
routing.routes.write This scope gives the ability to write the full routing table from the router.
routing.router_groups.read This scope gives the ability to read the full list of routing groups.
routing.router_groups.write This scopes gives the ability to write the full list of routing groups.

Other Scopes

Scope Description
doppler.firehose This scope gives the ability to read logs from the Loggregator Firehose endpoint.
notifications.write This scope gives the ability to send notifications through the Notification Service.
Was this helpful?
What can we do to improve?
View the source for this page in GitHub