# Prerequisites

Verify your environment meets the following requirements before installing Dapr Ops Dashboard.

- [Quickstart](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/getting-started/quickstart)
- [Installation Guide](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/installation-guide)

---

## Deployment checklist

Before you can successfully deploy Dapr Ops Dashboard, ensure you have:

- \[ ] **Kubernetes cluster** v1.21 or higher
- \[ ] **kubectl access** with cluster-admin permissions
- \[ ] **[Dapr Ops Dashboard account](https://diagrid.ws/conductor-trial)** (free, no credit card required)
- \[ ] **Network connectivity** - Outbound internet access to these [addresses](#network-requirements)
- \[ ] **[Kubernetes metrics server](https://github.com/kubernetes-sigs/metrics-server)** installed

---

## Supported Kubernetes distributions

Dapr Ops Dashboard is officially tested on the following Kubernetes distributions.

| Platform                               | Version | What's Pre-Installed                     | Additional Requirements                                                                                             |
| -------------------------------------- | ------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Amazon EKS                             | 1.21+   | RBAC, CSI, Load balancer                 | [Metrics Server](https://docs.aws.amazon.com/eks/latest/userguide/metrics-server.html) must be installed separately |
| Google GKE                             | 1.21+   | Metrics Server, RBAC, CSI, Load balancer | -                                                                                                                   |
| Azure AKS                              | 1.21+   | Metrics Server, RBAC, CSI, Load balancer | -                                                                                                                   |
| RedHat OpenShift                       | 4.6+    | Metrics Server, RBAC                     | Cluster 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-Premises                            | 1.21+   | Varies                                   | RBAC enabled; Metrics Server; Persistent volume support                                                             |
| ARM-based (M1/M2, Graviton, Ampere)    | 1.21+   | Varies by provider                       | Node selectors for ARM64 - [ARM guide](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/configure-arm-cluster)                         |

:::warning Testing Status
Additional Kubernetes distributions haven't been officially tested with Dapr Ops Dashboard. 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](https://github.com/kubernetes-sigs/metrics-server?tab=readme-ov-file#requirements): `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:

```bash
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

### Dapr Ops Dashboard agent

The Dapr Ops Dashboard agent consists of three components with the following default resource requests:

| Component                        | Type        | Default Resources      | Replicas     | Deployed On    |
| -------------------------------- | ----------- | ---------------------- | ------------ | -------------- |
| **diagrid-agent**                | Deployment  | 200m CPU, 400Mi memory | 2            | Selected nodes |
| **diagrid-agent-logs-collector** | DaemonSet   | 200m CPU, 400Mi memory | 1 per node\* | All nodes\*    |
| **diagrid-agent-otel**           | StatefulSet | 200m CPU, 400Mi memory | 2            | Selected nodes |

\**The Logs Collector and Otel Collector (metrics) use a modified version of the [OpenTelemetry Collector](https://opentelemetry.io/docs/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

Dapr Ops Dashboard can install Dapr with recommended resource configurations automatically. Default Dev and Prod profiles set appropriate values based on [Dapr production guidelines](https://docs.dapr.io/operations/hosting/kubernetes/kubernetes-production).

Read the [Configuration Guide](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/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 Dapr Ops Dashboard agent uses outbound egress only.

| Endpoint                                                  | Purpose                   | Port |
| --------------------------------------------------------- | ------------------------- | ---- |
| `https://conductor.r1.diagrid.io` | Console and control plane | 443  |
| `https://cloudgrid.r1.diagrid.io` | Agent communication       | 443  |
| `https://metrics.r1.diagrid.io`     | Telemetry and metrics     | 443  |

### Optional endpoints for Dapr installation & upgrades

If Dapr Ops Dashboard will **install or upgrade Dapr** using the upstream [Helm chart](https://github.com/dapr/dapr/blob/master/charts/dapr/README.md) and [container images](https://hub.docker.com/u/daprio), 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`

:::tip 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](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/byo-container-images).
:::

### Network policies

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

- Dapr Ops Dashboard agent → Dapr sidecars: Port `3501` (Dapr metadata API, resources)
- Dapr Ops Dashboard agent → Dapr control plane namespace (resources)

---

## RBAC permissions

### Installation permissions

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

### Dapr Ops Dashboard agent permissions

The Dapr Ops Dashboard 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

:::info Helm Managed Mode (Read-Only)
If you [install with Helm managed mode](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/installation-guide#helm-installation), 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](https://github.com/dapr/dapr/tree/master/charts/dapr/charts/dapr_rbac)
- **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 →](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/observe/components#component-initialization)

<details>
  <summary><b>Helm managed cluster connection (read-only mode)</b></summary>

  ```yaml
  - 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 /dapr-open-source/dapr-ops-dashboard/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"]
  ```
</details>

<details>
  <summary><b>Manifest backed cluster connection (Full management mode)</b></summary>

  ```yaml
  - 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
  ```
</details>

---

## Next steps

- [Install Dapr Ops Dashboard](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/installation-guide) — Choose your installation method and follow step-by-step instructions
- [Quickstart Guide](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/getting-started/quickstart) — Get Dapr Ops Dashboard running in 10 minutes with a minimal local setup
- [Cluster Insights](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/observe/clusters) — Dive into Dapr insights from your apps in Dapr Ops Dashboard

---

## Frequently Asked Questions

**Do I need Dapr installed before using Dapr Ops Dashboard?**

No. Dapr Ops Dashboard can install Dapr for you during cluster connection setup. You can also connect Dapr Ops Dashboard to existing Dapr installations (version 1.9+).

**What if my cluster doesn't have internet access?**

Dapr Ops Dashboard supports high security environments with some configuration:
 1. Mirror Dapr Ops Dashboard and Dapr images to your private registry.
 2. Configure cluster connection with custom image references.
 3. Network egress to the rules listed  [here](#network-requirements) is still required for agent to control plane communication.

 [View private registry setup guide →](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/byo-container-images)

**Can I use Dapr Ops Dashboard on ARM-based clusters?**

Yes! Dapr Ops Dashboard supports ARM64 architecture (Apple Silicon, AWS Graviton, Ampere). You'll need to configure node selectors during installation.

 [View ARM configuration guide →](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/configure-arm-cluster)

**What permissions does Dapr Ops Dashboard need?**

The Dapr Ops Dashboard 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 →](#rbac-permissions)

**Can I install Dapr Ops Dashboard 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): Dapr Ops Dashboard 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 Dapr Ops Dashboard Enterprise.

 [Learn more about Helm installation →](https://docs.diagrid.io/dapr-open-source/dapr-ops-dashboard/installation-guide#helm-installation)
