Authentication with OAuth 2 - Only for OCI (Gen 2) Environments

In EPM Cloud environments on Oracle Cloud Infrastructure (OCI) / Gen 2 architecture, you can use an OAuth 2 access token to issue REST APIs on EPM Cloud to satisfy the requirement of avoiding the use of passwords in your environment.

Setting Up Authentication with OAuth 2

In order to access EPM Cloud REST APIs with OAuth 2, an EPM Cloud Service Administrator has to request the Domain Administrator to set up an OAuth 2 client and provide the Identity Domain Cloud Service (IDCS) URL and Client ID.

Overview of the steps:

  • Step 1. Register an OAuth client. This is a one-time setup step that requires user interaction with IDCS Administrator privileges.

  • Step 2. Obtain and securely store the first refresh token. This step requires user interaction. It is a one-time step for each user that needs to invoke REST APIs with OAuth 2.

  • Step 3. Obtain an access token from the refresh token. This step is easily automated. Once automation has been implemented, it can run without user interaction.

The following sections provide detailed information about each step.

Step 1: Register an OAuth Client

Registering an OAuth client is a one-time process. The first step is to update the service provider configuration to authorize requests from the REST client application. As a security measure, any client application that accesses Oracle Cloud resources must be authorized to do so. An IDCS Administrator enables this authorization by registering a client and providing the appropriate registration information to the client's users.

A client application in IDCS is used to obtain an access token. A valid access token (also called a Bearer token) is sufficient authorization to invoke a REST API.

Oracle Enterprise Performance Management Cloud uses a role-based access control mechanism to permit only authorized users access to the service. For details, see About EPM Cloud User and Role Management. This requires that any OAuth 2 access token used to access EPM Cloud REST APIs contains a user context.

A grant type is a standard method to obtain an access token. There are a few different Grant Types as listed here that could be used to obtain an access token. An access token obtained by any of the supported grant types is acceptable as long as the access token is in the context of the user that would be invoking the REST APIs.

In this document, we describe the use of the Device Code Grant Type. EPM Automate has built-in support for the Device Code Grant type.

While the Device Code Grant Type would work in a majority of environments, it might not be right for every implementation. Any of the Grant Types that allow creating an access token with a user context would be suitable for EPM Cloud REST APIs. In addition to the Device Code Grant Type, the following Grant Types support access tokens in the context of an end user:

The next section highlights the steps to create a sample OAuth 2 client using the Device Code Grant Type to request an access token. It also demonstrates how to use the access token to invoke EPM Cloud's Get Daily Maintenance Window REST API.

Refer to the Oracle Identity Cloud Service documentation for more details on the Supported Access Grant Types.

The Identity Cloud Service Administrator follows the steps in this topic to create a public client using the Identity Cloud Service Administrator console. The IDCS Administrator then shares the Identity Cloud Service tenant URLand client ID with the EPM Cloud Service Administrator.

If you have an Oracle Identity Cloud Services domain, log in to the Oracle IDCS Administrator console to register an OAuth 2 Client as described in Detailed Information for Using IDCS Administrator Console to Register an OAuth 2 Client.

If your domain is a domain under Oracle Identity and Access Management, follow the instructions in Detailed Information for Using IAM Console to Register an OAuth 2 Client.

Detailed Information for Using IDCS Administrator Console to Register an OAuth 2 Client

  1. From the Applications drawer, click Add at the top of the page.

  2. In the Add Application dialog box, select Mobile Application.

  3. In the App Details section, enter a name for the REST client.
  4. Optional: Add other details.
  5. Click Next.
  6. In the Authorization section, under Allowed Grant Types, unselect the Implicit check box and select the Refresh Token and Device Code check boxes.
  7. Under the Token Issuance Policy section:

    1. Under Grant the client access to Identity Cloud Service Admin APIs, click Add.

    2. Select Identity Domain Administrator.

    3. Click Add to close the pop-up.

  8. Click Next and then Finish to complete creating this OAuth 2 client application.
  9. Note the client ID value on the pop-up.
  10. Click Activate to activate the client, and then click OK.

