Skip to main content

Prerequisites

Verify your environment meets the following requirements before installing Conductor.


Deployment checklist

Before you can successfully deploy Conductor, ensure you have:


Supported Kubernetes distributions

Conductor is officially tested on the following Kubernetes distributions.

PlatformVersionWhat's Pre-InstalledAdditional Requirements
Amazon EKS1.21+RBAC, CSI, Load balancerMetrics Server must be installed separately
Google GKE1.21+Metrics Server, RBAC, CSI, Load balancer-
Azure AKS1.21+Metrics Server, RBAC, CSI, Load balancer-
RedHat OpenShift4.6+Metrics Server, RBACCluster admin or SCC permissions; Network egress for outbound HTTPS
Local (Kind, Minikube, Docker Desktop)1.21+-Docker running; Metrics Server with TLS workaround (see below)
On-Premises1.21+VariesRBAC enabled; Metrics Server; Persistent volume support
ARM-based (M1/M2, Graviton, Ampere)1.21+Varies by providerNode selectors for ARM64 - ARM guide
Testing Status

Additional Kubernetes distributions haven't been officially tested with Conductor. You may try them at your own risk.

Metrics Server TLS workaround for local clusters:

After installing the Kubernetes Metrics Server on local Kubernetes clusters, you may need to account for this requirement: Kubelet certificate needs to be signed by cluster Certificate Authority (or disable certificate validation by passing --kubelet-insecure-tls to Metrics Server). To pass that flag, use this command on your cluster:

kubectl patch deployment metrics-server -n kube-system --type "json" \
-p '[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'

Cluster resource requirements

Conductor agent

The Conductor agent consists of three components with the following default resource requests:

ComponentTypeDefault ResourcesReplicasDeployed On
diagrid-agentDeployment200m CPU, 400Mi memory2Selected nodes
diagrid-agent-logs-collectorDaemonSet200m CPU, 400Mi memory1 per node*All nodes*
diagrid-agent-otelStatefulSet200m CPU, 400Mi memory2Selected nodes

*The Logs Collector and Otel Collector (metrics) use a modified version of the OpenTelemetry Collector. The Logs Collector runs on every node by default—use node selectors, affinity rules, or tolerations to restrict to nodes with Dapr applications for best results.

Dapr control plane resources

Conductor can install Dapr with recommended resource configurations automatically. Default Dev and Prod profiles set appropriate values based on Dapr production guidelines.

Read the Configuration Guide for more details.


Network requirements

Required outbound access

Your cluster must have outbound internet access to the following endpoints. No inbound access required, the Conductor agent uses outbound egress only.

EndpointPurposePort
conductor.diagrid.io, https://conductor.r1.diagrid.ioConsole and control plane443
cloudgrid.diagrid.io, https://cloudgrid.r1.diagrid.ioAgent communication443
metrics.diagrid.io, https://metrics.r1.diagrid.ioTelemetry and metrics443

Optional endpoints for Dapr installation & upgrades

If Conductor will install or upgrade Dapr using the upstream Helm chart and container images, also allow:

  • https://dapr.github.io/helm-charts/
  • https://hub.docker.com
  • https://auth.docker.io
  • https://registry.docker.io
  • https://registry-1.docker.io
  • https://production.cloudflare.docker.com
Private Registry Users

If using Dapr container images from a private registry, these addresses are not required. However, you become responsible for managing the Dapr Helm chart and container images, including upgrades. See Private Registry Guide.

Network policies

If using Kubernetes network policies, ensure the following is connectivity is allowed:

  • Conductor agent → Dapr sidecars: Port 3501 (Dapr metadata API, resources)
  • Conductor agent → Dapr control plane namespace (resources)

RBAC permissions

Installation permissions

  • Required: Kubernetes cluster admin role (or equivalent) to install the Conductor agent.
  • After installation: Only namespace-level permissions needed for the diagrid-cloud and application namespaces.

Conductor agent permissions

The Conductor agent requires Kubernetes RBAC permissions to:

  • Monitor Dapr control plane and workloads
  • Install and upgrade Dapr components (if managing Dapr)
  • Perform component initialization checks
  • Roll out applications with updated Dapr sidecars
