Skip to main content

Migrate from Dapr OSS on Kubernetes to Catalyst

Catalyst is built on Dapr OSS, so it supports the same APIs, resource types, and a selection of Dapr components*. As a result, your existing Dapr resources, such as policies and configurations, work without modification, and your application code can keep using the same Dapr SDKs.

This guide walks you through the process of migrating your workloads from Dapr OSS on Kubernetes to Catalyst.

Check compatibility before you migrate
  • Components: *Catalyst supports a curated subset of Dapr OSS components — state stores, pub/sub brokers, secret stores, bindings, conversation, and so on. Check the Catalyst component specs reference and confirm that every component type you rely on is supported. Components that aren't listed won't work on Catalyst and need an alternative or an exception before you can complete the migration.
  • Secret stores: Catalyst does not support secretstores.kubernetes, the secret store most Dapr applications on Kubernetes use. See Secret stores for what to do instead — depending on how you use it, you may need no secret store at all, or you may need to provision one before you migrate.
  • Configuration: In Catalyst you can only configure some fields within a Dapr Configuration resource; others are reserved for Catalyst's internal use. See Dapr configuration compatibility for the full list of editable and reserved fields.

Prerequisites​

  • A Kubernetes cluster running Dapr open source.
  • A Diagrid Catalyst organization you have global admin or editor access to. You can sign up for free at Diagrid Catalyst.
  • The Diagrid CLI installed and authenticated.
  • A secret store Catalyst supports — AWS Secrets Manager, Azure Key Vault or HashiCorp Vault — but only if one of your applications calls the Dapr Secrets API. See Secret stores.

Starting point: Dapr OSS on Kubernetes​

A typical Dapr OSS setup looks like this:

  • The Dapr control plane installed in the dapr-system namespace via Helm or the Dapr CLI.
  • Application pods annotated with dapr.io/enabled: "true", which get a Dapr sidecar injected by the Dapr operator.
  • Dapr CRDs such as Components, Configurations, Subscriptions, and Resiliency policies, stored in the Kubernetes cluster.

Two decisions shape your migration​

Before you start, you need to make two decisions — one architectural, one operational:

  1. Where the Dapr server runs — in Catalyst (remote) or in your application Kubernetes cluster (local).
  2. Which tools you want to use — with Catalyst-native tooling (UI, CLI, Terraform) or with the Catalyst Kubernetes operator.

Dapr Server location: remote or local​

  • Remote — Catalyst's Dapr server runs in Catalyst. Your app calls the Dapr API via Catalyst's endpoint and no Dapr server runs inside your app pod.
  • Local — Catalyst's Dapr server runs as a sidecar in your app pod, configured to talk to Catalyst's Dapr control plane. Your app continues to talk to the Dapr APIs over localhost the same as Dapr OSS.

Pick remote for zero server ops and the lowest infrastructure footprint. Pick local when the Dapr server must stay inside your network boundary or be co-located with the workload.

Local Dapr Server networking​

If you choose the local location for your Dapr Server, note that it will run inside your application Kubernetes cluster and is thus subject to your cluster's networking rules and policies. All traffic between the app, the Dapr Server sidecar, and any infrastructure is fully within your control and cannot be influenced by Catalyst. You are responsible for configuring appropriate network policies to isolate your workloads and allow access to the services and infrastructure they need.

Tooling: Catalyst-native or Kubernetes-native​

You can choose the tooling that best suits your setup for migrating and managing your workloads on Catalyst. For existing Dapr apps running on Kubernetes, the Catalyst Kubernetes Operator provides a simpler migration path. Once you've migrated your workloads, you can switch to using the native Catalyst tooling if you prefer.

Select from one of the options below to see how you can use that tooling to migrate your workloads.

PathBest whenWhat it does
Catalyst-nativeCatalyst is your source of truth and you drive infra from the UI, CLI, or TerraformYou create Catalyst resources yourself, then wire each workload to Catalyst
Kubernetes-nativeYour platform team already manages Dapr declaratively in-clusterThe Catalyst Kubernetes operator reconciles Dapr's K8s native resources into Catalyst