Detailed Information for Using IAM Console to Register an OAuth 2 Client

  1. Log in to your account at https://cloud.oracle.com/

  2. Click the hamburger menu on the top left and choose Identity and Security and then click Domains on the dialog box.

  3. From the Domains table, choose the appropriate domain (OracleIdentityCloudService by default). This brings you to the Domain Overview page.

  4. Note the Domain URL in the Domain Information section of the page. This is the tenant-base-URL that will be required to request a token.

  5. To create an OAuth 2 client, click Applications in the Identity Domain.

  6. Click the Add application button,

  7. Choose Mobile Application on the pop-up menu and then click the Launch Workflow button.

  8. Enter a name and a description to document the use of this OAuth 2 client.

  9. Click the Next button on the bottom left.

  10. On the Client configuration step, in the Authorization section, select Refresh token and Device code and unselect Implicit.

  11. In the Token Issuance policy section:

    1. Enable Add app roles.

    2. Click the Add roles button.

    3. Choose Identity Domain Administrator on the slide-in dialog box.

    4. Click the Add button to close the slide-in dialog box.

  12. Click Finish to complete the configuration and Activate to activate the application.

  13. Note the Client ID value in the General Information section of the OAuth Configuration.

The IDCS Administrator provides the IDCS URL and client ID to the EPM Cloud Service Administrator.

Step 2. Obtain and securely store the first refresh token

After the Domain Administrator has registered the REST client and provided the IDCS URL and client ID, an EPM Cloud user executes the following steps to get a valid refresh token.

  1. Issue the following unauthenticated request to the Identity Cloud Service URL:

    curl --location --request POST 'https://tenant-base-url/oauth2/v1/device' \
    --header 'Content-Type: application/x-www-form-urlencoded;charset=utf-8' \
    --data-urlencode 'response_type=device_code' \
    --data-urlencode 'scope=urn:opc:idm:__myscopes__  offline_access' \
    --data-urlencode 'client_id=<CLIENT ID OF OAUTH2 APPLICATION>'

    Here, the value of tenant-base-url is the IDCS URL provided by the Domain Administrator or the Domain URL from the IAM console. It is of the form idcs-<alphanumericvalue>.identity.oraclecloud.com. Similarly, the value for the CLIENT ID OF THE OAUTH2 APPLICATION is also provided by the Domain Administrator or retrieved from the Application's General Information section in IAM. It is an alphanumeric value.

    A valid response contains a device code, user code, and verification URI:

    {
      "expires_in": 300,
      "device_code": "4d03f7bc-f7a5-4795-819a-5748c4801d35",
      "user_code": "SDFGHJKL",
      "verification_uri": "https://tenant-base-url/ui/v1/device"
    }

    The user_code from the response is needed in the second step below, while device_code from the response is needed in the third step below.

    Note: Steps 2 and 3 are time-sensitive because the user code and device code expire 300 seconds (5 minutes) after creation. If the codes expire before these steps can be completed, redo the first step of this section to issue an unauthenticated request to the IDCS URL to receive a new pair of user and device codes.

  2. Open the verification_uri in a supported web browser.

    At this stage, it is important to know that if a user already has an active browser session, the user will not be prompted for re-authentication. If the token is to be generated in context of the currently signed-in user, then proceed with 2b. However, if the token is to be generated in the context of a different user, please sign-out of the current session and navigate to the verification_uri and continue with 2a.

    1. When prompted for credentials, authenticate the user who will be invoking the REST API. These credentials could be credentials for a SAML 2.0 compliant Identity Provider or a native IDCS credential.
    2. When prompted for a code in the browser session, enter the user_code from the response payload.
    3. When the Successful message is displayed, it is recommended to log out of the browser session and close the browser window.
  3. Within 5 minutes of executing the first step of this section and after executing the second step, issue the following request to the Identity Cloud Service URL:

    curl --location --request POST 'https://tenant-base-url/oauth2/v1/token' \
    --header 'Content-Type: application/x-www-form-urlencoded;charset=utf-8' \
    --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
    --data-urlencode 'device_code=<DEVICE CODE FROM THE PAYLOAD OF RESPONSE IN FIRST STEP>' \
    --data-urlencode 'client_id=<CLIENT ID OF THE OAUTH2 APPLICATION>'

    Here the value of tenant-base-url is the IDCS URL provided by the Domain Administrator, the device_code value is obtained from the response in Step 1, and client_id is the same client_id used in the first step of this section.

    The response contains the first refresh token:

    {
        "access_token": "eyJ4NXQjUzI.........evRJChXTRfzn6WlCw",
        "token_type": "Bearer",
        "expires_in": 3600,
        "refresh_token": "AQIDBAWF1.....RVkxNCB7djF9NCA="
    }

