---
title: "OAuth2 Authentication Support"
slug: "oauth2-authentication-support"
updated: 2025-11-16T15:58:49Z
published: 2025-11-16T15:58:49Z
---

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plainid.io/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth2 Authentication Support

OAuth2 is an authorization protocol that provides a secure way to access protected data from an application. The PIP Service can be configured to use OAuth 2.0 to securely access API based data sources, such as SCIM, Azure AD, OData, and REST.

To support OAuth authentication, pre-configuration is required. Individual websites typically provide developer-facing REST-based APIs for accessing their content and ways to register custom applications on users' behalf. The first step is to register the custom application on the website and collect consumer/API keys and secrets.

## OAuth Configuration For PAA

After you get your service client credentials, you need to set them up in the PIP Auth configuration. Currently, the Auth configuration for external services is done in an auth XML file containing general setup that you don’t need to change and security policy sections that need to be added for each service using OAuth.

### Environment Variables

Before configuring the sample code below, note that any module-option name can be set using an environment variable by enclosing it in `${env:&lt;module-option&gt;}`. The variable name can be any valid string.

For example: `&lt;module-option name=“client-secret”&gt; ${env: CLIENT_SECRET} &lt;/module-option&gt;`

### Using Secret Annotations in OAuth Configuration

In OAuth authentication, you can reference a secret from a secret store within the OAuth XML configuration file. The following example demonstrates how to use a secret annotation for the **client-secret** field:

```
<application-policy name="ps-auth2-massive">
    <authentication>
        <login-module code="com.plainid.pip.auth.oauth.clientcredential.OAuth20ClientCredentialLoginModule" flag="required">
            <module-option name="access-token-uri">https://login.microsoftonline.com/cd6168ed-fe82-4528-b2eb-4e030d322878/oauth2/v2.0/token</module-option>
            <module-option name="client-id">19f4ef6c-d0dd-42f0-844c-b529b609a171</module-option>
            <module-option name="client-secret">{{ printf "{{store=AWS_SECRETS_MANAGER_STORE,key=path1/path2/key}}" }}</module-option>
            <module-option name="scope">https://graph.microsoft.com/.default</module-option>
        </login-module>
    </authentication>
</application-policy>
```

