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.
- 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. Place your custom values in values-custom.yaml to apply changes without editing the base file.
Refer to the following sections for more information:
- Environment Variable Convention
- Common Keys
- Optimizing PDP Redis Utilization
- Enabling SSL for Runtime
- 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)
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 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 Note: For secret-based credentials, refer to the Secret Management Configuration guide. Supports AWS RDS IAM tokens with the following syntax: ` |
|
| 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. |
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. - JWKs were loaded successfully after multiple attempts. |
- JWKs url were loaded successfully, sourceInfo: identityTemplateId:{...}, name:{...}, url:{...}- JWKs url were loaded successfully, sourceInfo: scopeId:{...}, client_id:{...}, url:{...}- 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. - A JWKs load attempt failed and existing keys continue to be used. - JWKs keys were not updated for 24 hours. |
- JWKs load failed from url:{...}, sourceInfo: identityTemplateId:{...}, name:{...}, No keys loaded yet- JWKs load failed from url:{...}, sourceInfo: identityTemplateId:{...}, name:{...}, Continue using existing keys- JWKs keys from url:{...} were not updated for 24 hours |
| FAILED_LOAD | INFO | - JWKs URL load failed. - A retry for loading JWKs has been scheduled. |
- JWKs url load failed- scheduling next JWKs load retry in 15000 ms for url:{...}, sourceInfo: identityTemplateId:{...}, name:{...}, retryTimerId:{...} |
Request duration logs include timing information per service component (e.g., pip-operator). This helps in measuring and tuning performance.
Example:
"duration": 2,
"type": "pip-operator"
Duration logging is enabled by default. To disable it, set RTCONF_DETAILED_DURATIONS_LOGGING=false in values-custom.yaml.
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.
K8:
http://plainid-paa-runtime/api/runtime_health_checkStandalone:
http://<runtime_address>:<runtime_management_port>/api/runtime_health_checkAuthorization
- 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:
{
"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.
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.
For more details, see Authentication for Management APIs.
Use your bearer token in the Authorization header:
Authorization: Bearer 123
PAA Logger Endpoints
Retrieve loggers
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):
{
"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
POST https://api.{region}.plainid.io/pip-mgmt/1.0/monitor/loggers/runtime/{PAA_ID}/{LOGGER_NAME}
Example Request
{
"configuredLevel": "WARN"
}
Example Response
{
"data": {
"configuredLevel": "WARN",
"effectiveLevel": "WARN"
}
}