Secure and Protect the Tokens and Client ID

With OAuth 2, tokens are used instead of user credentials to access resources on EPM Cloud. A refresh token and client ID are used to get a new access token and a new refresh token. Thus, to ensure security of EPM Cloud, it is important to securely encrypt and store the client_id and any tokens. The REST client must securely store the refresh token and client_id.

For EPM Automate, use the encrypt command to create an epw file for OAuth 2.

Step 3: Obtain an Access Token from the Refresh Token

This step is required every time a new access token is required. The REST client uses the latest refresh token and client id to get an access token. It uses the access token as authorization to invoke REST APIs. It also ensures that the latest refresh token and client ID are stored securely.

The REST client uses the Refresh Token Grant type to get a new access token and a new refresh token. As mentioned above, this step can be automated. Once automated, it does not require user interaction.

To obtain a valid access token with this Grant Type, the REST client issues the following request to the IDCS URL:

curl --location --request POST 'https://tenant-base-url/oauth2/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=<DECRYPTED CLIENT ID OF OAUTH2 APPLICATION FROM SECURE STORE>' \
--data-urlencode 'refresh_token=<DECRYPTED REFRESH TOKEN FROM SECURE STORE>'

Here, the value of tenant-base-url is the IDCS URL provided by the Domain Administrator, and the refresh_token and client_id are obtained from the secure store where there were previously stored.

Note: While the client_id and refresh_token are stored securely, it is important that both refresh_token and client_id are decrypted to use in any request. All requests to Oracle IDCS and EPM Cloud are securely transmitted using the https protocol.

Example response:

{
"access_token": "eyJj5M4QjUkI.........abSjZaa86PlseS4lrt7R2",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "AAyyilYBAWD4....FVkxefd8kjoJr6HJPA="
}

The REST client saves the new refresh token for future use (see Secure and Protect the Token and Client ID) and uses the access token as authorization while invoking the REST API (see Use the Access Token).

Use the Access Token

In order to invoke an EPM Cloud REST API, the REST client must provide the access token (obtained in the previous step) in the authorization header as follows:

Authorization: Bearer <access token>

For example, to get the Automated Maintenance Window start time, the client application submits a GET request to this EPM Cloud endpoint /interop/rest/v1/services/dailymaintenance using the access token in the authorization header.

curl --location --request GET 'https://epm-host/interop/rest/v1/services/dailymaintenance' \
--header "Authorization: Bearer eyJ5M4QjUkI...abSjZaa86PlseS4lrt7R2"

Frequently Asked Questions

OAuth 2 was set up following the documentation before EPM Cloud Release 23.07. Is that configuration still valid?

Yes, the existing configuration will continue to work with existing OAuth 2 support for REST APIs and EPM Automate. However, it is highly recommended to use the updated procedure as it provides greater clarity and might be required for future updates.

How do I change my existing configuration created before EPM Cloud Release 23.07 to be consistent with the current procedure?