Helm Managed Mode (Read-Only)

If you install with Helm managed mode, the agent operates in read-only mode with reduced permissions. A minimal set of write rules remain for agent operation (leases, configmaps for checkpoints).

Permission details

  • Dapr Control Plane: RBAC rules use resourceNames where possible for least-privilege access
  • Dapr Workloads: Dynamic names prevent resourceNames, so follows Dapr RBAC chart
  • Workload Rollouts: To roll out applications and ensure they receive the latest version of the Dapr sidecar, the agent patches Kubernetes Deployment, DaemonSet, StatefulSet, and Job resources by modifying the diagrid.io/restartedAt annotation to trigger a rollout
  • Component Init: Agent reads component secrets to validate initialization - Learn more →
Helm managed cluster connection (read-only mode)
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"leases",
"pods",
"nodes/metrics",
"nodes/proxy",
"jobs",
"cronjobs",
"persistentvolumeclaims",
"serviceaccounts",
]
verbs: ["get"]
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"leases",
"pods",
"nodes",
"nodes/metrics",
"nodes/proxy",
"jobs",
"cronjobs",
"persistentvolumeclaims",
"endpoints",
"replicasets",
]
verbs: ["list"]
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"leases",
"pods",
"nodes",
"nodes/metrics",
"nodes/proxy",
"jobs",
"cronjobs",
"endpoints",
]
verbs: ["watch"]
- apiGroups: ["metrics.k8s.io"]
resources: ["pods"]
verbs: ["get", "list", "watch"]

# ⓘ by default, these are permitted cluster-wide. with the Helm managed agent, these are restricted to the agent and dapr namespaces.
# ⓘ however, with the Helm managed agent + component init disabled, these are restricted to the agent and dapr namespaces.
# ⓘ see more at https://docs.diagrid.io/conductor/observe/components#disabling-initialization
- apiGroups: ["*"]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]

- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["get"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
verbs: ["get"]
- apiGroups: ["", "apps", "extensions"]
resources: ["deployments", "pods", "pods/log", "namespaces"]
verbs: ["get", "list"]
- apiGroups: ["*"]
resources:
[
"components",
"configurations",
"subscriptions",
"resiliencies",
"httpendpoints",
]
verbs: ["get", "list", "watch"]
- apiGroups: ["dapr.io"]
resources: ["*"]
verbs: ["get", "list", "watch", "patch", "update"]
- apiGroups: ["apps", "*"]
resources: ["statefulsets", "statefulsets/finalizers"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets"]
verbs: ["get", "list", "watch"]
- nonResourceURLs:
- /metrics
verbs: ["get"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update"]

# ⓘ `resourceName` limited:
# (some write verbs necessary)
- apiGroups: ["*"]
resources: ["configmaps"]
verbs: ["get", "list", "watch", "create", "patch"]
resourceNames:
- agent-checkpoint
- agent-dependencies-checkpoint
- dapr-checkpoint
- diagnostics-checkpoint
- rollouts-checkpoint

# ⓘ OPTIONAL: present only if the cluster was set as OpenShift:
- apiGroups: ["security.openshift.io"]
resources: ["securitycontextconstraints"]
verbs: ["get"]

# ⓘ OPTIONAL: present only if the cluster has enabled Certificate Rotation:
# (some write verbs necessary)
- apiGroups:
[
"admissionregistration.k8s.io",
"dapr.io",
"policy",
"rbac.authorization.k8s.io",
]
resources:
[
"mutatingwebhookconfigurations",
"configurations",
"poddisruptionbudgets",
"clusterroles",
]
verbs: ["get", "update", "patch"]
- apiGroups: ["apps"]
resources: ["statefulsets", "deployments"]
verbs: ["get", "update", "patch"]
- apiGroups: ["*"]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
Manifest backed cluster connection (Full management mode)
- apiGroups: ["*"]
resources:
[
"services",
"secrets",
"configmaps",
"leases",
"services/finalizers",
"deployments/finalizers",
"pods",
"nodes",
"endpoints",
]
verbs: ["update"]
- apiGroups: ["*"]
resources: ["services", "leases", "secrets", "persistentvolumeclaims"]
verbs: ["delete"]
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"configmaps",
"events",
"leases",
"secrets",
"namespaces",
"serviceaccounts",
]
verbs: ["create"]
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"configmaps",
"leases",
"secrets",
"namespaces",
"serviceaccounts",
]
verbs: ["patch", "update"]
- apiGroups: ["*"]
resources: ["pods"]
verbs: ["patch"]
- apiGroups: ["*"]
resources:
[
"components",
"configurations",
"subscriptions",
"resiliencies",
"httpendpoints",
]
verbs: ["create", "patch", "update"]
- apiGroups: ["dapr.io"]
resources: ["*"]
verbs: ["create", "patch", "update"]
- apiGroups: ["apps", "*"]
resources: ["statefulsets", "statefulsets/finalizers"]
verbs: ["create", "patch", "update", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets"]
verbs: ["create", "patch", "update"]

# OpenShift specific permissions, only present if OpenShift was selected as the distribution:
- apiGroups: ["security.openshift.io"]
resources: ["securitycontextconstraints"]
verbs: ["create", "patch"]

# `resourceName` specified:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
resourceNames:
["dapr-dashboard", "dashboard-reader", "dashboard-reader-global"]
verbs: ["delete"]
- apiGroups: [""]
resources: ["serviceaccounts", "services"]
verbs: ["delete"]
resourceNames: ["dapr-dashboard", "dashboard-reader"]
- apiGroups: ["apps"]
resources: ["deployments", "deployments/finalizers"]
verbs: ["delete"]
resourceNames: ["dapr-dashboard"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets", "statefulsets"]
verbs: ["create"] # create, list, watch cannot use resourceNames
- apiGroups: ["apps"]
resources: ["deployments"]
resourceNames: ["dapr-operator", "dapr-sentry", "dapr-sidecar-injector"]
verbs: ["get", "patch", "update"]
- apiGroups: [""] # needed for downgrading from 1.15 to 1.14
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "delete"]
resourceNames:
- dapr-scheduler-data-dir-dapr-scheduler-server-0
- dapr-scheduler-data-dir-dapr-scheduler-server-1
- dapr-scheduler-data-dir-dapr-scheduler-server-2
- apiGroups: ["apps"]
resources: ["daemonsets", "deployments", "statefulsets"]
resourceNames:
["diagrid-agent-logs-collector", "diagrid-agent", "diagrid-agent-otel"]
verbs: ["get", "patch", "update"]
- apiGroups: ["apps"]
resources: ["statefulsets"]
resourceNames: ["dapr-placement-server", "dapr-scheduler-server"]
verbs: ["get", "patch", "update", "delete"] # delete is required when going from non-HA to HA
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "update", "delete"]
resourceNames: ["dapr-trust-bundle"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "update"]
resourceNames: ["dapr-trust-bundle"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["create"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "update"]
resourceNames: ["operator.dapr.io", "webhooks.dapr.io"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "update"]
resourceNames: ["operator.dapr.io", "webhooks.dapr.io"]
- apiGroups: ["apps"]
resources: ["deployments/finalizers"]
resourceNames: ["dapr-operator", "dapr-sentry", "dapr-sidecar-injector"]
verbs: ["update"]
- apiGroups: ["apps"]
resources: ["statefulsets/finalizers"]
resourceNames: ["dapr-placement-server", "dapr-scheduler-server"]
verbs: ["update"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["mutatingwebhookconfigurations"]
verbs: ["create"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["mutatingwebhookconfigurations"]
verbs: ["get", "patch", "update", "delete"]
resourceNames: ["dapr-sidecar-injector"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["create"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["patch", "update"]
resourceNames:
- dapr-operator-disruption-budget
- dapr-placement-server-disruption-budget
- dapr-scheduler-server-disruption-budget
- dapr-sentry-budget
- dapr-sidecar-injector-disruption-budget
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "update"]
resourceNames:
- dapr-placement-server
- dapr-scheduler-server
- dapr-sentry
- dapr-sidecar-injector
- dapr-api
- dapr-webhook
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["create"] # cannot use resourceNames for CRDs creation role
- apiGroups: ["*"]
resources: ["customresourcedefinitions"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"components.dapr.io",
"configurations.dapr.io",
"subscriptions.dapr.io",
"resiliencies.dapr.io",
"httpendpoints.dapr.io",
"pluggablecomponents.dapr.io",
]
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["get", "patch", "update"]
resourceNames: ["clusterconnections.conductor.diagrid.io"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings"]
verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"dapr-sentry",
"dapr-placement",
"dapr-operator-admin",
"dapr-injector",
"dapr-scheduler",
]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"dapr-sentry",
"dapr-placement",
"dapr-operator",
"dapr-injector",
"dapr-scheduler",
"secret-reader",
"dapr-secret-reader",
]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"dapr-sentry",
"dapr-placement",
"dapr-operator",
"dapr-injector",
"dapr-scheduler",
]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "patch", "update"]
resourceNames: ["secret-reader", "dapr-secret-reader"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"dapr-operator",
"dapr-placement",
"dapr-scheduler",
"dapr-sentry",
"dapr-injector",
]
# Required by dapr 1.14
- apiGroups: [""]
resources: ["resourcequotas"]
verbs: ["create", "list", "watch"]
- apiGroups: [""]
resources: ["resourcequotas"]
verbs: ["get", "patch", "update", "delete"]
resourceNames: ["dapr-system-critical-quota", "system-critical-quota"]
# Required by dapr 1.15
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch"]
# Diagrid ClusterRole and ClusterRoleBinding
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["patch", "update"]
resourceNames:
- diagrid-agent-dashboard-reader
- diagrid-agent-dapr-operator-admin
- diagrid-operator-dashboard-reader
- diagrid-operator-dapr-operator-admin
- diagrid
- diagrid-operator-agent-role
- diagrid-operator-role
- dapr-dashboard
- dashboard-reader
- dashboard-reader-global
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
- diagrid-agent-dapr-operator
- diagrid-agent-dashboard-reader
- diagrid-agent-dapr-role-tokenreview-binding
- diagrid-agent-dashboard-reader-global
- diagrid-operator-dapr-operator
- diagrid-operator-dashboard-reader
- diagrid-operator-dapr-role-tokenreview-binding
- diagrid-operator-dashboard-reader-global
- diagrid
- diagrid-operator-agent-role
- diagrid-operator-operator-role
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["patch", "update"]
resourceNames:
- diagrid-operator-role-cm
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
- diagrid-operator-operator-role

Next steps


Frequently Asked Questions

Do I need Dapr installed before using Conductor?
No. Conductor can install Dapr for you during cluster connection setup. You can also connect Conductor to existing Dapr installations (version 1.9+).
What if my cluster doesn't have internet access?
Conductor supports high security environments with some configuration: 1. Mirror Conductor and Dapr images to your private registry. 2. Configure cluster connection with custom image references. 3. Network egress to the rules listed here is still required for agent to control plane communication. View private registry setup guide →
Can I use Conductor on ARM-based clusters?
Yes! Conductor supports ARM64 architecture (Apple Silicon, AWS Graviton, Ampere). You'll need to configure node selectors during installation. View ARM configuration guide →
What permissions does Conductor need?
Conductor agent requires: • Read access to pods, deployments, services, configs, and Dapr resources • Write access to manage Dapr control plane (if managing Dapr) • No access to application data or secrets (except Dapr component secrets which stay on the cluster for initialization checks) View detailed RBAC permissions →
Can I install Conductor without cluster admin?
Initial installation requires cluster admin permissions. After installation, day-to-day management only requires namespace-level permissions for the `diagrid-cloud` and Dapr application namespaces.
What's the difference between Helm managed and manifest-backed (default) cluster connections?
• Manifest-backed (default): Conductor agent fully manages Dapr control plane (install, upgrade, configuration) and will overwrite any external changes made. • Helm managed: Agent operates read-only; you manage Dapr via Helm/GitOps externally Helm Managed mode uses reduced RBAC permissions and is available in Conductor Enterprise. Learn more about Helm installation →