Secret stores​

Catalyst supports three secret store types: aws.secretsmanager, azure.keyvault and hashicorp.vault. It does not support secretstores.kubernetes, the default secret store for a Dapr application on Kubernetes. Applying a component of that type is rejected:

invalid value of 'secretstores.kubernetes' provided for 'spec.type' field:
please use a supported type. See our docs @ https://docs.diagrid.io.

What to do about it depends on how your applications use the store, and the two cases are independent. Check both.

Components that reference a secret​

A component whose metadata uses secretKeyRef needs no secret store on Catalyst. Supply the value as plaintext instead:

# Dapr OSS
- name: redisPassword
secretKeyRef:
name: redis-secret
key: password

# Catalyst
- name: redisPassword
value: "<password>"

Catalyst identifies sensitive fields from the Dapr component metadata schema and extracts them into a Catalyst-managed secret store before the resource is persisted, so the plaintext value is never stored in the control plane. See Managing secrets.

This is a change of secrets model rather than a component swap: the value moves out of your cluster and into Catalyst.

Applications that call the Secrets API​

An application that calls GetSecret or GetBulkSecret needs a real secret store, so secretstores.kubernetes has to be replaced with one of the three supported types. Provision it before you migrate, because the application fails at runtime without it.

Two things to plan for:

  • Move the secret data. The contents of your Kubernetes Secret objects have to exist in the new store before the migrated application reads them.
  • Keep the component name. Your application names the store in every call, so reusing the original component name — only changing spec.type and its metadata — means the application code does not change.

Dapr configuration compatibility​

Catalyst supports the Dapr Configuration resource, but some fields are reserved for Catalyst's internal use and cannot be changed. Behavior can also differ between public (multi-tenant SaaS) regions and self-hosted (private) regions. Each field falls into one of these categories per region:

  • 🔒 Locked — Catalyst manages this field. Any value you supply is ignored or overwritten.
  • ✏️ Editable — You can set this field, subject to the validation noted.
FieldPublic regionsSelf-hosted regionsNotes
accessControl.trustDomain🔒 Locked🔒 LockedReserved by Catalyst; set automatically to your organization's SPIFFE trust domain.
accessControl.policies[].trustDomain🔒 Locked🔒 LockedForced to your organization's trust domain.
accessControl.policies[].namespace🔒 Locked🔒 LockedForced to your project namespace (prj-<namespace>).
features🔒 Locked🔒 LockedPreview feature toggles are managed by Catalyst.
api.allowed🔒 Locked🔒 LockedRestricted to the Catalyst platform API allow-list.
metrics🔒 Locked🔒 LockedCatalyst applies its own metric cardinality rules.
tracing (otel / zipkin)🔒 Editable✏️ EditableRequires otel.isSecure. Custom/internal endpoints are rejected in public regions.
workflow.maxConcurrentWorkflowInvocations, workflow.maxConcurrentActivityInvocations🔒 Locked✏️ EditableConcurrency limits. Managed by Catalyst in public regions; editable up to Catalyst's caps (5000 / 10000) in self-hosted regions.
workflow.stateRetentionPolicy (anyTerminal, completed, failed, terminated)✏️ Editable✏️ EditablePer-terminal-state retention durations (Go duration strings). Added in Dapr 1.17.
httpPipeline / appHttpPipeline handlers (user middleware)✏️ Editable✏️ EditableUser handlers are appended after Catalyst's reserved base handler, which is always present and cannot be removed.
accessControl.defaultAction + accessControl.policies[] (appId, defaultAction, operations with name / httpVerb / action)✏️ Editable✏️ EditableValidated as allow/deny rules.

Next steps​

  1. Migrate your workloads with the Catalyst Kubernetes operator or Catalyst-native tooling.
  2. Cut over and decommission Dapr OSS — move traffic onto Catalyst and remove the Dapr OSS control plane.