Permify publishes an official chart here: Permify Helm Charts.
Requirements
- A Kubernetes cluster
kubectlconfigured for that cluster- Helm 3 installed (Helm install docs)
Add Permify Helm repository
Copy
helm repo add permify https://permify.github.io/helm-charts
helm repo update
helm search repo permify
Download and edit values.yaml
Before install, review and customize your chart values.
Copy
curl -o values.yaml https://raw.githubusercontent.com/Permify/helm-charts/main/charts/permify/values.yaml
Copy
helm show values permify/permify
- Deployment template: charts/permify/templates/deployment.yaml
- All chart templates: charts/permify/templates
Install and upgrade
Install with your customized values:Copy
helm install permify permify/permify -f values.yaml
Copy
helm upgrade permify permify/permify -f values.yaml
Copy
kubectl get deployments,pods,svc
Helm Chart Configuration
Before you install, configure yourvalues.yaml. The snippets below mirror the chart values and document each parameter inline.
Deployment and image settings
Copy
# replicaCount -- Number of Permify pods to run. Increase for high availability and throughput.
replicaCount: 3
image:
# image.repository -- Container image repository for Permify.
repository: ghcr.io/permify/permify
# image.pullPolicy -- Image pull behavior. Always checks for newer image at pod start.
pullPolicy: Always
# image.tag -- Image tag override. For this guide, Permify version 1.6.0 is used
tag: v1.6.0
Health checks
Copy
livenessProbe:
# livenessProbe.enabled -- Enable liveness checks. Failed checks trigger container restart.
enabled: true
# livenessProbe.initialDelaySeconds -- Delay before first liveness check.
initialDelaySeconds: 60
# livenessProbe.periodSeconds -- Frequency of liveness checks.
periodSeconds: 10
# livenessProbe.timeoutSeconds -- Timeout per liveness check.
timeoutSeconds: 5
# livenessProbe.failureThreshold -- Consecutive failures before restart.
failureThreshold: 12
# livenessProbe.successThreshold -- Consecutive successes needed to mark healthy.
successThreshold: 1
readinessProbe:
# readinessProbe.enabled -- Enable readiness checks. NotReady pods are removed from service endpoints.
enabled: true
# readinessProbe.initialDelaySeconds -- Delay before first readiness check.
initialDelaySeconds: 5
# readinessProbe.periodSeconds -- Frequency of readiness checks.
periodSeconds: 10
# readinessProbe.timeoutSeconds -- Timeout per readiness check.
timeoutSeconds: 5
# readinessProbe.failureThreshold -- Consecutive failures before pod is marked NotReady.
failureThreshold: 6
# readinessProbe.successThreshold -- Consecutive successes to mark Ready.
successThreshold: 1
startupProbe:
# startupProbe.enabled -- Enable startup checks for slower boot scenarios.
enabled: false
# startupProbe.initialDelaySeconds -- Delay before first startup check.
initialDelaySeconds: 60
# startupProbe.periodSeconds -- Frequency of startup checks.
periodSeconds: 10
# startupProbe.timeoutSeconds -- Timeout per startup check.
timeoutSeconds: 5
# startupProbe.failureThreshold -- Consecutive failures before restart during startup phase.
failureThreshold: 30
# startupProbe.successThreshold -- Consecutive successes needed to pass startup phase.
successThreshold: 1
# customLivenessProbe -- Full custom probe object. Overrides chart default liveness probe when set.
customLivenessProbe: {}
# customReadinessProbe -- Full custom probe object. Overrides chart default readiness probe when set.
customReadinessProbe: {}
# customStartupProbe -- Full custom probe object. Overrides chart default startup probe when set.
customStartupProbe: {}
Service and ingress
Copy
service:
# service.type -- Service exposure type: ClusterIP, NodePort, or LoadBalancer.
type: LoadBalancer
# service.annotations -- Annotations on Kubernetes Service resource.
annotations: {}
ingress:
# ingress.enabled -- Create ingress resources for external HTTP(S) access.
enabled: false
# ingress.className -- Ingress class to target (for example nginx).
className: ""
# ingress.annotations -- Ingress-controller-specific annotations.
annotations: {}
hosts:
- # ingress.hosts[].host -- Hostname routed to Permify service.
host: chart-example.local
paths:
- # ingress.hosts[].paths[].path -- URL path for route matching.
path: /
# ingress.hosts[].paths[].pathType -- Path matching mode (ImplementationSpecific, Prefix, Exact).
pathType: ImplementationSpecific
# ingress.tls -- TLS host/secret mappings for HTTPS termination.
tls: []
Permify application configuration (app)
Copy
app:
# app.account_id -- Optional account identifier for runtime/account-scoped behavior.
account_id: ""
server:
# app.server.rate_limit -- Server request rate limit.
rate_limit: 100_000
http:
# app.server.http.enabled -- Enable HTTP API listener.
enabled: true
# app.server.http.port -- HTTP listener port.
port: 3476
tls:
# app.server.http.tls.enabled -- Enable TLS for HTTP endpoint.
enabled: false
grpc:
# app.server.grpc.port -- gRPC listener port.
port: 3478
tls:
# app.server.grpc.tls.enabled -- Enable TLS for gRPC endpoint.
enabled: false
logger:
# app.logger.level -- Log verbosity (error, warn, info, debug).
level: info
profiler:
# app.profiler.enabled -- Enable pprof profiling endpoint.
enabled: true
# app.profiler.port -- pprof server port.
port: 6060
authn:
# app.authn.enabled -- Enable API authentication.
enabled: false
# app.authn.method -- Authentication method (for example preshared).
method: preshared
preshared:
# app.authn.preshared.keys_secret -- Optional secret reference for preshared keys.
# keys_secret:
# app.authn.preshared.keys -- Inline preshared keys accepted by the API.
keys: ["secret"]
tracer:
# app.tracer.enabled -- Enable distributed tracing export.
enabled: false
meter:
# app.meter.enabled -- Enable metrics export.
enabled: false
# app.meter.exporter -- Metrics exporter type.
exporter: otlp
# app.meter.endpoint -- Metrics exporter endpoint.
endpoint: telemetry.permify.co
service:
# app.service.circuit_breaker -- Enable circuit breaker behavior for internal operations.
circuit_breaker: false
watch:
# app.service.watch.enabled -- Enable watch/change-stream behavior.
enabled: false
schema:
cache:
# app.service.schema.cache.number_of_counters -- Counter count used by schema cache policy.
number_of_counters: 1_000
# app.service.schema.cache.max_cost -- Memory budget for schema cache.
max_cost: 8MiB
permission:
# app.service.permission.concurrency_limit -- Limit concurrent permission evaluations.
concurrency_limit: 100
cache:
# app.service.permission.cache.number_of_counters -- Counter count used by permission cache policy.
number_of_counters: 10_000
# app.service.permission.cache.max_cost -- Memory budget for permission cache.
max_cost: 16MiB
Database and distributed mode
Copy
app:
database:
# app.database.engine -- Storage backend. 'memory' is ephemeral; 'postgres' is persistent.
engine: postgres
# app.database.uri -- PostgreSQL connection URI.
uri: postgres://postgres:secret@localhost:5432/permify?sslmode=disable
# app.database.uri_secret -- If you use a secret to store the database URI, set it here.
#uri_secret: ""
# app.database.auto_migrate -- Run schema migrations automatically at startup.
auto_migrate: true
# app.database.max_open_connections -- Max DB connections.
max_open_connections: 20
# app.database.max_idle_connections -- Max idle DB connections.
max_idle_connections: 1
# app.database.max_connection_lifetime -- Max lifetime for DB connections.
max_connection_lifetime: 300s
# app.database.max_connection_idle_time -- Max idle time before DB connection is closed.
max_connection_idle_time: 60s
garbage_collection:
# app.database.garbage_collection.enabled -- Enable stale tuple cleanup jobs.
enabled: false
# app.database.garbage_collection.interval -- GC run interval.
# interval: 200h
# app.database.garbage_collection.window -- GC lookback window.
# window: 200h
# app.database.garbage_collection.timeout -- Timeout per GC run.
# timeout: 5m
distributed:
# app.distributed.enabled -- Enable distributed mode across multiple instances.
enabled: false
Resources, database job, autoscaling, and scheduling
Copy
# resources -- CPU/memory requests and limits for the Permify container.
# Setting requests/limits strongly affects scheduling, stability, and autoscaling behavior.
resources: {}
autoscaling:
# autoscaling.enabled -- Enable HorizontalPodAutoscaler for Permify deployment.
enabled: false
# autoscaling.minReplicas -- Minimum number of replicas when autoscaling is enabled.
minReplicas: 1
# autoscaling.maxReplicas -- Maximum number of replicas when autoscaling is enabled.
maxReplicas: 100
# autoscaling.targetCPUUtilizationPercentage -- CPU utilization target for HPA scaling decisions.
targetCPUUtilizationPercentage: 80
# autoscaling.targetMemoryUtilizationPercentage -- Memory utilization target for HPA scaling decisions.
targetMemoryUtilizationPercentage: 80
# nodeSelector -- Constrain pod placement to nodes with matching labels.
nodeSelector: {}
# tolerations -- Allow scheduling onto tainted nodes.
tolerations: []
# affinity -- Advanced pod scheduling rules (node affinity, pod affinity/anti-affinity).
affinity: {}
Production notes
- Set
app.authn.enabled: trueand supply keys via secret-based settings in production. - If you expose Permify externally, either configure
ingressand TLS or use a LoadBalancer-type service.