kuma-migrator

Migrates Kuma and Kong Mesh policy manifests across the API changes in the 2.x line and into 3.0 — rewrites what can be rewritten safely, and reports what cannot, with the reason.

📦 Homebrew · Linux · macOS · Windows 🔓 Apache-2.0 🔏 Attested release binaries

Why

The policy API changed substantially across 2.0–2.14, and some of the 3.0 removals are silent.

The Kuma and Kong Mesh policy API changed substantially across 2.0–2.14, and 3.0 removes a number of fields that 2.14 still accepts. Some of those removals are silent: the manifest applies cleanly and simply stops doing what it used to.

kuma-migrator automates the mechanical parts, flags the parts that need a human, and writes a Markdown report of every change it made or would make.

How it works

Two commands, plus a manual apply step. Extract from a live control plane, migrate (preview first with --dry-run), apply.

Pipeline diagram: extract pulls resources from a running control plane, migrate writes the migrated manifests and report (add --dry-run to preview with no YAML written), apply — a manual step, not a kuma-migrator command — runs kubectl or kumactl in the report's order.
# 1a. Pull resources via kumactl (self-hosted OR Konnect-hosted, zonal or Global CP)
kuma-migrator extract --kumactl-context konnect-global-prod --output-dir ./raw-policies

# 1b. ...or via kubectl (self-hosted, Kubernetes-backed CP)
kuma-migrator extract --kube-context zone-eu-west1-prod --output-dir ./raw-policies

# 2. Write the migrated manifests + migration-report.md
#    (add --dry-run to preview first — writes migration-plan.md, no YAML)
kuma-migrator migrate --input-dir ./raw-policies --output-dir ./migrated

# Now read migration-report.md — it gives the exact apply order for your
# setup (Mesh resources go last: they switch on meshServices.mode: Exclusive)

# 3a. Apply them yourself if you used --kumactl-context (self-hosted or
#     Konnect) — kumactl rejects a directory, so apply one file at a time
kumactl config use-context konnect-global-prod
kumactl apply -f ./migrated/konnect-global-prod-global-ctx/mesh-default/resiliency/MeshTimeout-my-timeout.yaml

# 3b. ...or via kubectl if you extracted via --kube-context — this step
#     is manual; kuma-migrator never touches your control plane's state
kubectl apply -f ./migrated/zone-eu-west1-prod-zone-ctx/mesh-default/resiliency/

Three mechanical translations

Applied to every legacy policy the tool touches.

Three examples of kuma-migrator's mechanical translations: a Dataplane tag becomes a structured targetRef, a legacy policy kind like Timeout becomes MeshTimeout, and a MeshSubset tag selector becomes a Dataplane/MeshService reference.
A Dataplane tag decoded into a structured targetRef, a legacy policy kind rewritten to its Mesh* successor, and a tag/label selector expanded into a typed reference — the same mechanism behind every conversion below.

What it handles

Alongside these, every output document is scanned for deprecated and removed fields across the 2.x line and 3.0.

ScenarioMigration
Legacysources/destinations/selectors policies → targetRef/to/from/rules, with the conf body rewritten to the successor's schema — except TrafficRoute (ambiguous HTTP vs TCP) and VirtualOutbound (no single successor), reported for manual migration
SubsetMeshSubset with service tags → Dataplane/MeshService
RulesDeprecated from[] → rules[], for MeshTimeout/MeshCircuitBreaker/MeshRateLimit/MeshAccessLog/MeshTLS only (Kuma 2.10+) — MeshTrafficPermission/MeshFaultInjection use a different, SPIFFE-based rules[] shape and are not auto-converted
MeshMesh CRD observability → standalone MeshMetric/MeshTrace/MeshAccessLog
ExternalServiceExternalService → MeshExternalService
GWMeshGateway and MeshGatewayRoute → Gateway API. Kuma 3.0 deletes the built-in gateway API outright, so under v3 MeshGatewayInstance is reported rather than converted, and the source objects must be deleted before upgrading. MeshHTTPRoute/MeshTCPRoute are current policies on both lines and pass through unchanged
OPAPolicyKong Mesh OPAPolicy → MeshOPA

Why MTP/MFI's from[] is never auto-converted: MeshTrafficPermission modes. Full list: migration paths and deprecation warnings.

Choosing a target: --to-latest v2|v3

One output cannot serve both lines.

migrate (including its --dry-run mode) takes --to-latest v2 (default, latest 2.x) or v3. 3.0 removes fields 2.14 still requires, and some 3.0 replacements (MeshOpenTelemetryBackend, SecureDataSource) do not exist before 2.14.

v2 keeps the output applicable to a 2.x control plane and reports 3.0 removals as forward-looking advisories.

v3 rewrites what it safely can and flags the rest — a v3 report carries a banner warning that the output must not be applied to a 2.x CP.

See choosing a target version.

Verify what you install

Every release archive carries a build provenance attestation.

You do not have to trust that a downloaded archive matches this repository — you can check. Each release binds its archives to the exact commit and GitHub Actions run that built them, cryptographically, via GitHub build provenance attestation.

VERSION=$(gh release view --repo Kong/kuma-migrator --json tagName --jq '.tagName' | tr -d 'v')
curl -LO "https://github.com/Kong/kuma-migrator/releases/latest/download/kuma-migrator_${VERSION}_linux_amd64.tar.gz"
gh attestation verify "kuma-migrator_${VERSION}_linux_amd64.tar.gz" --repo Kong/kuma-migrator

The same digests appear in the release's checksums.txt, in the attestation, and in the Homebrew cask's sha256 fields — nothing is rebuilt in between.

Install

Homebrew (macOS and Linux)

brew install --cask bcollard/kuma-migrator/kuma-migrator

Pre-built binaries

Download the binary for your platform from the GitHub Releases page — Linux and macOS (amd64/arm64), Windows (amd64).

From source

git clone https://github.com/Kong/kuma-migrator.git && cd kuma-migrator
make build
# binary at ./dist/kuma-migrator

Full options: installation guide.

Documentation

Everything above is the short version. Each page below goes deeper on one part of it.

PageWhat it covers
InstallationHomebrew, binaries, from source
CLI referenceEvery command, flag, and the config file
Extracting from a control planeCP-mode rules, output layout, Konnect, Universal vs Kubernetes format
Plan and migrateDry run, output layout, Gateway API placement
Choosing a target version--to-latest and the checks that change with it
Applying the migrated manifestsApply order, and cleaning up changed kinds
Migration paths and deprecationsEverything detected, fixed or flagged
MeshTrafficPermission modesfrom[] vs rules[], and why it is not mechanical
MeshHTTPRoute and 3.0 routingThe 404 change, and the targetRef matrix for every policy
Transformation examplesBefore-and-after YAML per scenario
Console output and reportsWhat you see, and what the report contains
Notes and caveatsBehaviour worth knowing before relying on the output

Index: docs/.

Changelog

19 releases since April 2026. Full history: Releases · compare view.