The following steps will bring your existing configuration in line with the documented configuration:

  1. For the Oracle Cloud Services, on the Configuration tab under Resources, unselect the Is Refresh Token Allowed checkbox.

  2. For the OAuth 2 client application, under Token Issuance Policy, remove the Resource or Resources selected and add the Identity Administrator Role to the Client as described in Step 7 for IDCS Administrator console or Step 11 for IAM console.

  3. Follow the steps described in Step 2. Obtain and securely store the first refresh token to request a new refresh token using the scope urn:opc:idm:__myscopes__ offline_access. After getting the refresh token, save it securely.

    For EPM Automate, create a new epw file using the updated instructions in EPM Automate Commands, and then save the new refresh token and client id and use it to authorize access.

Can the expiry time of a refresh token be modified?

The expiry time of the refresh token is configurable in Identity Cloud Service by the Domain Administrator on a per EPM Cloud environment basis. The client requesting the refresh token cannot modify the expiry time or duration. The client should request a new refresh token before the old one expires, in order to not repeat the initial setup again. The default expiry period is 604800 seconds, which is 7 days.

What error is returned when the refresh token has expired?

Executing a refresh token grant flow with an expired refresh token results in a 400 Bad Request response and the following payload:

{  "error": "invalid_grant",
    "error_description": "Token is expired for client : <CLIENT_ID>",
    "ecid": "UsbMB0KCV00000000"
}

What error is returned when the refresh token is invalid?

Executing a refresh token grant flow with an invalid refresh token results in a 400 Bad Request response and the following payload:

{  "error": "invalid_grant",
    "error_description": "The given token in the request is invalid",
    "ecid": "UsbMB0KCV00000000"
}

What errors are returned for other issues?

A 400 Bad Request response with the following payloads are returned when there is an error:

Invalid request (for example, not all request parameters are supplied):

{
    "error": "invalid_request",
    "error_description": "The request contains invalid parameters or values"
}

Invalid grant (for example, using a token that has already been used) :

{
    "error": "invalid_grant",
    "error_description": "The token has already been consumed"
}

Invalid scope (for example, providing invalid scope):

{
    "error": "invalid_scope",
    "error_description": "Invalid scope"
}

What error is returned when an invalid or expired access token is provided?

When an invalid or expired access token is provided in a request, the server responds with a 401 Unauthorized response with the following HTML in the payload:

<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr>
</body>
</html>

Can a token be requested with multiple scopes?

Multiple scopes across different resources (EPM Cloud environments) are not supported by Identity Cloud Service. Each token request can support only one resource. Requests for multiple scopes within the same resource are supported with space delimited scopes. Requesting multiple scopes across different resources results in a 400 Bad Request response with the following payload:

{
"error": "invalid_scope",
"error_description": "Invalid scope"
}

Can a valid token received for one EPM Cloud environment be used to access all EPM Cloud environments in the same IDCS domain?

The EPM Cloud Service Administrator for an environment provisions each user with predefined and application roles and specific access for that environment. The same user may be provisioned with different privileges on different environments in the same IDCS domain. The functionality that a user is able to perform on any EPM Cloud environment is dependent on the roles and access the user has on that environment. Thus, a valid, unexpired bearer token received for one EPM Cloud environment can be used across all EPM Cloud environments in the same IDCS domain for authentication purposes. However, the authorization of what a particular user can do on a particular EPM Cloud environment is dependent on the roles the user has on that environment.

What information is logged in the access log with OAuth?

The access log shows the user name, just as it does with basic authorization. The client ID and access token are not logged.

When using multiple scripts to run EPM REST APIs, the refresh token grant type seems to fail randomly with a message that the token is already consumed. What is the resolution?

Each refresh token is a single use token. After first use, the same token cannot be reused. Trying to use a particular token after it has already been used results in the message, The token is already consumed.

The right way is to set up each script with its own refresh token. To do that, execute the procedure to obtain and save the first refresh token once for each script requiring a refresh token, and then set up each script to use its own refresh token. All scripts can still use the same clientID.