---
title: "PDP"
slug: "pdp-1"
status: "update"
updated: 2026-03-16T10:31:12Z
published: 2026-03-22T16:24:27Z
canonical: "docs.plainid.io/pdp-1"
---

> ## 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.

# PDP

The **Policy Decision Point (PDP)** is the core Runtime component responsible for evaluating access requests against your configured Policies. It acts as the decision engine in the PlainID architecture, processing identity, resource, and contextual information to determine authorization outcomes.

You can consume this service as a Cloud or deployed as your PAA. 

:::(Internal) (Private notes)
For more information on how to deploy and manage the service refer to the following:


For more information on the Cloud Service refer to the following:
Dev Guide links


include below above 
The PDP includes the following modes:
:::



- **Cloud PDP**: Fully managed and hosted by PlainID.
- **PAA PDP**: Deployed as part of a self-managed PAA. 

Regardless of deployment, PDP behavior remains consistent to ensure scalable, policy-driven access decisions.

This service includes a flexible configuration structure that allows you to control service behavior and optimize performance. While the default values are typically sufficient, certain use cases may benefit from customized configuration.

In Standalone PAA deployments, you can edit the JSON configuration file directly. In Kubernetes-based PAA deployments, you can inject a complete configuration map. However, the recommended method for managing configuration updates is through **Environment Variables**.

The Runtime service supports overriding any configuration key by using a naming convention in the `extraEnv` section of your [values.yaml](/v1/docs/valuesyaml-file). Place your custom values in [values-custom.yaml](/v1/docs/sample-values-customyaml-file) to apply changes without editing the base file.

