On-premises prerequisites
Prepare your environment before you run the self-hosted Permit Platform installer. This page is for the operator who sets up the cluster. When every item in the verification checklist passes, continue to the installation guide.
The on-premises installer is available to Enterprise customers with an on-premises license. To get a license, contact Permit.io.
Requirements at a glance
| Requirement | Details |
|---|---|
| Cluster | Kubernetes 1.21 or later, or Red Hat OpenShift 4.8 or later, sized as described in Cluster sizing |
| Tools | kubectl and Helm 3.8 or later, plus oc for OpenShift and docker to push images |
| Permissions | Rights to create namespaces, deployments, ingress resources, and persistent volume claims |
| Storage | A storage class with dynamic provisioning |
| Container registry | A registry the cluster can pull from, unless you use the OpenShift internal registry |
| Git | A policy repository and an SSH deploy key with write access |
| Network | A frontend domain and inbound access on ports 80 and 443 |
Cluster sizing
Node and cluster sizes
| Deployment | Nodes | CPU per node | RAM per node | Storage per node | Network |
|---|---|---|---|---|---|
| Development, testing, or proof of concept | 1 | 8 cores | 32 GB | 100 GB | 1 Gbps |
| Production | 4 or more | 4 cores | 16 GB | 50 GB, plus shared storage | 1 Gbps |
| High-availability production | 6 or more | 8 cores | 32 GB | 200 GB | 10 Gbps |
OpenSearch and Keycloak run on the Java virtual machine (JVM), so plan node memory for both. Decision logs in OpenSearch and data in PostgreSQL grow over time, so monitor volume usage after installation.
Example node types
| Provider | 4 vCPU, 16 GB node | 8 vCPU, 32 GB node | Storage |
|---|---|---|---|
| AWS (EKS, Red Hat OpenShift Service on AWS) | m5.xlarge | m5.2xlarge | gp3 SSD volumes, for example the gp3-csi storage class on ROSA |
| Google Cloud (Google Kubernetes Engine, GKE) | e2-standard-4 | e2-standard-8 | SSD persistent disks, for example the premium-rwo storage class |
| Azure (AKS) | Standard_D4s_v3 | Standard_D8s_v3 | Premium SSD managed disks |
| OpenShift Container Platform (OCP) on VMware vSphere or bare metal | 4 vCPU, 16 GB | 8 vCPU, 32 GB | Local SSD or storage area network (SAN) storage with a Container Storage Interface (CSI) driver |
Supported platforms
| Platform | Versions and variants |
|---|---|
| Kubernetes | Any Cloud Native Computing Foundation (CNCF) certified Kubernetes 1.21 or later: Amazon EKS, Google GKE, Azure AKS, or a kubeadm cluster |
| Red Hat OpenShift | 4.8 or later: OpenShift Container Platform (OCP), Red Hat OpenShift Service on AWS (ROSA), or OpenShift Dedicated |
| Kind | Local development and testing only |
Install the command-line tools
The installer checks for the tools it needs for the target you choose and exits with a list of the missing ones.
| Target | Required on your workstation |
|---|---|
| Kubernetes (EKS, AKS, self-managed) | kubectl, helm, and docker to push images to your registry |
| Google GKE | gcloud, kubectl, helm, and docker to push images to Artifact Registry |
| Red Hat OpenShift | oc, kubectl, and helm |
| Kind | docker, kind, kubectl, and helm |
Use Helm 3.8 or later. For Kind and OpenShift, the installer generates certificates with mkcert when it is installed, and with OpenSSL otherwise.
Prepare cluster access
Kubernetes cluster access
For Amazon EKS, Google GKE, Azure AKS, or a self-managed Kubernetes cluster, your kubectl context needs cluster admin access, or role-based access control (RBAC) permissions to:
- Create namespaces. The default namespace is
permit-platform. - Create deployments, services, secrets, and ingress resources.
- Create persistent volume claims.
The installer deploys to the cluster in your current kubectl context. Check access, permissions, and tools:
# Check Kubernetes access
kubectl cluster-info
kubectl get nodes
# Verify permissions
kubectl auth can-i create namespace
kubectl auth can-i create deployment
kubectl auth can-i create ingress
# Check storage
kubectl get storageclass
# Verify Docker
docker --version
docker system info
# Check Helm
helm version
Each kubectl auth can-i command prints yes. kubectl get storageclass lists at least one class, and helm version reports version 3.8 or later.
Google GKE access
- Install the Google Cloud SDK:
# macOS
brew install --cask google-cloud-sdk
# Linux
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
# Verify installation
gcloud --version
- Sign in, select the project, and get the cluster credentials:
# Authenticate with Google Cloud
gcloud auth login
# Set your project
gcloud config set project YOUR_PROJECT_ID
# Get cluster credentials
gcloud container clusters get-credentials YOUR_CLUSTER_NAME \
--zone us-central1-a \
--project YOUR_PROJECT_ID
# Verify cluster access
kubectl cluster-info
kubectl get nodes
Your Google Cloud account needs the roles/container.admin and roles/artifactregistry.writer roles, or these permissions:
container.clusters.getcontainer.clusters.updateartifactregistry.repositories.uploadArtifactsartifactregistry.repositories.downloadArtifacts
The installer does not install an ingress controller on GKE. The Helm chart creates its ingress with the nginx class (ingress.className in values.yaml), so install the NGINX ingress controller in the cluster, or set ingress.className to the controller you use. The Artifact Registry repository for the images is created during installation, in Push the images to your container registry.
OpenShift cluster access
For Red Hat OpenShift, your oc login needs cluster admin access, or permissions to:
- Create projects. The default project is
permit-platform. - Create deployments and routes or ingress resources.
- Create persistent volume claims.
- Grant the
anyuidsecurity context constraint (SCC). The installer grantsanyuidto the namespace's default service account, which OpenSearch needs.
The installer exits if oc whoami fails, so sign in with oc login first. Check access, permissions, and tools:
# Check OpenShift cluster access
oc cluster-info
oc get nodes
oc whoami
# Verify permissions
oc auth can-i create project
oc auth can-i create deployment
oc auth can-i create route
# Check storage classes
oc get storageclass
# Verify SCC access (required for database containers)
oc get scc anyuid
oc adm policy who-can use scc anyuid
# Check tools
oc version
docker --version
helm version
# Test project creation (cleanup after test)
oc new-project permit-test-validation
oc delete project permit-test-validation
Each oc auth can-i command prints yes, and oc get scc anyuid returns the constraint.
Set up the Git repository for Policy Sync
Policy Sync stores and syncs your policies in a Git repository over SSH. The installer requires a repository URL and an SSH private key, and exits if either placeholder in values.yaml is not replaced.
1. Create an SSH key pair
# Generate SSH key for policy repository access
ssh-keygen -t rsa -b 4096 -f permit-policy-key -N ""
# This creates:
# permit-policy-key (private key - keep secure)
# permit-policy-key.pub (public key - add to Git repository)
# Set correct permissions
chmod 600 permit-policy-key
The command creates permit-policy-key (the private key, which goes into values.yaml) and permit-policy-key.pub (the public key, which goes into the Git platform).
2. Add the public key as a deploy key
- GitHub
- GitLab
- Bitbucket
- In the repository, open Settings > Deploy keys.
- Click Add deploy key.
- Paste the contents of
permit-policy-key.pub. - Select Allow write access. Policy Sync needs write access to the repository.
- Click Add key.
- In the project, open Settings > Repository > Deploy Keys.
- Click Add new key.
- Paste the contents of
permit-policy-key.pub. - Select Grant write permissions to this key. Policy Sync needs write access to the repository.
- Click Add key.
- In the repository, open Settings > Access keys.
- Click Add key.
- Paste the contents of
permit-policy-key.pub. - Click Add SSH key.
3. Test Git access
# Test SSH connection (replace with your Git platform)
ssh -T git@github.com -i ./permit-policy-key
# Expected response:
# "Hi username/repository! You've successfully authenticated, but GitHub does not provide shell access."
A greeting with your repository name confirms that the key works.
Values to keep for installation
| Value | Example | Goes into |
|---|---|---|
| Repository SSH URL | git@github.com:yourorg/permit-policies.git | permitServices.policySync.policyRepoUrl |
| Private key | Contents of permit-policy-key | permitServices.policySync.sshPrivateKey |
Plan network access
External ports
| Port | Protocol | Purpose | Required |
|---|---|---|---|
| 80 | HTTP | Web traffic to the frontend domain | Yes |
| 443 | HTTPS | Web traffic to the frontend domain | Yes |
| 6443 | Kubernetes API | Cluster management from outside the cluster | Only if you manage the cluster remotely |
On hosts that filter traffic with iptables, allow the ports:
# Web traffic (required)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Kubernetes API (if managing cluster externally)
iptables -A INPUT -p tcp --dport 6443 -j ACCEPT
Internal service ports
The platform services use these ports inside the namespace. Kubernetes services route them, so open them only if you apply network policies:
| Port | Service |
|---|---|
| 5432 | PostgreSQL, the read replica, PgBouncer, and the Keycloak database |
| 6379 | Redis |
| 5672, 15672 | RabbitMQ: Advanced Message Queuing Protocol (AMQP) and the management UI |
| 9200, 9300 | OpenSearch |
| 5601 | OpenSearch Dashboards |
| 7002 | OPAL server (Open Policy Administration Layer) |
| 8000 | Permit backend and internal API services |
| 8080 | Keycloak |
| 8181 | Open Policy Agent (OPA) |
DNS
- Production: create a DNS record that points the frontend domain at your ingress or load balancer.
- Development: use a
.localdomain and add it to the hosts file on the machine that runs the browser.
The installation guide shows both in Point the frontend domain at the cluster.
Plan storage
The platform stores data in persistent volumes for PostgreSQL, the PostgreSQL read replica, the Keycloak database, OpenSearch, RabbitMQ, and Redis. The cluster needs a storage class that provisions volumes dynamically.
| Service | Storage recommendation |
|---|---|
| PostgreSQL | SSD with 3000 or more input/output operations per second (IOPS) |
| OpenSearch | NVMe SSD |
| Redis | SSD |
The installer package sets each volume size in charts/permit-platform/values.yaml under thirdPartyServices.<service>.persistence.size. Check the sizes there before you provision storage, and reserve extra space for backups and snapshots.
Check that a default storage class exists:
# Check available storage classes
kubectl get storageclass
# Should show something like:
# NAME PROVISIONER AGE
# standard (default) k8s.io/minikube-hostpath 1h
One class shows (default) after its name.
Choose how to handle TLS
Decide before installation how the frontend domain gets its certificate:
- Self-signed certificates that the installer generates with
--generate-tls. - Your own certificate from your certificate authority, set in
values.yaml. - TLS terminated outside the cluster, for example at a load balancer or with cert-manager, with
--skip-tls-check.
Configure TLS certificates in the installation guide describes each option.
Fix common prerequisite problems
kubectl can't reach the cluster
Point kubectl at your kubeconfig file and test the connection:
# If kubectl not configured:
export KUBECONFIG=/path/to/your/kubeconfig
# Test cluster connectivity
kubectl cluster-info
No storage class exists
For a development cluster, create a default storage class:
# Create a simple storage class (development only)
kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
EOF
The kubernetes.io/no-provisioner class does not create volumes. Create a PersistentVolume for each claim manually, or the database pods stay Pending. Use a dynamic provisioner for production.
Docker commands fail with a permission error
Add your user to the docker group, then sign out and back in:
# Add user to docker group (requires logout/login)
sudo usermod -aG docker $USER
# Or use sudo with docker commands
sudo docker --version
Verification checklist
Before you install, confirm each item:
-
kubectl cluster-info(oroc cluster-info) reaches the cluster. - You can create namespaces, deployments, and ingress resources.
- A default storage class exists.
- Helm 3.8 or later is installed.
- Docker runs on your workstation, if you push images to a registry.
- A container registry is ready, unless you use the OpenShift internal registry.
- The frontend domain is chosen, and DNS or a hosts file entry is planned.
- The policy Git repository exists, and
ssh -Tsucceeds with the deploy key. - You know how the frontend domain gets its TLS certificate.
Next steps
- Install the platform with the installation guide.
- Follow the on-premises quick start for a default installation.
- Troubleshoot the on-premises platform.
For help with prerequisites, email support@permit.io or ask in the Permit community on Slack.