Skip to main content

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.

Enterprise on-premises license required

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

RequirementDetails
ClusterKubernetes 1.21 or later, or Red Hat OpenShift 4.8 or later, sized as described in Cluster sizing
Toolskubectl and Helm 3.8 or later, plus oc for OpenShift and docker to push images
PermissionsRights to create namespaces, deployments, ingress resources, and persistent volume claims
StorageA storage class with dynamic provisioning
Container registryA registry the cluster can pull from, unless you use the OpenShift internal registry
GitA policy repository and an SSH deploy key with write access
NetworkA frontend domain and inbound access on ports 80 and 443

Cluster sizing

Node and cluster sizes

DeploymentNodesCPU per nodeRAM per nodeStorage per nodeNetwork
Development, testing, or proof of concept18 cores32 GB100 GB1 Gbps
Production4 or more4 cores16 GB50 GB, plus shared storage1 Gbps
High-availability production6 or more8 cores32 GB200 GB10 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

Provider4 vCPU, 16 GB node8 vCPU, 32 GB nodeStorage
AWS (EKS, Red Hat OpenShift Service on AWS)m5.xlargem5.2xlargegp3 SSD volumes, for example the gp3-csi storage class on ROSA
Google Cloud (Google Kubernetes Engine, GKE)e2-standard-4e2-standard-8SSD persistent disks, for example the premium-rwo storage class
Azure (AKS)Standard_D4s_v3Standard_D8s_v3Premium SSD managed disks
OpenShift Container Platform (OCP) on VMware vSphere or bare metal4 vCPU, 16 GB8 vCPU, 32 GBLocal SSD or storage area network (SAN) storage with a Container Storage Interface (CSI) driver

Supported platforms

PlatformVersions and variants
KubernetesAny Cloud Native Computing Foundation (CNCF) certified Kubernetes 1.21 or later: Amazon EKS, Google GKE, Azure AKS, or a kubeadm cluster
Red Hat OpenShift4.8 or later: OpenShift Container Platform (OCP), Red Hat OpenShift Service on AWS (ROSA), or OpenShift Dedicated
KindLocal 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.

TargetRequired on your workstation
Kubernetes (EKS, AKS, self-managed)kubectl, helm, and docker to push images to your registry
Google GKEgcloud, kubectl, helm, and docker to push images to Artifact Registry
Red Hat OpenShiftoc, kubectl, and helm
Kinddocker, 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

  1. 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
  1. 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.get
  • container.clusters.update
  • artifactregistry.repositories.uploadArtifacts
  • artifactregistry.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 anyuid security context constraint (SCC). The installer grants anyuid to 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

  1. In the repository, open Settings > Deploy keys.
  2. Click Add deploy key.
  3. Paste the contents of permit-policy-key.pub.
  4. Select Allow write access. Policy Sync needs write access to the repository.
  5. Click Add 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

ValueExampleGoes into
Repository SSH URLgit@github.com:yourorg/permit-policies.gitpermitServices.policySync.policyRepoUrl
Private keyContents of permit-policy-keypermitServices.policySync.sshPrivateKey

Plan network access

External ports

PortProtocolPurposeRequired
80HTTPWeb traffic to the frontend domainYes
443HTTPSWeb traffic to the frontend domainYes
6443Kubernetes APICluster management from outside the clusterOnly 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:

PortService
5432PostgreSQL, the read replica, PgBouncer, and the Keycloak database
6379Redis
5672, 15672RabbitMQ: Advanced Message Queuing Protocol (AMQP) and the management UI
9200, 9300OpenSearch
5601OpenSearch Dashboards
7002OPAL server (Open Policy Administration Layer)
8000Permit backend and internal API services
8080Keycloak
8181Open Policy Agent (OPA)

DNS

  • Production: create a DNS record that points the frontend domain at your ingress or load balancer.
  • Development: use a .local domain 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.

ServiceStorage recommendation
PostgreSQLSSD with 3000 or more input/output operations per second (IOPS)
OpenSearchNVMe SSD
RedisSSD

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 (or oc 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 -T succeeds with the deploy key.
  • You know how the frontend domain gets its TLS certificate.

Next steps

For help with prerequisites, email support@permit.io or ask in the Permit community on Slack.