Refer to the following sections for more information:
- [Environment Variable Convention](#environment-variables-convention)
- [Common Keys](#common-keys)
- [Optimizing PDP Redis Utilization](#optimizing-pdp-redis-utilization)
- [Enabling SSL for Runtime](/docs/enabling-ssl-for-runtime)
- [Logging Environment Variable Overrides](#logging-environment-variable-overrides)


---

### Environment Variable Convention

#### Prefix, Hierarchy, and Examples
**Prefix**

All Environment Variables must begin with the prefix: `RTCONF_`

**Hierarchy**

Use a double underscore (`__`) to separate hierarchy levels in the configuration structure. For array-based configurations, include the array index using the same syntax.

> *Use a single underscore (`_`) to separate words within a configuration key.*


**Examples**
The following table demonstrates the naming convention and hierarchical structure for ENV_VARs. 

| Config Key                   | The config key full JSON Path           | ENV_VAR                                         |
| ---------------------------- | --------------------------------------- | ----------------------------------------------- |
| refreshAssetTemplates (root) | $.refreshAssetTemplates                 | `RTCONF_REFRESH_ASSET_TEMPLATES`               |
| isSysLogEnable (audit)       | $.audit.isSysLogEnable                  | `RTCONF_AUDIT__IS_SYSLOG_ENABLE`               |
| isHttps (ssl)                | $.ssl.isHttps                           | `RTCONF_SSL__IS_HTTPS`                         |
| type (asset provider)        | $.assetProvider.connection.type         | `RTCONF_ASSET_PROVIDERS__0__CONNECTION__TYPE`  |
| serviceMgmtPort              | $.serviceMgmtPort                       | `RTCONF_SERVICE_MGMT_PORT`                     |

*Note: Ensure that the serviceMgmtPort is set to 80 (default)*   

:::(Info) (Separating Management and Application Ports)
When enabling SSL (`isHttps=true`), it's important to separate the management and application ports due to differences in how TLS validation behaves across endpoints. By default, both `httpPort` and `serviceMgmtPort` use port 8010, which works in both Kubernetes and Standalone modes.

To avoid conflicts or unexpected behavior—especially in environments with strict TLS validation—configure `serviceMgmtPort` to be distinct from `httpPort`. In Kubernetes, you can also override the health check ports independently to ensure proper probe functionality.
:::

### Common Keys

Below are key Runtime settings you may want to fine-tune. For help with advanced configurations, contact **PlainID Professional Services**.

| Config Key                                                  | JSON Path                                                                                      | Default | ENV_VAR                                                  |  
|-------------------------------------------------------------|--------------------------------------------------------------------------------------------------|---------|----------------------------------------------------------|  
| Service Port                                                | `$.httpPort`                                                                                   | `8010`  | `RTCONF_HTTP_PORT`                                       |  
| Enable Identity PIP traceability                            | `$.useIdentityPipSqlTraceability`                                                              | `true`  | `RTCONF_USE_IDENTITY_PIP_SQL_TRACEABILITY`               |  
| Max PIP Assets connection pool size                         | `$.assetProviders[0].connection.jdbcMaxPoolSize`                                               | `20`    | `RTCONF_ASSET_PROVIDERS__0__CONNECTION__JDBC_MAX_POOL_SIZE`   |  
| Min PIP Assets connection pool size                         | `$.assetProviders[0].connection.jdbcMinPoolSize`                                               | `5`     | `RTCONF_ASSET_PROVIDERS__0__CONNECTION__JDBC_MIN_POOL_SIZE`   |  
| PIP Assets query timeout (seconds)                          | `$.assetProviders[0].connection.queryTimeoutInSeconds`                                         | `25`    | `RTCONF_ASSET_PROVIDERS__0__CONNECTION__QUERY_TIMEOUT_IN_SECONDS` |  
| Asset provider instance count                               | `$.assetProviders[0].count`                                                                    | `20`    | `RTCONF_ASSET_PROVIDERS__0__COUNT`                        |  
| Asset provider thread pool size                             | `$.assetProviders[0].workerPool`                                                               | `20`    | `RTCONF_ASSET_PROVIDERS__0__WORKER_POOL` <br><br>**Note**: For Identity providers, use `ENTITY_PROVIDERS` instead of `ASSET_PROVIDERS`. |  
| Enable audit logging to DB                                  | `$.audit.isDataBaseEnable`                                                                     | `false` | `RTCONF_AUDIT__IS_DATABASE_ENABLE`                        |  
| DB driver for audit logging                                 | `$.audit.connection.driverName`                                                                |         | `RTCONF_AUDIT__CONNECTION__DRIVER_NAME`                  |  
| DB connection URL for audit                                 | `$.audit.connection.url`                                                                       |         | `RTCONF_AUDIT__CONNECTION__URL`                          |  
| DB user for audit logging                                   | `$.audit.connection.user`                                                                      |         | `RTCONF_AUDIT__CONNECTION__USER`                         |  
| DB password for audit logging                               | `$.audit.connection.password`                                                                  |         | `RTCONF_AUDIT__CONNECTION__PASSWORD` <br><br>**Note**: For secret-based credentials, refer to the [Secret Management Configuration](/v1/docs/secret-management-configuration) guide. Supports AWS RDS IAM tokens with the following syntax:<br>`|-`<br>&nbsp;&nbsp;`{{store=AWS_RDS_IAM_AUTH_STORE,key=test_user@...}}` |  
| Max identities returned in user list                        | `$.identityAgentLimit`                                                                         | `1000`  | `RTCONF_IDENTITY_AGENT_LIMIT`                             |  
| Metrics refresh interval                                    | `$.runtimeRefreshSnapshot`                                                                     | `60000` | `RTCONF_RUNTIME_REFRESH_SNAPSHOT`                        |

---

### Optimizing PDP Redis Utilization

The PDP uses Redis to cache metadata, identity records, and responses. To reduce latency and minimize Redis load, the PDP stores metadata locally in its internal cache. The following Environment Variables let you fine-tune this behavior:

| Configuration Key                 | Default Value | Description                                                                                                                                         |
|----------------------------------|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
| `SHOULD_READ_FROM_CACHE_BEFORE_DB` | `false`        | When set to `true`, the PDP uses prefetched data from its internal cache instead of Redis. Reduces Redis calls during authorization processing.    |
| `SCOPE_SETTINGS_COOLDOWN_SECONDS`  | `60`           | Defines how often (in seconds) the PDP refreshes metadata from Redis when internal caching is enabled.                                             |

:::(Info) (Important Note)
When caching is enabled (`SHOULD_READ_FROM_CACHE_BEFORE_DB=true`), metadata changes in PAP will not reflect immediately in PAA. The delay is controlled by `SCOPE_SETTINGS_COOLDOWN_SECONDS`.
:::


---

The PDP includes detailed logging for observability and performance diagnostics. Logs cover:

- Configuration overrides via Environment Variables
- Request lifecycle, including start and completion
- Authorization flow (with debug-level detail)
- Request durations and errors



### JWKs Retrieval and Refresh Behavior

The PDP retrieves public keys from the configured **JWKS endpoints** to validate JWT tokens used in authorization flows. These JWKS URLs are defined in **Scopes** and **Identity Templates**.

To ensure continued validity of token verification, the PDP periodically refreshes the keys from the configured JWKS sources. If a refresh attempt fails, the PDP continues using the **most recently successfully loaded keys** and retries the refresh according to its retry policy. The only exception is the **initial load**, where no keys are available yet. If that attempt fails, JWT validation cannot proceed until a successful load occurs.



#### JWKs Runtime Load Lifecycle and Load Failures

INFO-level logs are emitted for JWKs Runtime load activity.  
When a JWKs load attempt fails, the failure is logged.

| JWKs Runtime State | Log Level | Description | Example Log Message |
|-------------------|----------|-------------|---------------------|
| **LOADING** | INFO | - A JWKs load attempt has started. | - `starting #4 attempt to load JWKs from url:{...}, sourceInfo: identityTemplateId:{...}, name:{...}` |
| **LOADED** | INFO | - JWKs were loaded successfully from a URL.<br>- JWKs were loaded successfully after multiple attempts. | - `JWKs url were loaded successfully, sourceInfo: identityTemplateId:{...}, name:{...}, url:{...}`<br>- `JWKs url were loaded successfully, sourceInfo: scopeId:{...}, client_id:{...}, url:{...}`<br>- `JWKs were loaded successfully from url:{...} after {...} attempts` |
| **FAILED_LOAD** | WARN | - A JWKs load attempt failed. | - `JWKs load failed from url:{...} on attempt #3, sourceInfo: identityTemplateId:{...}, name:{...}` |
| **FAILED_LOAD** | ERROR | - A JWKs load attempt failed and no keys are available.<br>- A JWKs load attempt failed and existing keys continue to be used.<br>- JWKs keys were not updated for 24 hours. | - `JWKs load failed from url:{...}, sourceInfo: identityTemplateId:{...}, name:{...}, No keys loaded yet`<br>- `JWKs load failed from url:{...}, sourceInfo: identityTemplateId:{...}, name:{...}, Continue using existing keys`<br>- `JWKs keys from url:{...} were not updated for 24 hours` |
| **FAILED_LOAD** | INFO | - JWKs URL load failed.<br>- A retry for loading JWKs has been scheduled. | - `JWKs url load failed`<br>- `scheduling next JWKs load retry in 15000 ms for url:{...}, sourceInfo: identityTemplateId:{...}, name:{...}, retryTimerId:{...}` |

---


:::(Info) (Request Duration)
Request duration logs include timing information per service component (e.g., pip-operator). This helps in measuring and tuning performance.

Example:
```json
"duration": 2,
"type": "pip-operator"
````

Duration logging is enabled by default. To disable it, set `RTCONF_DETAILED_DURATIONS_LOGGING=false` in [values-custom.yaml](/v1/docs/sample-values-customyaml-file).
:::

---

:::(Internal) (Private notes)

#### Configuring Redis Caching in PlainID

To further optimize Redis usage, PlainID provides a runtime API for refreshing Redis scope metadata:

**POST** `/api/2.0/runtime/refresh-scope`

**Parameters**

| Parameter | Description                                                                                                             |
| --------- | ----------------------------------------------------------------------------------------------------------------------- |
| `paaID`   | The unique ID of the PAA. Available in Tenant or Environment Settings under the **Policy Authorization Point** section. |

**Responses**

| Type    | Status Code | Body                                                     |
| ------- | ----------- | -------------------------------------------------------- |
| Success | 200 OK      | Scope policies and settings refreshed successfully       |
| Error   | 429         | Too many requests. Please try again later.               |
| Error   | 500         | Internal server error. Failed to refresh scope metadata. |

:::

---


## Logging Environment Variable Overrides

Any Environment Variable override is logged by the Runtime service. These entries appear at the `Info` level and follow this format:

```

config.json key <key-name> was overridden by <env-var-name> environment variable

````

Errors and validation issues related to Environment Variable syntax are also logged for easier troubleshooting.

---

#### Runtime Service Health Check

The Runtime Service GET request retrieves the PAA's runtime service health status. 
:::(Internal) (Private notes)
add link to general health monitoring section in PAA
:::
**K8:** 

:::(Info) (GET    `http://plainid-paa-runtime/api/runtime_health_check` )
:::

**Standalone:** 
:::(Info) (GET    `http://<runtime_address>:<runtime_management_port>/api/runtime_health_check` )
:::

Authorization 
- None 

Header 
- None 

**Standalone Parameters**
| Parameter | Value |
| --- | --- |
|<runtime_address> | Standalone - Server host name |
| <runtime_management_port> | 8010 (Standalone Service - default internal runtime port) |

**Service Response:**

```json
{
  "status": "UP",
  "details": {
    "redis": {
      "status": "UP",
      "details": {
        "read": {
          "status": "UP"
        },
        "write": {
          "status": "UP"
        }
      }
    }
  }
}

```

### Runtime Logging API

The Runtime Logger API allows you to inspect and adjust logging levels in the Runtime service without restarting it. This ensures faster troubleshooting and dynamic log visibility during debugging sessions.

::: (Warning) (Important)
Use low-level log settings only for temporary debugging; reset them for production stability.
:::
### Logging Configuration

Log level changes via the API reset when the Runtime restarts. To configure them permanently:

* Helm: `.Values.runtime.logLevel`
* Standalone: set Runtime Environment Variables directly.

### Authentication

**These APIs require JWT authentication with Tenant Admin permissions.**

::: (Info) (Security: Bearer Auth)
For more details, see [Authentication for Management APIs](https://docs.plainid.io/apidocs/authentication-mgmt-apis){target="\_blank"}.
Use your bearer token in the `Authorization` header:
`Authorization: Bearer 123`
:::

---

## PAA Logger Endpoints

**Retrieve loggers**

```http
GET https://api.{region}.plainid.io/pip-mgmt/1.0/monitor/loggers/runtime/{PAA_ID}
GET https://api.{region}.plainid.io/pip-mgmt/1.0/monitor/loggers/runtime/{PAA_ID}/{LOGGER_NAME}
```

**Example GET response (Runtime):**

```json
{
  "data": {
    "levels": ["OFF","TRACE","DEBUG","INFO","WARN","ERROR"],
    "loggers": {
      "com.plainid.runtime": {
        "configuredLevel": "INFO",
        "effectiveLevel": "INFO"
      },
      "root": {
        "configuredLevel": "ERROR",
        "effectiveLevel": "ERROR"
      }
    }
  }
}
```

**Response Fields**

| Parameter       | Type   | Description                                                       |
| --------------- | ------ | ----------------------------------------------------------------- |
| configuredLevel | string | The level set explicitly via configuration or API.                |
| effectiveLevel  | string | The actual level applied (may be inherited from a parent logger). |

---

**Modify log levels**

```http
POST https://api.{region}.plainid.io/pip-mgmt/1.0/monitor/loggers/runtime/{PAA_ID}/{LOGGER_NAME}
```

**Example Request**

```json
{
  "configuredLevel": "WARN"
}
```

**Example Response**

```json
{
  "data": {
    "configuredLevel": "WARN",
    "effectiveLevel": "WARN"
  }
}
```
