Skip to main content

Deploy a PDP in an On-Premises Cluster

This page is for operators of a self-hosted Permit Platform. It shows how to install a policy decision point (PDP) in the same Kubernetes cluster with the PDP Helm chart, connect the PDP to your Permit backend, and check that the PDP answers authorization requests. Your applications send authorization checks to the PDP instead of to the Permit backend.

Prerequisites

  • A running self-hosted Permit Platform. See the installation guide.
  • The permit-backend-v2 service running in the platform namespace. The commands on this page use the default namespace, permit-platform.
  • An environment API key from your self-hosted Permit frontend. The PDP uses the key to fetch the policies and data of that environment. See Get your API key for where the key is in the frontend.
  • Helm 3 and kubectl with access to the cluster.

Install the PDP

The PDP Helm chart is published in the permitio/PDP repository. The chart creates a permitio-pdp deployment and a permitio-pdp service.

Add the PDP Helm repository

helm repo add pdp https://permitio.github.io/PDP/
helm repo update

Install the chart

Replace <YOUR_API_TOKEN> with your environment API key. PDP_CONTROL_PLANE points the PDP at your self-hosted backend, http://permit-backend-v2:8000, instead of the Permit cloud.

On OpenShift, set openshift.enabled=true. The chart then creates the permitio-pdp-sa service account, binds it to the restricted-v2 Security Context Constraint (SCC), and runs the container as non-root with writable temporary volumes.

helm install pdp pdp/pdp \
--set openshift.enabled=true \
--set pdp.ApiKey="<YOUR_API_TOKEN>" \
--set "pdp.pdpEnvs[0].name=PDP_CONTROL_PLANE" \
--set "pdp.pdpEnvs[0].value=http://permit-backend-v2:8000" \
--namespace permit-platform

Chart parameters

ParameterDescriptionRequired
pdp.ApiKeyEnvironment API key. The chart stores it in a Kubernetes secret and passes it to the PDP as PDP_API_KEY.Yes
pdp.existingApiKeySecret.name, pdp.existingApiKeySecret.keyAn existing secret and key that hold the API key. When set, the chart doesn't create a secret.No
pdp.pdpEnvs[0].nameSet to PDP_CONTROL_PLANE.Yes
pdp.pdpEnvs[0].valueURL of your self-hosted backend service, http://permit-backend-v2:8000.Yes
openshift.enabledTurn on the OpenShift service account, SCC binding, and security context.Yes, on OpenShift
pdp.replicasNumber of PDP pods. Default: 1.No
resources.requests.cpu, resources.requests.memory, resources.limits.memoryCPU and memory for the PDP container. Defaults: 256m, 512Mi, and 1Gi.No
pdp.debug_modetrue sets PDP_DEBUG=true and turns on decision debug logging.No
pdp.portService port. Default: 7766. The service forwards to container port 7000.No

Verify the PDP

Check the pod status

kubectl get pods -n permit-platform | grep pdp

The PDP is running when the permitio-pdp pod shows 1/1 and Running:

permitio-pdp-7597689658-95ntd 1/1 Running 0 2m

Check the health endpoint

Forward the service port to your machine:

kubectl port-forward svc/permitio-pdp 7766:7766 -n permit-platform

In a second terminal, request the health endpoint:

curl http://localhost:7766/health

A healthy PDP returns HTTP 200 with "status": "ok". HTTP 503 with "status": "error" names the failing component. The health endpoint doesn't need an API key. The port-forward maps local port 7766 to the service, which forwards to container port 7000. Inside the pod, use port 7000. For the response format and the /healthy and /ready paths, see PDP health check endpoints.

Check the PDP logs

kubectl logs -f deployment/permitio-pdp -n permit-platform

Look for errors that mention the control plane URL or the API key. Errors on these lines mean the PDP can't fetch its policies. See PDP can't connect to the backend.

Send authorization requests to the PDP

Applications in the cluster reach the PDP at this address:

SettingValue
Service namepermitio-pdp
Port7766
Namespacepermit-platform
URL from the same namespacehttp://permitio-pdp:7766

Point the Permit SDK in your application at the PDP URL. The /allowed endpoint answers one permission check: can a user perform an action on a resource.

