{
  "schema_version": 2,
  "id": "operate/iris/intent-router/self-managed/deploy",
  "title": "Deploy Redis Intent Router",
  "url": "https://redis.io/docs/latest/operate/iris/intent-router/self-managed/deploy/",
  "summary": "Install Redis Intent Router, then create a Router, mint an agent key, and make one authenticated match.",
  "tags": [
    "docs",
    "operate",
    "iris"
  ],
  "last_updated": "2026-11-03T16:45:14-08:00",
  "page_type": "content",
  "content_hash": "30431fccc3875ef7dd78747bded0f12ecfb2dbed2c3f9599c7b9ae1b8266817a",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "> [!NOTE]\n> For a supported install, see [Install with the Redis Iris suite chart](#install-with-the-redis-iris-suite-chart). The standalone steps on this page show what each value does.\n\nFollow these steps to install the Intent Router control plane and data plane with the `redis-intent-router` Helm chart, connect them to your Identity Service release, and end with one authenticated match request.\n\nYou use three credentials along the way: the control-plane admin token, the Identity Service control token, and an agent key. For what each credential unlocks, see [Credentials](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/authentication#credentials).\n\nBefore you begin, review the [prerequisites](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/prerequisites)."
    },
    {
      "id": "1-create-the-namespace",
      "title": "1. Create the namespace",
      "role": "content",
      "text": "[code example]"
    },
    {
      "id": "2-create-secrets",
      "title": "2. Create Secrets",
      "role": "content",
      "text": ""
    },
    {
      "id": "configure-the-identity-service-release-first",
      "title": "Configure the Identity Service release first",
      "role": "configuration",
      "text": "For every Identity Service setting, and for running one release that serves several products, see the [Identity Service guide](https://redis.io/docs/latest/operate/iris/identity-service).\n\nThe chart deploys no Identity Service. Set these values on your Identity Service release so that it checks Router grants and accepts the data plane's runtime credential. The examples assume this chart is installed as release `intent` in the same namespace as an Identity Service release named `ids`.\n\n| Identity Service value | Setting |\n| --- | --- |\n| `runtime.serviceCredentials[]` | An entry with `name: intent-dp`, `subject: intent-dp`, `allowedOperations: [api-key-introspect]`, `allowedProducts: [intent]`, and the same `existingSecret` and `secretKey` as `identityService.credential`. |\n| `productValidation.products.intent.enabled` | `true` |\n| `productValidation.products.intent.baseURL` | The control-plane Service, `http://intent-redis-intent-router-controlplane:9400`. |\n| `productValidation.products.intent.credential` | The same Secret and key as `controlplane.internalToken`. |\n| `runtime.apiKeyTenant.singleTenantID` | The same value as `tenantId`. |\n\nNeither chart checks these values against the other. If the Identity Service release also serves other Iris products, add these entries to its existing lists. All products use the one tenant."
    },
    {
      "id": "create-the-connection-files",
      "title": "Create the connection files",
      "role": "content",
      "text": "Save the two Redis connections as `intent-controlplane-storage.yaml` and `intent-dataplane-storage.yaml`, as shown in [Storage Secret](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/configuration#storage-secret). The file names become the Secret's keys."
    },
    {
      "id": "create-the-secrets",
      "title": "Create the Secrets",
      "role": "content",
      "text": "Generate three distinct tokens, then create the Secrets:\n\n[code example]\n\nThe Identity Service release mounts `intent-controlplane-internal` and `intent-dp-credential` too, so create them in its namespace as well if it runs in another one.\n\nTo let the chart generate the admin or internal token instead, skip its Secret and delete its `existingSecret` line from the values file. The chart keeps a generated token across upgrades and never rotates it. The chart never generates `intent-dp-credential`.\n\nFor an embedding provider other than `noop`, also create the inference Secret, as shown in [Embedding models](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/configuration#embedding-models)."
    },
    {
      "id": "3-create-intent-valuesyaml",
      "title": "3. Create `intent-values.yaml`",
      "role": "content",
      "text": "Write the values file from [Helm values](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/configuration#helm-values), with your tenant, image tags, and Secret names."
    },
    {
      "id": "before-you-install-check-your-values",
      "title": "Before you install: check your values",
      "role": "content",
      "text": "Check each value before you install. If one is wrong, you see the symptom in its row.\n\n| Check | Symptom | Fix |\n| --- | --- | --- |\n| `tenantId` is set | Rendering fails with a named message | Set the tenant. |\n| Each image has a `tag` | Rendering fails, or pods `ImagePullBackOff` | Set `controlplane.image.tag` and `dataplane.image.tag`. |\n| The admin token, internal token, and Identity Service credential come from three different Secrets or keys | Rendering fails | Create three distinct token files. |\n| `dataplane.identityServiceBaseURL` is `https://`, or `identityService.allowInsecureTransport` is `true` | Rendering fails | Choose one. |\n| `tenantId` equals the Identity Service's `runtime.apiKeyTenant.singleTenantID` | Minting an agent key for a Router fails | Set both to the same tenant. |\n| `inference.models` lists one model, and `noop` only with `inference.allowLocalModels=true` | Rendering fails | List the one model the deployment offers. |\n| The inference Secret has an `embedders_connection_details` entry named after the model's `provider` | A new Router stays `PROVISIONING` or fails | Add the entry under that provider name. |\n| The data-plane Redis has Search | A new Router is `FAILED` and `failureReason` mentions vector search | Use a Redis 8 build that includes Search, or load the Search and Query engine. |"
    },
    {
      "id": "4-install",
      "title": "4. Install",
      "role": "content",
      "text": "[code example]\n\nTo add `helm test` pods that probe each service and run the shared security-profile checks, set `tests.enabled` to `true` in your values."
    },
    {
      "id": "5-verify-pods-and-health",
      "title": "5. Verify pods and health",
      "role": "content",
      "text": "[code example]\n\nRun each port-forward in its own terminal and leave it running:\n\n[code example]\n\n[code example]\n\n[code example]\n\nThen check readiness on every service:\n\n[code example]"
    },
    {
      "id": "6-create-a-router",
      "title": "6. Create a Router",
      "role": "content",
      "text": "Load the admin token, then create a Router. See [Manage Routers](https://redis.io/docs/latest/develop/ai/context-engine/intent-router/manage-routers) for every option.\n\n[code example]\n\nIf the chart generated the admin token, read it from `intent-redis-intent-router-controlplane-admin-token` instead.\n\nThe [API examples](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/api-examples#create-a-router) create the Router and wait until its state is `READY`."
    },
    {
      "id": "7-mint-an-agent-key",
      "title": "7. Mint an agent key",
      "role": "content",
      "text": "Mint a key with a grant on the Router through the Identity Service. See [Mint an agent key](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/api-examples#mint-an-agent-key)."
    },
    {
      "id": "8-make-one-authenticated-call",
      "title": "8. Make one authenticated call",
      "role": "content",
      "text": "Match a query with the key against the data plane:\n\n[code example]\n\nA Router with no intents returns `200` and `{\"items\": []}`. A `401` means the key is wrong, and a `403` means it lacks a grant on the Router. A `409` means the Router isn't `READY` yet."
    },
    {
      "id": "install-with-the-redis-iris-suite-chart",
      "title": "Install with the Redis Iris suite chart",
      "role": "setup",
      "text": "The `redis-iris` Helm chart installs Intent Router with the Identity Service and the UI in one release. `global.iris.products.intent.enabled` turns Intent Router on, and is `true` by default. The other products are on by default too, so set `global.iris.products.<product>.enabled: false` for each one you don't install. Put this chart's values under the `intent:` key.\n\nThe suite derives these values from `global.iris`. Don't set them under `intent:`: a value that differs fails the render and names the field.\n\n- `tenantId` and `license.*`, from `global.iris.tenantId` and `global.iris.license`.\n- `dataplane.identityServiceBaseURL` and `identityService.allowInsecureTransport`, which point at the suite's Identity Service.\n- `identityService.credential` and `controlplane.internalToken`, which the suite generates or reads from `global.iris.secrets`. The suite registers them and the tenant on its Identity Service, so skip [Configure the Identity Service release first](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/deploy#configure-the-identity-service-release-first).\n- `auth.oidc.audience`, `dataplane.oidc`, and `controlplane.oidc.enabled`, from `global.iris.auth`.\n\nThe suite also fixes `fullnameOverride`, the Service ports, `dataplane.strategy`, and `podDisruptionBudget.enabled`, and runs two data-plane replicas by default. Its Services are `redis-intent-router-controlplane`, `redis-intent-router-dataplane`, and `iris-identity-service`. By default it generates the admin token in the Secret `iris-intent-admin-token`. The suite chart doesn't support the FIPS profile.\n\nYou still set the storage Secret and the embedding model:\n\n[code example]\n\n[code example]\n\nThe rest of this guide applies to the values under `intent:`."
    },
    {
      "id": "next-steps",
      "title": "Next steps",
      "role": "content",
      "text": "- [Define intents and match queries](https://redis.io/docs/latest/develop/ai/context-engine/intent-router/quickstart).\n- [Operate the deployment](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/operations)."
    }
  ],
  "examples": [
    {
      "id": "1-create-the-namespace-ex0",
      "language": "bash",
      "code": "kubectl create namespace <namespace-name>",
      "section_id": "1-create-the-namespace"
    },
    {
      "id": "create-the-secrets-ex0",
      "language": "bash",
      "code": "umask 077\nfor token in admin-token internal-token dp-credential; do\n  openssl rand -base64 32 > \"$token\"\ndone\nkubectl -n <namespace-name> create secret generic intent-storage \\\n  --from-file=intent-controlplane-storage.yaml \\\n  --from-file=intent-dataplane-storage.yaml\nkubectl -n <namespace-name> create secret generic intent-license --from-file=license=./license\nkubectl -n <namespace-name> create secret generic intent-controlplane-admin --from-file=token=./admin-token\nkubectl -n <namespace-name> create secret generic intent-controlplane-internal --from-file=token=./internal-token\nkubectl -n <namespace-name> create secret generic intent-dp-credential --from-file=token=./dp-credential",
      "section_id": "create-the-secrets"
    },
    {
      "id": "4-install-ex0",
      "language": "bash",
      "code": "helm repo add redis-ai https://helm.redis.io/ai\nhelm repo update redis-ai\nhelm install intent redis-ai/redis-intent-router \\\n  --version 1.0.0 \\\n  --namespace <namespace-name> \\\n  -f intent-values.yaml \\\n  --wait --timeout 5m",
      "section_id": "4-install"
    },
    {
      "id": "5-verify-pods-and-health-ex0",
      "language": "bash",
      "code": "kubectl -n <namespace-name> rollout status deployment/intent-redis-intent-router-controlplane\nkubectl -n <namespace-name> rollout status deployment/intent-redis-intent-router-dataplane",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "5-verify-pods-and-health-ex1",
      "language": "bash",
      "code": "kubectl -n <namespace-name> port-forward svc/intent-redis-intent-router-controlplane 9400:9400",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "5-verify-pods-and-health-ex2",
      "language": "bash",
      "code": "kubectl -n <namespace-name> port-forward svc/intent-redis-intent-router-dataplane 9401:9401",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "5-verify-pods-and-health-ex3",
      "language": "bash",
      "code": "kubectl -n <namespace-name> port-forward svc/ids-iris-identity-service 9200:9200",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "5-verify-pods-and-health-ex4",
      "language": "bash",
      "code": "curl -sS http://localhost:9400/health/readiness\ncurl -sS http://localhost:9401/health/readiness\ncurl -sS http://localhost:9200/health/readiness",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "6-create-a-router-ex0",
      "language": "bash",
      "code": "export IRIS_INTENT_ROUTER_SERVICE_URL='http://localhost:9400'\nexport IRIS_INTENT_ROUTER_SERVICE_TOKEN=\"$(kubectl -n <namespace-name> get secret \\\n  intent-controlplane-admin -o jsonpath='{.data.token}' | base64 --decode)\"",
      "section_id": "6-create-a-router"
    },
    {
      "id": "8-make-one-authenticated-call-ex0",
      "language": "bash",
      "code": "curl -sS -X POST \"$IRIS_INTENT_ROUTER_URL/iris/data/v1/intent/routers/$IRIS_INTENT_ROUTER_ID/match\" \\\n  -H \"Authorization: Bearer $IRIS_INTENT_ROUTER_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"query\": \"hello\"}'",
      "section_id": "8-make-one-authenticated-call"
    },
    {
      "id": "install-with-the-redis-iris-suite-chart-ex0",
      "language": "yaml",
      "code": "intent:\n  storage:\n    existingSecret: intent-storage\n  inference:\n    existingSecret: intent-inference\n    models:\n      - provider: openai\n        model: text-embedding-3-small\n        dimensions: 1536",
      "section_id": "install-with-the-redis-iris-suite-chart"
    },
    {
      "id": "install-with-the-redis-iris-suite-chart-ex1",
      "language": "bash",
      "code": "helm install iris redis-ai/redis-iris \\\n  --version 1.0.0 \\\n  --namespace <namespace-name> \\\n  -f iris-values.yaml",
      "section_id": "install-with-the-redis-iris-suite-chart"
    }
  ]
}