Refer to [Using Secrets for PIP Data Sources](/docs/secret-management-configuration-1#using-secrets-for-pip-data-sources) for more information.

### Sample auth-config.xml file:

```
<?xml version='1.0'?>
<policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:security-config:5.0" xmlns="urn:jboss:security-config:5.0" xmlns:jbxb="urn:jboss:security-config:5.0">
  <application-policy name="teiid-security-file">
    <authentication>
      <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
        <!-- https://access.redhat.com/documentation/en-us/jboss_enterprise_application_platform/5/html/security_guide/ch12#Using_JBoss_Login_Modules-Password_Hashing -->
        <module-option name="usersProperties">users.properties</module-option>
        <module-option name="rolesProperties">roles.properties</module-option>
        <module-option name="unauthenticatedIdentity">nobody</module-option>
        <module-option name="hashAlgorithm">MD5</module-option>
        <module-option name="hashEncoding">base64</module-option>
      </login-module>
    </authentication>
  </application-policy>

  <application-policy name="oauth2-azure-ad-staging">
    <authentication>
      <login-module code="com.plainid.pip.auth.oauth.clientcredential.OAuth20ClientCredentialLoginModule" flag="required">
        <module-option name="scope">https://graph.microsoft.com/.default</module-option>
        <module-option name="access-token-uri">https://login.microsoftonline.com/********-****-****-****-************/oauth2/v2.0/token</module-option>
        <module-option name="client-id">client-id</module-option>
        <module-option name="client-secret">{{ printf "{{store=AWS_SECRETS_MANAGER_STORE,key=path1/path2/key}}" }}</module-option>
      </login-module>
    </authentication>
  </application-policy>

  <!-- Add application credentials. Details below -->
</policy>
```

For each service using OAuth, you need to add an `&lt;application policy&gt;` section with the relevant service credentials.

### Sample `&lt;application-policy&gt;` Settings for Azure AD OAuth Configuration

```
<application-policy name="oauth2-azure-ad-staging">
  <authentication>
    <login-module code="com.plainid.pip.auth.oauth.clientcredential.OAuth20ClientCredentialLoginModule" flag="required">
      <module-option name="scope">https://graph.microsoft.com/.default</module-option>
      <module-option name="access-token-uri">https://login.microsoftonline.com/********-****-****-****-************/oauth2/v2.0/token</module-option>
        <module-option name="client-id">${env:AAD_CLIENT_ID}</module-option>
        <module-option name=“client-secret”>${env:AAD_CLIENT_SECRET}</module-option>
    </login-module>
  </authentication>
</application-policy>
```

The `application-policy` name (in the above example is `oauth2-azure-ad-staging`) is used to set the **Security Domain** field in the PIP Settings screen when configuring the Data Source.

### Module Options Properties Table

The OAuth jar (`pip-auth-extensions-#.jar`) and `auth-config.xml` configuration file should be set in all PAAs.

| Property | Description | Mandatory |
| --- | --- | --- |
| scope | OAuth2 scope | No |
| access-token-uri | Access token URL from IDP | Yes |
| client-id | Client ID of the application | Yes |
| client-secret | Client Secret of the application | Yes |
| setAuthorizationHeader | Indicates how client credentials will be sent to the token endpoint (True - ClientID and Secret passed as authorization header, False - ClientID and Secret passed in the form payload) | No |

---

## Assertion Flow OAuth Configuration

Some services may require the OAuth 2.0 **assertion flow** instead of the standard client credentials flow. The PIP Service supports this using the **`OAuth20AssertionCCLoginModule`**, which exchanges a signed JWT for an access token at the token endpoint.

This module signs a JWT using a private key and submits it to the token endpoint to obtain an access token. Unlike standard OAuth flows that use a client secret, the assertion flow is required when the identity provider enforces **key-based authentication**.

### Example

Below is an Okta Assertion Flow example:

```
<application-policy name="Acme1">
  <authentication>
    <login-module code="com.plainid.pip.auth.oauth.assertion.OAuth20AssertionCCLoginModule" flag="required">
      <module-option name="client-id">0oav0ftbpiwt38hgf697</module-option>
      <module-option name="scope">okta.users.read okta.users.manage</module-option>
      <module-option name="access-token-uri">https://integrator-143235553242307.okta.com/oauth2/v1/token</module-option>
      <module-option name="private-key">-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiGew0BAQ2FAASCBKgwggSkAjhgfhAoIBfQCttJR5P6cE71A8
...
psu+yfpqVRsUy0yaJnNR7jeu
-----END PRIVATE KEY-----</module-option>
    </login-module>
  </authentication>
</application-policy>
```

---

### Module Options for Assertion Flow

| Property | Description | Mandatory |
| --- | --- | --- |
| client-id | Application Client ID registered in the IdP | Yes |
| scope | Space-separated OAuth scopes for access | Yes |
| access-token-uri | Identity provider token endpoint URL | Yes |
| private-key | Private key used to sign the JWT for assertion | Yes |

          Secret Manager Support

          

Secret Manager (SM) support: Only the client-id and private-key can reference secrets using the store format described in the [Secret Management](/v1/docs/secret-management-configuration-1) documentation: `{{store=&lt;storeName&gt;,key=&lt;keyName&gt;,jsonpath=$.&lt;path&gt;}}`

---

## User-Password login through Token configuration

This module supports calling a REST API endpoint for authentication and retrieving a token that can be used for requests to services using User/Password Login Tokens (not by OAuth standard), like the **Saviynt** API.

To support this general User/Password flow, use the login module called `TokenRestLoginModule`. Instead of exchanging a Client ID and Secret in a token endpoint as done in a standard OAuth 2.0 client credential flow, it makes a REST call to a login API, sends the required credentials as parameters or in the request body, and extracts a token from the response.

          Saviynt Note

          

For example, Saviynt uses the `/ECM/api/login` endpoint to authenticate API calls. This requires users to send a user/password, they receive a token from the login response, and then using that token to authenticate subsequent Saviynt API requests and fetch data.

The new `TokenRestLoginModule` supports two configuration flows using configurable **credentials** in:

- The Login call as request params.
- The params to generate a Login call payload if the login endpoint expects a request body.

          Secret Manager Support

          

The credentials defined in the username and password parameters can be obtained through Secret Manager support by configuring a secret key syntax. like{{store=<storename data-tomark-pass="">,key=<keyname data-tomark-pass="">,jsonpath=$.<path data-tomark-pass="">}}, instead of entering clear text credentials. See the Secret Management<br> {target=_blank} documentation for more information.</path></keyname></storename>

### Examples

#### Credentials Params Example

```
<application-policy name="saviynt1">
  <authentication>
    <login-module code="com.plainid.pip.auth.oauth.custom.TokenRestLoginModule" flag="required">
      <module-option name="url">https://<saviynt-base-url>/ECM/api/login</module-option>
      <module-option name="param:username">admin</module-option>
      <module-option name="param:password">adminpass123</module-option>
      <module-option name="header:Content-Type">application/json</module-option>
      <module-option name="method">POST</module-option>
      <module-option name="body">{}</module-option>
      <module-option name="credential-flow">Basic</module-option>
    </login-module>
  </authentication>
</application-policy>
```

#### Parameterized Body Example

In this option the `username` and `password` are declared as params and defined in the config and than referenced by the syntax ${param} in the body template.

```
<application-policy name="saviynt1">
  <authentication>
    <login-module code="com.plainid.pip.auth.oauth.custom.TokenRestLoginModule" flag="required">
      <module-option name="url">https://<saviynt-base-url>/ECM/api/login</module-option>
      <module-option name="param:username">admin</module-option>
      <module-option name="param:password">adminpass123</module-option>
      <module-option name="header:Content-Type">application/json</module-option>
      <module-option name="method">POST</module-option>
      <module-option name="body">{"username": "${username}","password": "${password}"}</module-option>
    </login-module>
  </authentication>
</application-policy>
```

### Module Options

These are Module options for Saviynt:

| Property | Description | Mandatory |
| --- | --- | --- |
| url | Saviynt login API endpoint (e.g., `https://&lt;saviynt-base-url&gt;/ECM/api/login`) | Yes |
| param:username | Username for authentication. Can use **Secret Manager variables** with the format `{{store=&lt;storeName&gt;,key=&lt;keyName&gt;,jsonpath=$.&lt;path&gt;}}` | Yes |
| param:password | Password for authentication. Can use Secret Manager variables with the format `{{store=&lt;storeName&gt;,key=&lt;keyName&gt;,jsonpath=$.&lt;path&gt;}}` | Yes |
| header:Content-Type | Content type header (usually `application/json`) | Yes |
| method | HTTP method used for authentication, usually `POST` | Yes |
| body | Any text (e.g., JSON) sent to the login endpoint. Supports parameterization with `${}` placeholders for dynamic values (username, password, etc.) | Yes |
| credential-flow | When set to Basic, the `param:username` and `param:password` values are automatically encoded as Basic Auth using Base64 on <user>:<password>. If omitted or left empty, Basic Auth is not applied and the user must manually include the username and password as needed, like within the JSON payload in body. | No |

**Additional Information**

- **Environment variables:** Any `module-option` can be overridden with environment variable syntax (`${env:VAR_NAME}`). Tags in between are processed through an Environment Variable translation.

---

## Containerized PAA

In Containerized PAA, the **auth-config.xml** file is located at `app/conf/auth-config.xml`.

PlainID PAA Helm Chart includes two configuration files:

- **values.yaml** - Stores all potential setting parameters, and the default values for the PAA.
- **custom-values.yaml** - Used to set only the parameters/settings that are modified. As a best practice, we recommend using this file for setting the relevant parameter values by adding configuration values from the **values.yaml** to the **values-custom.yaml** file.

You can use the above **custom-values.yaml** mechanism to inject your **auth-config.xml** file. You need to add all the XML content, not just your application policies sections, to your **custom-values.yaml** under this key:

```
pipOperator:
  plainIDConfig:
    auth-config.xml: |
      <?xml version='1.0'?>
      <policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:security-config:5.0"
        xmlns="urn:jboss:security-config:5.0">
        <!-- Add your XML content here -->
      </policy>
```

Following is an example:

```
tenantId: "ENTER_TENANT_ID" # Tenant Id (can be found in the Hybrid Agent Keys tab)
agentSecretKey: "ENTER_AGENT_SECRET_KEY" # Agent Secret key (can be found in the Hybrid Agent Keys tab)
paaId: "ENTER_PAA_ID" # Policy Authorization Agent Id (can be found in the Policy Authorization Agents tab)

pipOperator:
  plainIDConfig:
    auth-config.xml: |
      <?xml version='1.0'?>
      <policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:security-config:5.0"
        xmlns="urn:jboss:security-config:5.0">
        <!-- Add your XML content here -->
      </policy>
```

### Standalone/VM PAA

In a Standalone/VM PAA, the `auth-config.xml` file is located at `$PLAINID_HOME/pip-operator/conf/auth-config.xml`. Add OAuth services as application policies, as described above.

### OAuth Logging

Additional logging for OAuth can be configured by adding the following section to the `auth-config.xml` via the `custom-values.yaml` mechanism:

```
<logger name="org.teiid.jboss.oauth" level="detail" additivity="false">
    <appender-ref ref="RollingFile" />
</logger>
```

### OAuth Setting For PIP Data Sources

After completing the OAuth configuration, you will be able to configure PIP data sources accessible by OAuth authentication.

In the PIP settings UI, when creating a data source with adapters that allow/require the usage of OAuth (e.g., Azure Active Directory, SCIM, REST, or OData v4.0), you will need to reference the `auth-config.xml` file and the specific application-policy name as the Security Domain:

1. In the **Policy Authorization Agent** section(s), under the **Security Type** field, choose **None**.
2. In the **Translator Properties** section, add two new properties with these key-value pairs:
  - Key = `authConf`, Value = "<path of the `auth-config.xml` file as described above.>"
  - Key = `securityDomain`, Value = "<name of the application-policy you added in the XML for your service>"

## Using Secrets for PIP Data Source Connections

When configuring databases and other data sources in the UI, you can use secrets to manage authentication credentials securely. Instead of storing credentials in plain text, you can reference them from a secret store, enabling seamless secret rotation and enhanced security.