# Example authorization request
curl -X POST http://permitio-pdp:7766/allowed \
-H "Authorization: Bearer <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"user": {"key": "user@example.com"},
"action": "read",
"resource": {"type": "document", "key": "123", "tenant": "default"}
}'

The PDP expects user as an object with a key, and resource as an object with a type and an optional key and tenant. Send the environment API key in an Authorization: Bearer header. The PDP returns a JSON object whose allow field is true or false.

Advanced configuration

The examples in this section include openshift.enabled=true. On other Kubernetes distributions, remove that line. To change an existing release, run helm upgrade with --reuse-values instead of helm install, so Helm keeps the API key and control plane settings you already set.

Set CPU and memory

The chart reads CPU and memory from the top-level resources keys: resources.requests.cpu, resources.requests.memory, and resources.limits.memory.

helm install pdp pdp/pdp \
--set openshift.enabled=true \
--set pdp.ApiKey="<YOUR_API_TOKEN>" \
--set "pdp.pdpEnvs[0].name=PDP_CONTROL_PLANE" \
--set "pdp.pdpEnvs[0].value=http://permit-backend-v2:8000" \
--set resources.requests.cpu="512m" \
--set resources.requests.memory="1Gi" \
--set resources.limits.memory="2Gi" \
--namespace permit-platform

For sizing guidance, see System requirements and performance.

Run multiple replicas

Run more than one PDP pod so authorization checks continue when a pod restarts. The chart reads the replica count from pdp.replicas. When pdp.replicas is greater than 1, the chart also creates a PodDisruptionBudget with minAvailable: 1.

helm install pdp pdp/pdp \
--set openshift.enabled=true \
--set pdp.ApiKey="<YOUR_API_TOKEN>" \
--set "pdp.pdpEnvs[0].name=PDP_CONTROL_PLANE" \
--set "pdp.pdpEnvs[0].value=http://permit-backend-v2:8000" \
--set pdp.replicas=3 \
--namespace permit-platform

Add environment variables

Each entry in pdp.pdpEnvs becomes an environment variable on the PDP container. Keep PDP_CONTROL_PLANE at index 0 and add more variables at the next indexes. The example adds a second variable at index 1. For debug logging, set pdp.debug_mode=true, which sets PDP_DEBUG=true.

helm install pdp pdp/pdp \
--set openshift.enabled=true \
--set pdp.ApiKey="<YOUR_API_TOKEN>" \
--set "pdp.pdpEnvs[0].name=PDP_CONTROL_PLANE" \
--set "pdp.pdpEnvs[0].value=http://permit-backend-v2:8000" \
--set "pdp.pdpEnvs[1].name=PDP_LOG_LEVEL" \
--set "pdp.pdpEnvs[1].value=DEBUG" \
--namespace permit-platform

Troubleshooting

PDP can't connect to the backend

Symptom: The PDP logs show connection errors to the control plane, or the health endpoint returns 503.

  1. Check that the permit-backend-v2 service exists in the namespace:

    kubectl get svc permit-backend-v2 -n permit-platform
  2. Test the connection from the PDP pod to the backend:

    kubectl exec -it deployment/permitio-pdp -n permit-platform -- curl http://permit-backend-v2:8000/health

    If the PDP image has no curl, run the request from a temporary pod in the same namespace.

  3. Check the API key. The key must be an environment API key from your self-hosted Permit frontend. A key from another Permit instance doesn't work. To change the key, run helm upgrade pdp pdp/pdp --reuse-values --set pdp.ApiKey="<YOUR_API_TOKEN>" --namespace permit-platform.

OpenShift security context errors

Symptom: On OpenShift, the PDP pod isn't created, and the replica set events mention a Security Context Constraint.

  1. Check that the restricted-v2 SCC exists:

    oc get scc restricted-v2
  2. Check that the chart created the service account. The chart creates it only when openshift.enabled=true:

    kubectl get serviceaccount permitio-pdp-sa -n permit-platform

Pod pending or restarting for lack of resources

Symptom: The PDP pod stays Pending, or restarts with OOMKilled.

  1. Check the free capacity of the nodes:

    kubectl describe nodes
  2. Lower the memory request. --reuse-values keeps the API key and control plane settings. For a pod killed with OOMKilled, raise resources.limits.memory instead.

    helm upgrade pdp pdp/pdp \
    --reuse-values \
    --set resources.requests.memory="512Mi" \
    --namespace permit-platform

Next steps