Managing the IDP Token Enrichment Service
    • 28 Oct 2024
    • 14 Minutes to read
    • Dark
      Light
    • PDF

    Managing the IDP Token Enrichment Service

    • Dark
      Light
    • PDF

    Article summary

    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

    image.png

    1. User requests to log into the Online Bank Portal.
    2. The organization's Online Bank Portal application receives the login requests and sends a query to the IDP.
    3. The IDP sends a query to the PlainID IDP Token Enrichment Service
    4. The PDP calculates the decision.
    5. 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.
    6. 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)
    • 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)
    Note

    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:

    Note

    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

    1. Download the Helm package for the relevant PAA.
    2. 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.
    3. 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.
    4. Copy the idpWebhook section to your custom-values.yaml
    5. To enable the IDP Token Enrichment Service, set the idpWebhook: enabled: flag to true.
    6. Configure additional service operations as needed (refer to the Additional Configurations section).
    7. Configure your IDP applications in the relevant section.

    Standalone Deployment

    1. Download the Standalone package for the relevant PAA.
    2. To enable the IDP Token Enrichment Service:
      1. Locate and open the plainid/init/aliases file.
      2. Locate the function start_plainid_paa() { and function stop_plainid_paa() { functions.
      3. Append start_idp-webhook and stop_idp-webhook to the end of the relevant sections.
    3. 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

    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

    KeyNameRequiredDescriptionValue ExamplesDefaultVendor-specific Required Parameters
    http.portYesThe port that the IDP Token Enrichment service listens to50018080--
    server.nameYesName of the serveridp-hookidp-webhook--
    server.auth.secretNoThis secret is used to allow the IDP to authenticate with the IDP Token Enrichment Service endpoint------
    runtime.hostYesBase URL of the PDP in your PAA------
    runtime.uriYesStatic value of the PDP endpoint used for token enrichment/api/runtime/token/v3----
    runtime.timeoutNoTimeout for PDP Runtime requests3s----
    runtime.ignoreSSLNoFlag to ignore SSL certificate validationfalsefalse--
    log.formatNoLog formattext / json (for structured logging)text--
    log.levelNoLog leveltrace, debug, info, warn, warning, error, fatal, panicinfo--
    log.logToNoLog destinationconsole / file / rollingconsole--
    log.filePathYes, if log.logTo has any of values: file, rollingLog file location/opt/plainid/logs/idpwebhook.log----
    log.maxSizeNoMaxSize is the maximum size in megabytes of the log file before it gets rotated.10100MB--
    log.maxAgeNoMaxAge is the maximum number of days to retain old log files based on the timestamp encoded in their filename.14The default is not to remove old log files based on age.--
    log.maxBackupsNoMaxBackups is the maximum number of old log files to retain.5The default is to retain all old log files (though MaxAge may still cause them to get deleted)--
    log.localTimeNoLocalTime is the local time zone.true, false (use UTC time)false--
    log.compressNoCompress determines if the rotated log files should be compressed using gzip.true, false (not to perform compression)false--
    management.portYesPort for management endpoint80818081--

    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.

    KeyNameRequiredDescriptionValue ExamplesDefaultVendor-specific Required Parameters
    apps.<app>YesThe IDP Application name - must be an exact match and unique------
    apps.<app>.clientidNoThe PlainID Scope Client IDPSIG6O4TLVZ6EJZRZJKT--Required for:
    - Entra ID
    apps.<app>.clientsecretNoThe PlainID Scope Client Secret----Required for:
    - Entra ID
    apps.<app>.entitytypeYesThe Identity Type which will be used for the authorization calculation in PDPUser, employees etc.

    Or any Identity Template ID defined in PlainID and used for the integration.
    User--
    apps.<app>.useridNoThe JSON path to the user ID in the IDP request$.Data.AuthenticationContext.User.UserPrincipalName--Required for:
    - Entra ID
    apps.<app>.claimsYesList of claims and the corresponding JSON Path mappings from the PlainID PDP Responseplainid: $.response[*].access[?(@.resourceType == "accounts")].path

    See a full example in the Mapping the PlainID Policy Decision Response to Claims section below.
    --
    apps.<app>.includeidentityNoIndicate to the PDP whether to include the Identity Attributes in the responsetrue
    false
    false--
    apps.<app>.resourcetypesNoResource 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>.parseResponseTypeNoSwitches to key value format in claims.jsonpath / cloud (used for claims key value pairs in full cloud integration when applicable)jsonpath--
    apps.<app>.tokentypeNoUsed in claim parsing logic of Okta IDPidentity, access--Required for:
    - Okta
    apps.<app>.paramsNoAdditional params used for Okta IDP----Required for:
    - Okta
    apps.<app>.idTokenNoContains configurations needed for OIDC Token Verification.----Required for:
    - Entra ID
    apps.<app>.idToken.verifyNoEnable OIDC token verificationtrue, falsefalseRequired for:
    - Entra ID
    apps.<app>.skipClientIDCheck
    NoSkip JWT Audience (ClientID in OIDC terms) check (for testing purposes)true, falsefalseRequired for:
    - Entra ID
    apps.<app>.skipIssuerCheckNoJWT Issuer check skip (for testing purposes)true, falsefalse--
    apps.<app>.idToken.issYes, only if the idToken.verify is set to trueJWT Issuerhttps://login.microsoftonline.com/c179854f-7b57-4eee-abb2-b34cbcf0626e/v2.0--Required for:
    - Entra ID
    apps.<app>.idToken.audYes, only if the idToken.verify is set to trueJWT Audiencefe88b193-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.

    Environment Variables Format

    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:

    ExpressionDescription
    $.response[*].access[?(@.resourceType == "ProfileInformation")].attributes.BUGet the Business Unit (BU) code from the ProfileInformation Assets included in the PDP Response
    $.response[*].access[?(@.resourceType == "Accounts")].pathGet 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_roleGet 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.


    Was this article helpful?

    What's Next