The PlainID IDP Token Enrichment Service integrates with Identity Providers (IDPs) to dynamically enrich users' Authorizations. During user authentication, entitlements calculated by PlainID policies are translated into claims and included in the JWT generated by the IDP, which is then used by Applications.
This Authorization pattern enables seamless control over user access per authentication session, without requiring the user or the Application to interact with the PlainID platform or be aware of the dynamic policy calculations. This ensures that your organization's access rules are applied transparently.
You can read more about this Authorization pattern here.
Many IDP providers connect to external data sources during user login to enrich token claims. PlainID acts as an enrichment provider by adapting to each IDP vendor’s proprietary configuration and mapping requirements, aligning them with PlainID’s request and response structures.
To leverage this pattern, deploy and configure the IDP Token Enrichment Service, connect your Applications to the PDP for Policy decisions, and complete the integration with your organization’s IDP. This page provides details on how to deploy, configure, and maintain the IDP Token Enrichment Service. For IDP integration, refer to the relevant IDP vendor page in our documentation as well as the vendor's own documentation.
Token Enrichment Workflow Example
- User requests to log into the Online Bank Portal.
- The organization's Online Bank Portal application receives the login requests and sends a query to the IDP.
- The IDP sends a query to the PlainID IDP Token Enrichment Service
- The PDP calculates the decision.
- The PDP returns a decision. Claims with the required values are then returned to the PlainID Token Enrichment Service, which enriches the JWT token and returns it to the organization's IDP.
- The enriched JWT is returned to the Application, which uses the information in the enriched token to either allow or deny access to the Application.
PAP Prerequisites
To leverage the IDP Token Enrichment Service with your IDP, you must define the necessary authorization artifacts within the PlainID Dynamic Authorization Platform (PAP). The following artifacts are required to complete the integration:
- Application
- Represents the integration with your IDP.
- Asset Type (linked to the Application)
- Governs the authorizations or claims received based on Policies during the token enrichment process.
- Scope (linked to the Application)
- Acts as an integration object. Retain your Scope's
Client ID
andClient Secret
, as these need to be defined in the IDP Token Enrichment Service Configuration.
- Acts as an integration object. Retain your Scope's
- Policies
- Corresponding Policies must be created and linked to the Application and Asset type. These Policies define the business logic that dynamically determine the Authorizations enriched in the user token.
- PAA (Policy Authorization Agent)
- The Policy Authorization Agent must be downloaded, deployed, and operational within your infrastructure.
PlainID fully supports Cloud integration for some IDPs. This requires a Claims Asset Type definition, in addition to defining your Authorizations as Claim Assets with pairs of claimKey
and claimValue
Attributes.
Contact PlainID Support for more details regarding this integration pattern.
IDP Prerequisites
IDP prerequisites and integration specifics are detailed in each IDP vendor page. You can refer to the following vendor pages for more information:
If using any other IDP that supports external data source integration during the authentication flow and you wish to integrate with PlainID as an enrichment provider, please contact PlainID support.
IDP Token Enrichment Service in the Policy Authorization Agent (PAA)
The PAA deployment includes the IDP Token Enrichment Service as part of the service bundle. By default this service is disabled and if needed it should be enabled and configured.
To install or upgrade your IDP Token Enrichment Service:
K8s Helm Deployment
- Download the Helm package for the relevant PAA.
- In the downloaded Helm package, locate and open the values.yaml and custom-values.yaml files. Similar to other services, you can override configuration by copying relevant configurations from the values.yaml to custom-values.yaml and define there your preferred values.
- In the values.yaml file, locate the
idpWebhook
section which includes:- The service enablement configuration flag
- Other service operational configurations
- Consult our Professional Services team if required.
- A commented out
config.yaml
section with all configurations you need for the integration.
- Copy the
idpWebhook
section to your custom-values.yaml - To enable the IDP Token Enrichment Service, set the
idpWebhook: enabled:
flag totrue
. - Configure additional service operations as needed (refer to the Additional Configurations section).
- Configure your IDP applications in the relevant section.
Standalone Deployment
- Download the Standalone package for the relevant PAA.
- To enable the IDP Token Enrichment Service:
- Locate and open the
plainid/init/aliases
file. - Locate the
function start_plainid_paa() {
andfunction stop_plainid_paa() {
functions. - Append
start_idp-webhook
andstop_idp-webhook
to the end of the relevant sections.
- Locate and open the
- To configure your IDP Token Enrichment Service integration, locate the config.yaml file under idp-webhook\conf folder in your downloaded pack, configure additional service operations as needed, and setup your IDP applications.
Additional Configurations
For details on additional configurations, refer to IDP Token Enrichment Service Configuration Parameters section and copy the relevant parameters to your custom-values.yaml file and edit according to your IDP integration. Set up additional service operational configuration as needed and setup your IDP applications.
Configure Your IDP Token Enrichment Service Integration
The configuration for your IDP integration within the IDP Token Enrichment Service is handled through the config.yaml file for Standalone deployments, or by copying the relevant section from values.yaml to values-custom.yaml for Kubernetes Helm deployments.
These configurations define general service settings and details about the Applications integrated from your IDP, including how requests are processed and how PlainID dynamic authorizations will enrich claims. Detailed tables outlining the various configuration options and their explanations are provided in the following section.
IDP Token Enrichment Service Configuration Parameters
If using a Helm deployment, all configurations need to be set through the custom-values.yaml file in your package. Ensure that you copy the relevant parameters from the values.yaml and add it to your custom-values.yaml.
General Parameters
KeyName | Required | Description | Value Examples | Default | Vendor-specific Required Parameters |
---|---|---|---|---|---|
http.port |
Yes | The port that the IDP Token Enrichment service listens to | 5001 |
8080 |
-- |
server.name |
Yes | Name of the server | idp-hook |
idp-webhook |
-- |
server.auth.secret |
No | This secret is used to allow the IDP to authenticate with the IDP Token Enrichment Service endpoint | -- |
-- |
-- |
runtime.host |
Yes | Base URL of the PDP in your PAA | -- |
-- |
-- |
runtime.uri |
Yes | Static value of the PDP endpoint used for token enrichment | /api/runtime/token/v3 |
-- |
-- |
runtime.timeout |
No | Timeout for PDP Runtime requests | 3s |
-- |
-- |
runtime.ignoreSSL |
No | Flag to ignore SSL certificate validation | false |
false |
-- |
log.format |
No | Log format | text / json (for structured logging) |
text |
-- |
log.level |
No | Log level | trace , debug , info , warn , warning , error , fatal , panic |
info |
-- |
log.logTo |
No | Log destination | console / file / rolling |
console |
-- |
log.filePath |
Yes, if log.logTo has any of values: file, rolling | Log file location | /opt/plainid/logs/idpwebhook.log |
-- |
-- |
log.maxSize |
No | MaxSize is the maximum size in megabytes of the log file before it gets rotated. | 10 |
100MB |
-- |
log.maxAge |
No | MaxAge is the maximum number of days to retain old log files based on the timestamp encoded in their filename. | 14 |
The default is not to remove old log files based on age. | -- |
log.maxBackups |
No | MaxBackups is the maximum number of old log files to retain. | 5 |
The default is to retain all old log files (though MaxAge may still cause them to get deleted) | -- |
log.localTime |
No | LocalTime is the local time zone. | true , false (use UTC time) |
false |
-- |
log.compress |
No | Compress determines if the rotated log files should be compressed using gzip. | true , false (not to perform compression) |
false |
-- |
management.port |
Yes | Port for management endpoint | 8081 |
8081 |
-- |
Application Parameters
Integration with IDPs is based on applications, defined in the IDP and represent the business application that will consume the dynamic authorization via token enrichment, and configured in the Token Enrichment Service with the below parameters.
Note: Each Application the IDP Token Enrichment service needs to have individual Application configurations.
KeyName | Required | Description | Value Examples | Default | Vendor-specific Required Parameters |
---|---|---|---|---|---|
apps.<app> |
Yes | The IDP Application name - must be an exact match and unique | -- |
-- |
-- |
apps.<app>.clientid |
No | The PlainID Scope Client ID | PSIG6O4TLVZ6EJZRZJKT |
-- |
Required for: - Entra ID |
apps.<app>.clientsecret |
No | The PlainID Scope Client Secret | -- |
-- |
Required for: - Entra ID |
apps.<app>.entitytype |
Yes | The Identity Type which will be used for the authorization calculation in PDP | User , employees etc. Or any Identity Template ID defined in PlainID and used for the integration. |
User |
-- |
apps.<app>.userid |
No | The JSON path to the user ID in the IDP request | $.Data.AuthenticationContext.User.UserPrincipalName |
-- |
Required for: - Entra ID |
apps.<app>.claims |
Yes | List of claims and the corresponding JSON Path mappings from the PlainID PDP Response | plainid: $.response[*].access[?(@.resourceType == "accounts")].path See a full example in the Mapping the PlainID Policy Decision Response to Claims section below. |
-- |
|
apps.<app>.includeidentity |
No | Indicate to the PDP whether to include the Identity Attributes in the response | true false |
false |
-- |
apps.<app>.resourcetypes |
No | Resource types passed to PDP. Resource Type is a representation of the Asset type governs the authorizations/claims one will get based on policies during the token enrichment flow. |
Any valid resource type defined in the Authorization WS used for the integration | -- |
-- |
apps.<app>.parseResponseType |
No | Switches to key value format in claims. | jsonpath / cloud (used for claims key value pairs in full cloud integration when applicable) |
jsonpath |
-- |
apps.<app>.tokentype |
No | Used in claim parsing logic of Okta IDP | identity , access |
-- |
Required for: - Okta |
apps.<app>.params |
No | Additional params used for Okta IDP | -- |
-- |
Required for: - Okta |
apps.<app>.idToken |
No | Contains configurations needed for OIDC Token Verification. | -- |
-- |
Required for: - Entra ID |
apps.<app>.idToken.verify |
No | Enable OIDC token verification | true , false |
false |
Required for: - Entra ID |
apps.<app>.skipClientIDCheck |
No | Skip JWT Audience (ClientID in OIDC terms) check (for testing purposes) | true , false |
false |
Required for: - Entra ID |
apps.<app>.skipIssuerCheck |
No | JWT Issuer check skip (for testing purposes) | true , false |
false |
-- |
apps.<app>.idToken.iss |
Yes, only if the idToken.verify is set to true | JWT Issuer | https://login.microsoftonline.com/c179854f-7b57-4eee-abb2-b34cbcf0626e/v2.0 |
-- |
Required for: - Entra ID |
apps.<app>.idToken.aud |
Yes, only if the idToken.verify is set to true | JWT Audience | fe88b193-bb50-4c09-ade0-a2710dd9f5d7 |
-- |
Required for: - Entra ID |
Configuring Environment Variables
Users can set Environment Variables in their config.yaml to handle sensitive data (e.g., API keys) and manage configurations across different Environments.
Every configuration value supports Environment Variables substitutions in the following format:
${ENV_VAR_NAME:<default_value>}
The default_value
parameter is optional.
E.g. port: ${MANAGEMENT_PORT:8081}
Note: In the following example, there are two IDP Application configurations ("Bank Portal" and "Loans Approval")
Configuration Example
server:
name: idp-webhook
auth:
secret: ${IDP_HOOK_AUTH_SECRET} # This secret will be used to allow the IDP to authenticate with the IDP Webhook endpoint (Optional)
http:
port: ${IDP_HOOK_HTTP_PORT:8020}
management:
port: ${IDP_HOOK_MANAGEMENT_PORT:8021}
# if management endpoint path needs to be changed from the default /health:
# prefix: ${IDP_HOOK_MANAGEMENT_PREFIX:/probes}
log:
level: ${IDP_HOOK_LOG_LEVEL:debug} # possible values: trace, debug, info, warn, warning, error, fatal, panic
format: ${IDP_HOOK_LOG_FORMAT:json} # possible values: json, text
logTo: ${IDP_HOOK_LOG_TO:file} # possible values: console, file, rolling
filePath: ${IDP_HOOK_LOG_FILE_PATH:logs/webhook.log} # only relevant if logTo is file or rolling
# if logTo is rolling - use the following optional parameters to configure the rolling file appender
# maxSize: 2
# maxAge: 1
# maxBackups: 5
# compress: true
# localTime: false
runtime:
host: ${PDP_RUNTIME_HOST:https://demo.plainid.cloud}
uri: /api/runtime/token/v3
timeout: 3s
apps:
Bank Portal:
clientid: ${BANK_PORTAL_SCOPE_CLIENT_ID:PPWZYCOMXGNTHMGO8CIT}
clientsecret: ${BANK_PORTAL_SCOPE_CLIENT_SECRET}
entitytype: User
tokentype: identity # possible values: identity, access
includeIdentity: true
userid: $.identity.claims.sub
claims:
plainid: $.response[*].access[?(@.resourceType == "assetExternal")].path
FirstName_identity: $.identity.attributes.first_name
Loan Approval:
clientid: ${LOAN_APPROVAL_SCOPE_CLIENT_ID:PXY8GCMDLPKSNAFDAA7A}
clientsecret: ${LOAN_APPROVAL_SCOPE_CLIENT_SECRET}
entitytype: Main
tokentype: identity # possible values: identity, access
userid: $.identity.claims.sub
claims:
plainid: $.response[*].access[?(@.resourceType == "portal-permissions")].path
FirstName_identity: $.identity.attributes.name
Mapping the PlainID Policy Decision Response to Claims
When integrating the PlainID Policy Decision Point (PDP) with your Identity Provider (IDP), the Policy Decision Response returned by the PDP often contains valuable authorization data, like attributes or identity claims. Mapping these values correctly to the user’s token or claims in the IDP is crucial for ensuring that the right access permissions are granted.
To facilitate this mapping, you can use JSONPath Expressions, which allow you to extract specific data points from the PDP response and map them to claims within the IDP. Each expression corresponds to a particular set of information in the PDP response, which you can enrich the user’s token with during the token enrichment process.
PlainID Policy Decision Response Mapping Examples:
Expression | Description |
---|---|
$.response[*].access[?(@.resourceType == "ProfileInformation")].attributes.BU |
Get the Business Unit (BU ) code from the ProfileInformation Assets included in the PDP Response |
$.response[*].access[?(@.resourceType == "Accounts")].path |
Get the Asset id (path ) from the Accounts Asset Type Assets included in the PDP Response |
$.response[*].access[?(@.resourceType == "InternalIDP")].attributes.AttText[*] |
Get a multi-value set of Attributes from the InternalIDP Asset Type Assets included in the PDP Response |
$.identity.attributes.user_role |
Get the user_role Attribute from the identity included in the PDP Response Notice: To map identity Attributes, the includeIdentity must be set to true |
Use-Case Decision Mapping Scenario
Below is a use-case scenario which includes a PDP Response Sample, Service mapping example, and a sample response derived from the sample and mapping example:
PDP Response Sample
Below is a sample response which contains the values that are extracted in the claim mapping process.
{
"tokenValidity": 0,
"response": [
{
"access": [
{
"path": "docE3",
"attributes": {
"EntitlementID": [
"docE3"
],
"EntitlementName": [
"Documents Delete"
],
"AppID": [
"doc_portal"
]
},
"resourceType": "appsEntitlements",
"actions": [
{
"action": "ACCESS"
}
]
},
{
"path": "docE2",
"attributes": {
"EntitlementID": [
"docE2"
],
"EntitlementName": [
"Documents Move"
],
"AppID": [
"doc_portal"
]
},
"resourceType": "appsEntitlements",
"actions": [
{
"action": "ACCESS"
}
]
},
{
"path": "docE1",
"attributes": {
"EntitlementID": [
"docE1"
],
"EntitlementName": [
"Documents Read"
],
"AppID": [
"doc_portal"
]
},
"resourceType": "appsEntitlements",
"actions": [
{
"action": "ACCESS"
}
]
}
]
}
],
"contextData": null
}
Service Mapping Example
This is an example of an IDP Token Enrichment Service configuration that the user can copy from the values.yaml and configure in the custom-values.yaml:
apps:
- TestIntegration:
clientid: ********
clientsecret: ***************
entitytype: Sample_Identity
claims:
# plainid_app_id: $.response[*].access[?(@.resourceType == "appsEntitlements")].attributes.AppID[*]
plainid_entitlement: $.response[*].access[?(@.resourceType == "appsEntitlements")].attributes.EntitlementName[*]
Sample Response
In the sample response, the plainid_entitlement claims mapping is shown with the relevant values.
{
"plainid_entitlement": [
"Documents Delete",
"Documents Move",
"Documents Read"
]
}
Maintenance
Users can regularly check the service logs to monitor for any errors or warnings and use the health check endpoints to ensure the service is running properly.
Monitoring
Following is a list of known errors and troubleshooting tips:
-
Error: "
failed to locate app
"- Cause: The requested application in the IDP request is not found in the IDP Token Enrichment Service configuration.
- Resolution: Check the application configuration section and verify that the app name is consistent in both the IDP and IDP Token Enrichment Service configurations.
-
Error: "
failed to GetToken
"- Cause: This error is typically caused by PDP Runtime issues or connection configuration problems.
- Examples:
failed to GetToken: received status 400 and body: User is not a valid identity type
failed to GetToken: received status 401 and body: Invalid secret
failed to GetToken: failed to do runtime request: Post "http://10.7.66.13:8080/api/runtime/token/v3": dial tcp 10.7.66.13:8080: i/o timeout
- Resolution: Review and correct any PDP Runtime or connection configuration issues. Ensure that the connection details and secrets are valid.
Log Management and Backup Procedures
To maintain the IDP effectively, it's important to monitor and manage log files regularly. This ensures that they do not consume excessive storage space. If necessary, adjust the log rotation settings to manage the log file growth more efficiently. Regular log monitoring will also help you catch any unusual activity or issues early.
In addition to log management, regularly back up your configuration files and any customizations you've made. This practice is essential for preventing data loss and ensuring you can quickly restore data in case of failure or misconfiguration.
Health Check
Health checks monitor the service's status and availability by exposing endpoints that return the current state of the service. These checks ensure the service is running properly and can differentiate between overall service availability (liveness) and its readiness to handle requests (readiness).
PAA Helm
By default, the management port configured is 9090.
management:
port: ${MANAGEMENT_PORT:9090}
# if the management endpoint path needs to be changed from the default /health:
# prefix: ${MANAGEMENT_PREFIX:/probes}
The probe endpoints are:
Liveness:
http://<IDP_HOOK_HOST>:9090/health
http://<IDP_HOOK_HOST>:9090/health/liveness
Readiness:
-http://<IDP_HOOK_HOST>:9090/health/readiness
PAA Standalone
By default, the management port configured is 8021.
management:
port: ${IDP_HOOK_MANAGEMENT_PORT:8021}
# if the management endpoint path needs to be changed from the default /health:
# prefix: ${IDP_HOOK_MANAGEMENT_PREFIX:/probes}
The probe endpoints are:
Liveness:
-http://<IDP_HOOK_HOST>:8021/health
-http://<IDP_HOOK_HOST>:8021/health/liveness
Readiness:
http://<IDP_HOOK_HOST>:8021/health/readiness
Logging
Logging is essential for monitoring service behavior and diagnosing issues. It provides detailed insights at various levels (trace, debug, info, warn, error, fatal), which helps track events and troubleshoot efficiently.
The service uses structured logging with configurable levels and formats.
- Supported log levels:
- trace
- debug
- info
- warn
- error
- fatal
- Formats:
- JSON
- Text
Configure logging in the log
section of the configuration file or use environment variables:
log:
level: ${IDP_HOOK_LOG_LEVEL:debug} # possible values: trace, debug, info, warn, warning, error, fatal, panic
format: ${IDP_HOOK_LOG_FORMAT:json} # possible values: json, text
logTo: ${IDP_HOOK_LOG_TO:console} # possible values: console, file, rolling
Log Rotation
The IDP Token Enrichment Service supports log rotation to manage log file sizes and maintain a history of log files. Log rotation is handled automatically by the service's logging framework. To enable it, set log.logTo
to log.logTo: rolling.