{
  "schema_version": 2,
  "id": "operate/iris/agent-memory/self-managed/deploy",
  "title": "Deploy Redis Agent Memory",
  "url": "https://redis.io/docs/latest/operate/iris/agent-memory/self-managed/deploy/",
  "summary": "Install Redis Agent Memory with chart-rendered configuration and agent-key authentication, then make one authenticated call.",
  "aliases": [
    "/develop/ai/context-engine/agent-memory/self-managed/control-plane/",
    "/develop/ai/context-engine/agent-memory/self-managed/deploy-control-plane/",
    "/operate/iris/agent-memory/self-managed/deploy-control-plane/",
    "/develop/ai/context-engine/agent-memory/self-managed/install-k8s/",
    "/develop/ai/context-engine/agent-memory/self-managed/deploy-static/",
    "/operate/iris/agent-memory/self-managed/deploy-static/"
  ],
  "tags": [
    "docs",
    "operate",
    "iris"
  ],
  "last_updated": "2026-10-21T18:51:10+03:00",
  "page_type": "content",
  "content_hash": "42dd2c525189a52bc35339c4c694cdd1c0f34ca9edebbdd5e49e52104d954ed6",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "These steps install Redis Agent Memory with chart-rendered configuration and agent-key\nauthentication, and end with one authenticated call to the Data Plane.\n\nInstall Identity Service as release `ids`, then Memory as release `redis-agent-memory`.\nThese steps use Memory chart `0.8.0` and Identity Service chart `0.10.0` in one namespace.\nYou create the shared credentials and Identity Service control token; Memory generates its\nControl Plane admin token. See [Credentials](https://redis.io/docs/latest/operate/iris/agent-memory/self-managed/authentication#credentials).\n\nBefore installing, provide two Transport Layer Security (TLS) endpoints through your hosting\nenvironment: one forwarding to `ids-iris-identity-service:9200`, and one forwarding to\n`redis-agent-memory-controlplane:9100`. Neither chart terminates TLS. Replace the endpoint\nplaceholders with addresses reachable from the calling pods. Obtain their certificate authority\n(CA) certificates as a PEM bundle named `service-ca.crt`; use your organization's trust bundle\nif the endpoints use public certificates.\n\nBefore you begin, review the [prerequisites](https://redis.io/docs/latest/operate/iris/agent-memory/self-managed/prerequisites)."
    },
    {
      "id": "isolated-lab-without-tls",
      "title": "Isolated lab without TLS",
      "role": "content",
      "text": "For a network-isolated lab without the Federal Information Processing Standards (FIPS) profile,\nyou can use the in-cluster HTTP Services instead of TLS frontends. In `ram-values.yaml`, change:\n\n[code example]\n\nIn `values-ids.yaml`, change the validator URL to\n`productValidation.products.memory.baseURL: http://redis-agent-memory-controlplane:9100`.\nKeep the other settings in both files. Tokens travel over plaintext HTTP on these two hops;\nuse TLS for production. FIPS refuses this configuration.\n\nFor this lab option, skip `service-ca.crt` and the initial `ram-ca` creation in step 2, and omit\n`tls` from `values-ids.yaml`. For self-managed worker identity, still create `ram-ca` from the\ncluster CA as described in [Prepare worker identity](#prepare-worker-identity-for-your-platform).\nOn EKS and AKS, omit Memory's `tls` block too unless another connection requires a private CA."
    },
    {
      "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": "[code example]\n\nBoth releases mount `memory-dp-credential` and `memory-internal-token`. You own these Secrets;\nneither release generates them in this procedure. The runtime credential lets Memory check\nagent keys. The internal token lets Identity Service validate grants against Memory's Control\nPlane. The `ids-control-token` Secret is separate and is used only by Identity Service.\n\n`overlay.yaml` holds the Redis addresses and provider credentials. The Data Plane, the workers, and\nthe Control Plane all mount it:\n\n[code example]\n\n`ids-metadata.yaml` tells the Identity Service where Metadata Redis is:\n\n[code example]"
    },
    {
      "id": "install-identity-service-first",
      "title": "Install Identity Service first",
      "role": "setup",
      "text": "Save this as `values-ids.yaml`:\n\n[code example]\n\n[code example]\n\nThe Memory Control Plane does not exist yet. Configure its endpoint now, but wait until both\nreleases and the TLS routes are ready before minting keys: Identity Service calls the Control\nPlane to validate each store grant."
    },
    {
      "id": "prepare-worker-identity-for-your-platform",
      "title": "Prepare worker identity for your platform",
      "role": "content",
      "text": "With agent-key authentication, workers call the Data Plane with their projected service account\ntoken, and the Data Plane checks that token against the cluster's JSON Web Key Set (JWKS). The\nchart's defaults disagree here: the Data Plane defaults to `agent_key` authentication, while\n`workerAuth.enabled` defaults to `false`. With `agent_key`, you must configure worker identity. The\nvalues in [step 3](#3-create-ram-valuesyaml) do this.\n\nThe Data Plane fetches the JWKS without credentials and trusts only the\ncertificate authority (CA) bundle in its image. What you set up depends on where the cluster's\nissuer is served:\n\n| Cluster | `issuer` | `jwks_uri` | Extra steps | Tested |\n|---------|----------|------------|-------------|--------|\n| Self-managed (kind, kubeadm, on-premises) | from `kubectl get --raw /.well-known/openid-configuration` (kind: `https://kubernetes.default.svc.cluster.local`) | `https://kubernetes.default.svc/openid/v1/jwks` | `ram-ca` Secret containing the cluster CA + `tls.caCertSecret: ram-ca` + ClusterRoleBinding (cluster admin's decision) | Yes, on kind |\n| Amazon Elastic Kubernetes Service (EKS) | `aws eks describe-cluster --name <cluster> --query cluster.identity.oidc.issuer --output text` | the `jwks_uri` field of `<issuer>/.well-known/openid-configuration` | Data Plane egress to the issuer host, or the `com.amazonaws.<region>.oidc-eks` PrivateLink endpoint with private DNS. The hostname differs for IPv6 clusters and AWS China, so copy it, don't type it | No |\n| Azure Kubernetes Service (AKS), OpenID Connect (OIDC) issuer enabled | `az aks show -n <cluster> -g <resource-group> --query oidcIssuerProfile.issuerUrl -o tsv` (exact, including the trailing slash) | the `jwks_uri` field of `<issuer>.well-known/openid-configuration` | Data Plane egress. The issuer is on by default only for new Standard clusters on 1.34+ and on AKS Automatic. `--enable-oidc-issuer` on an existing cluster restarts the API server and cannot be undone | No |\n| Google Kubernetes Engine (GKE) | as self-managed | as self-managed | as self-managed, because anonymous access to the GKE `jwks` endpoint is not verified | No |\n| Air-gapped (any) | as self-managed | as self-managed | as self-managed | Yes, on kind |\n\nAlways take `jwks_uri` from the discovery document. Don't build it from the issuer, because the AKS\npath differs. On EKS and AKS, replace `issuer` and `jwks_uri` in the values and skip\nthe rest of this section. With TLS service endpoints, keep `tls.caCertSecret: ram-ca`\nfor their trust bundle. For the HTTP-only lab option, omit this block unless another connection\nrequires a private CA.\n\nOn self-managed, GKE, and air-gapped clusters, add the cluster CA to the service CA bundle\nso the Data Plane also trusts the API server certificate:\n\n[code example]\n\nFor the HTTP-only lab option, use `cp cluster-ca.crt ram-ca.crt` instead of the `cat` command;\nthere is no service CA file to combine.\n\nThe Data Plane also needs to read the JWKS without logging in. Allowing that is the cluster\nadmin's decision:\n\n[code example]\n\nThis binding grants only `get` on `/.well-known/openid-configuration` and `/openid/v1/jwks`, which\nserve issuer metadata and public signing keys, not secrets. It applies to unauthenticated callers\nacross the whole cluster. It has no effect where the API server disables anonymous authentication.\nOn those clusters, there is no working setup for `agent_key` with workers."
    },
    {
      "id": "3-create-ram-valuesyaml",
      "title": "3. Create `ram-values.yaml`",
      "role": "content",
      "text": "[code example]\n\n- `<chat-model>` is any chat model the endpoint serves.\n- `controlplane.configData.embedding.dimensions` must equal `memory.embedding.models.dimensions`.\n- `background_jobs.idempotency.enabled` prevents successful jobs from running again after\n  redelivery and serializes extraction for the same session. The walkthrough enables it for\n  workers and supplies its Redis URL through the overlay. Keep it enabled in production;\n  without it, workers warn that duplicate memories remain possible. This is separate from\n  queue submission deduplication.\n- `<service-account-issuer>` is the cluster's issuer. Read it with:\n\n  [code example]\n\n- `tls.caCertSecret` names the CA bundle from [step 2](#2-create-secrets).\n- The chart writes the agent-key introspection settings and mounts `memory-dp-credential` at\n  `/etc/identity-service/runtime/memory-dp/token`. Do not hand-set the introspection endpoint or credential under `memory.auth` or `shared.auth`.\n- `tenantId: default` matches `runtime.apiKeyTenant.singleTenantID` in `values-ids.yaml`.\n  The Control Plane creates admin-token stores in this tenant.\n- The published Memory chart defaults `image.tag` and `controlplane.image.tag` to `0.8.0`;\n  the example pins them explicitly. Identity Service uses its own chart's application version,\n  `0.10.0`, independently.\n\n\nNo external model provider? To try the API with local models, see [Evaluate locally](#evaluate-locally)."
    },
    {
      "id": "before-you-install-check-your-values",
      "title": "Before you install: check your values",
      "role": "content",
      "text": "Check each value in `ram-values.yaml` before you install. If one is wrong, you see the symptom in\nits row. The rows are checklist items CL-1 to CL-6.\n\n| Row | Check | Symptom | Fix |\n| --- | --- | --- | --- |\n| <a id=\"cl-1\"></a>CL-1 | `memory.license.license_path` is set | Server and worker pods `CrashLoopBackOff`; log: `initialize license enforcement: license validation failed; refusing to start: invalid license format` | Set `memory.license.license_path: /etc/redis-agent-memory/license` |\n| <a id=\"cl-2\"></a>CL-2 | `memory.promote_session_memory.strategies.instruct.llm` is set | Worker pods `CrashLoopBackOff` (server stays Ready); log: `promote_session_memory: Strategies: strategies.instruct.llm is required.` | Add the `instruct.llm` block |\n| <a id=\"cl-3\"></a>CL-3 | Each `llm.provider` names an `inference_providers` entry | Server and worker pods `CrashLoopBackOff`; log: `panic: config validation failed: promote_session_memory.strategies.instruct.llm: provider \"<name>\" is not defined in inference_providers (defined: <names>)` | Add `memory.inference_providers.<name>` or fix the name |\n| <a id=\"cl-4\"></a>CL-4 | `memory.dataplane_client.base_url` is `http://redis-agent-memory:9000` | Pods Ready, but no memories appear; worker log: `getting session memory: Get \"http://<wrong-host>:9000/v1/stores/<store-id>/session-memory/...\"` … `dial tcp: lookup <wrong-host>` (the rest depends on the cluster DNS) | Set `http://redis-agent-memory:9000` |\n| <a id=\"cl-5\"></a>CL-5 | Any overridden image tags exist in the chosen registry | Pods `ImagePullBackOff`, event: `Failed to pull image \"redislabs/agent-memory:<tag>\": … not found` | Use the published defaults or valid mirrored tags for each release |\n| <a id=\"cl-6\"></a>CL-6 | `auth.worker_identity` matches the worker (issuer, audience, subject with your namespace) | Pods Ready, but no memories appear; worker log: `memory-dataplane API error: status 401`; the Data Plane logs `401` on `GET /v1/stores/<store-id>/session-memory/<session-id>` with no reason | Fix `issuer` from `/.well-known/openid-configuration` and the namespace in `subject`. The same symptom appears when the Data Plane cannot fetch the cluster JWKS, so also check [worker identity for your platform](#prepare-worker-identity-for-your-platform) |"
    },
    {
      "id": "4-install",
      "title": "4. Install",
      "role": "content",
      "text": "[code example]\n\nOn small clusters, install without `--atomic --wait`, as shown, and watch pod status.\n\nIf you want Helm to wait, set an explicit timeout that matches the environment:\n\n[code example]"
    },
    {
      "id": "5-verify-pods-and-health",
      "title": "5. Verify pods and health",
      "role": "content",
      "text": "[code example]\n\nThe server, worker, and `redis-agent-memory-controlplane` pods must be Ready.\nCheck the separate Identity Service release too:\n\n[code example]\n\nWait for its pod to be Ready. With TLS frontends, verify that both configured endpoints route\nto their Services before creating a key. For the HTTP-only lab option, verify that both\nin-cluster Service addresses are reachable from the calling pods.\n\nRun each `port-forward` in this guide in its own terminal. Port-forward the Data Plane and check its\nhealth. The health check doesn't need an agent key:\n\n[code example]\n\nThe response is:\n\n[code example]"
    },
    {
      "id": "6-create-a-store",
      "title": "6. Create a store",
      "role": "content",
      "text": "Use the Control Plane admin token:\n\n[code example]\n\nThe response carries `storeId`."
    },
    {
      "id": "7-mint-an-agent-key",
      "title": "7. Mint an agent key",
      "role": "content",
      "text": "Use the Identity Service control token:\n\n[code example]\n\nUse the same tenant as `tenantId` and `runtime.apiKeyTenant.singleTenantID`, here `default`.\nThe response's `token` is the agent key. It is shown only once."
    },
    {
      "id": "8-make-one-authenticated-call",
      "title": "8. Make one authenticated call",
      "role": "content",
      "text": "[code example]\n\nThe first long-term memories appear up to 5 minutes after the session events, because promotion\nruns at the end of a clock-aligned 300-second window. To shorten the wait, set\n`extractionCadence.activeIntervalSeconds` (60–600) on the store. No API triggers promotion."
    },
    {
      "id": "evaluate-locally",
      "title": "Evaluate locally",
      "role": "content",
      "text": "This setup runs with no external model provider. The `noop` embedder produces meaningless vectors,\nand a small local model produces rough extractions. Use it to try the API, not to judge quality or\nfor production.\n\nSave this Deployment and Service as `ollama.yaml`. Replace `<ollama-version>` with 0.13.3 or later:\n\n[code example]\n\nDeploy it in the release namespace:\n\n[code example]\n\nThe first start downloads about 2 GB.\n\nEdit the existing `ram-values.yaml`: replace the complete `memory.embedding`,\n`memory.embedders_connection_details`, `memory.inference_providers`, and\n`memory.promote_session_memory` maps with the corresponding maps in this snippet. Also update\n`controlplane.configData.embedding.dimensions`. Keep the other settings, including authentication,\nworker callbacks, and `background_jobs.idempotency`.\n\nApply these edits to the existing file. Passing the snippet as another `-f` file merges the maps\nand retains old OpenAI entries.\n\n[code example]\n\n`api_key: ollama` is a placeholder. The client requires a key, and Ollama ignores it.\n\nReplace `overlay.yaml` with the Redis-only overlay, removing the complete\n`embedders_connection_details` and `promote_session_memory` blocks:\n\n[code example]\n\nIf Memory is already installed, update the `ram-secrets` Secret from this file, upgrade with\nthe edited values, and restart the Data Plane, workers, and Control Plane so they reload the\noverlay. See [Secret rotation](https://redis.io/docs/latest/operate/iris/agent-memory/self-managed/operations#secret-rotation).\n\nUse this provider switch only in a disposable evaluation installation. Changing the settings\ndoes not migrate existing stores or their vector indexes. After switching, create a new store\nand agent key using steps 6–7 for local evaluation. Existing stores retain their original\nembedding dimensions and cannot be reused with this example."
    },
    {
      "id": "next-steps",
      "title": "Next steps",
      "role": "content",
      "text": "- [API examples](https://redis.io/docs/latest/operate/iris/agent-memory/self-managed/api-examples) for the full API.\n- [Operations](https://redis.io/docs/latest/operate/iris/agent-memory/self-managed/operations) for key rotation."
    }
  ],
  "examples": [
    {
      "id": "isolated-lab-without-tls-ex0",
      "language": "yaml",
      "code": "dataplane:\n  identityServiceBaseURL: http://ids-iris-identity-service:9200\nidentityService:\n  allowInsecureTransport: true\n  credential:\n    existingSecret: memory-dp-credential",
      "section_id": "isolated-lab-without-tls"
    },
    {
      "id": "1-create-the-namespace-ex0",
      "language": "bash",
      "code": "kubectl create namespace <namespace-name>",
      "section_id": "1-create-the-namespace"
    },
    {
      "id": "2-create-secrets-ex0",
      "language": "bash",
      "code": "kubectl -n <namespace-name> create secret generic ram-license \\\n  --from-file=license=./ram-license.key\nkubectl -n <namespace-name> create secret generic ram-secrets \\\n  --from-file=overlay.yaml=./overlay.yaml\nkubectl -n <namespace-name> create secret generic ram-ids-metadata \\\n  --from-file=metadata.yaml=./ids-metadata.yaml\nkubectl -n <namespace-name> create secret generic memory-dp-credential \\\n  --from-literal=token=\"$(openssl rand -hex 32)\"\nkubectl -n <namespace-name> create secret generic memory-internal-token \\\n  --from-literal=token=\"$(openssl rand -hex 32)\"\nkubectl -n <namespace-name> create secret generic ids-control-token \\\n  --from-literal=token=\"$(openssl rand -hex 32)\"\nkubectl -n <namespace-name> create secret generic ram-ca \\\n  --from-file=ca.crt=./service-ca.crt --save-config",
      "section_id": "2-create-secrets"
    },
    {
      "id": "2-create-secrets-ex1",
      "language": "yaml",
      "code": "metadata:\n  urls: [\"redis://<metadata-redis-host>:6379\"]\ndatabases:\n  \"1\":\n    urls: [\"redis://<store-redis-host>:6379\"]\nbackground_jobs:\n  redis:\n    urls: [\"redis://<job-redis-host>:6379\"]\n  idempotency:\n    urls: [\"redis://<job-redis-host>:6379\"]\nembedders_connection_details:\n  openai:\n    credentials:\n      api_key: <openai-api-key>\npromote_session_memory:\n  strategies:\n    instruct:\n      llm:\n        credentials:\n          api_key: <openai-api-key>",
      "section_id": "2-create-secrets"
    },
    {
      "id": "2-create-secrets-ex2",
      "language": "yaml",
      "code": "metadata:\n  urls: [\"redis://<metadata-redis-host>:6379\"]",
      "section_id": "2-create-secrets"
    },
    {
      "id": "install-identity-service-first-ex0",
      "language": "yaml",
      "code": "metadata:\n  existingSecret: ram-ids-metadata\ncontrol:\n  existingSecret: ids-control-token\n  autoGenerate: false\nruntime:\n  unscopedGrantsProduct: memory\n  apiKeyTenant:\n    singleTenantID: default\n  serviceCredentials:\n    - name: memory-dp\n      subject: memory-dp\n      allowedOperations: [api-key-introspect]\n      allowedProducts: [memory]\n      existingSecret: memory-dp-credential\n      secretKey: token\nproductValidation:\n  products:\n    memory:\n      baseURL: https://<control-plane-tls-endpoint>\n      credential:\n        existingSecret: memory-internal-token\n        secretKey: token\ntls:\n  caCertSecret: ram-ca",
      "section_id": "install-identity-service-first"
    },
    {
      "id": "install-identity-service-first-ex1",
      "language": "bash",
      "code": "helm repo add redis-ai https://helm.redis.io/ai\nhelm repo update redis-ai\nhelm install ids redis-ai/iris-identity-service \\\n  --version 0.10.0 \\\n  --namespace <namespace-name> \\\n  -f values-ids.yaml",
      "section_id": "install-identity-service-first"
    },
    {
      "id": "prepare-worker-identity-for-your-platform-ex0",
      "language": "bash",
      "code": "kubectl -n <namespace-name> get configmap kube-root-ca.crt -o jsonpath=\"{.data.ca\\.crt}\" >./cluster-ca.crt\ncat service-ca.crt cluster-ca.crt > ram-ca.crt\nkubectl -n <namespace-name> create secret generic ram-ca \\\n  --from-file=ca.crt=./ram-ca.crt --dry-run=client -o yaml | kubectl apply -f -",
      "section_id": "prepare-worker-identity-for-your-platform"
    },
    {
      "id": "prepare-worker-identity-for-your-platform-ex1",
      "language": "bash",
      "code": "kubectl create clusterrolebinding redis-agent-memory-oidc-discovery \\\n  --clusterrole=system:service-account-issuer-discovery --group=system:unauthenticated",
      "section_id": "prepare-worker-identity-for-your-platform"
    },
    {
      "id": "3-create-ram-valuesyaml-ex0",
      "language": "yaml",
      "code": "tenantId: default\ndataplane:\n  identityServiceBaseURL: https://<identity-service-tls-endpoint>\nidentityService:\n  credential:\n    existingSecret: memory-dp-credential\n    secretKey: token\nlicense:\n  existingSecret: ram-license\nconfig:\n  render: true\nsecrets:\n  secretName: ram-secrets\nshared:\n  databases:\n    \"1\":\n      name: default\nworkerAuth:\n  enabled: true\nmemory:\n  license:\n    license_path: /etc/redis-agent-memory/license\n  default_extraction_strategy: instruct\n  embedding:\n    provider: openai\n    models:\n      default_embedding_model: text-embedding-3-small\n      dimensions: 1536\n  embedders_connection_details:\n    openai:\n      base_url: https://api.openai.com\n      credentials:\n        type: static\n  inference_providers:\n    openai:\n      endpoint:\n        base_url: https://api.openai.com/v1\n        timeout: 30s\n        auth_format: bearer\n  promote_session_memory:\n    strategies:\n      instruct:\n        llm:\n          provider: openai\n          credentials:\n            type: static\n          models:\n            default_chat_model: <chat-model>\n  background_jobs:\n    idempotency:\n      enabled: true\n    redis:\n      enabled: true\n      queue_prefix: ram\n      worker_regions: [default]\n  request_region:\n    default: default\n  dataplane_client:\n    base_url: http://redis-agent-memory:9000\n    auth:\n      disabled: false\n      type: service_account_token\n      token_file: /var/run/secrets/redis-agent-memory-worker/token\n  auth:\n    method: agent_key\n    worker_identity:\n      enabled: true\n      issuer: <service-account-issuer>\n      jwks_uri: https://kubernetes.default.svc/openid/v1/jwks\n      audience:\n        - redis-agent-memory\n      subjects:\n        - subject: \"system:serviceaccount:<namespace-name>:redis-agent-memory-worker\"\n          user_id: redis-agent-memory-worker\n          roles:\n            - operator\n          resources:\n            \"mem-store:*\":\n              permissions:\n                - write\n  session_summarisation:\n    enabled: false\n  session_summary_view:\n    enabled: false\nimage:\n  tag: \"0.8.0\"\ncontrolplane:\n  internalToken:\n    existingSecret: memory-internal-token\n  image:\n    tag: \"0.8.0\"\n  config:\n    render: true\n  configData:\n    profile: prod\n    auth:\n      type: admin-token\n      admin_token:\n        token_file: /etc/controlplane-onprem/admin/token\n    license:\n      license_path: /etc/redis-agent-memory/license\n    embedding:\n      dimensions: 1536\ntls:\n  caCertSecret: ram-ca",
      "section_id": "3-create-ram-valuesyaml"
    },
    {
      "id": "3-create-ram-valuesyaml-ex1",
      "language": "bash",
      "code": "kubectl get --raw /.well-known/openid-configuration | jq -r .issuer",
      "section_id": "3-create-ram-valuesyaml"
    },
    {
      "id": "4-install-ex0",
      "language": "bash",
      "code": "helm repo add redis-ai https://helm.redis.io/ai\nhelm repo update redis-ai\nhelm install redis-agent-memory redis-ai/redis-agent-memory \\\n  --version 0.8.0 \\\n  --namespace <namespace-name> \\\n  -f ram-values.yaml\nkubectl -n <namespace-name> get pods -w",
      "section_id": "4-install"
    },
    {
      "id": "4-install-ex1",
      "language": "bash",
      "code": "helm install redis-agent-memory redis-ai/redis-agent-memory \\\n  --version 0.8.0 \\\n  --namespace <namespace-name> \\\n  -f ram-values.yaml \\\n  --wait \\\n  --timeout 15m",
      "section_id": "4-install"
    },
    {
      "id": "5-verify-pods-and-health-ex0",
      "language": "bash",
      "code": "kubectl -n <namespace-name> get pods -l app.kubernetes.io/name=redis-agent-memory",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "5-verify-pods-and-health-ex1",
      "language": "bash",
      "code": "kubectl -n <namespace-name> get pods -l app.kubernetes.io/instance=ids",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "5-verify-pods-and-health-ex2",
      "language": "bash",
      "code": "kubectl -n <namespace-name> port-forward svc/redis-agent-memory 9000:9000\ncurl http://localhost:9000/health/readiness",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "5-verify-pods-and-health-ex3",
      "language": "json",
      "code": "{\"status\":\"ready\"}",
      "section_id": "5-verify-pods-and-health"
    },
    {
      "id": "6-create-a-store-ex0",
      "language": "bash",
      "code": "kubectl -n <namespace-name> port-forward svc/redis-agent-memory-controlplane 9100:9100\nRAM_ADMIN_TOKEN=$(kubectl -n <namespace-name> get secret \\\n  redis-agent-memory-controlplane-admin-token -o jsonpath='{.data.token}' | base64 -d)\ncurl -sS -X POST http://localhost:9100/v1/stores \\\n  -H \"Authorization: Bearer $RAM_ADMIN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"my-store\"}'",
      "section_id": "6-create-a-store"
    },
    {
      "id": "7-mint-an-agent-key-ex0",
      "language": "bash",
      "code": "kubectl -n <namespace-name> port-forward svc/ids-iris-identity-service 9200:9200\nIDS_CONTROL_TOKEN=$(kubectl -n <namespace-name> get secret \\\n  ids-control-token -o jsonpath='{.data.token}' | base64 -d)\ncurl -sS -X POST http://localhost:9200/v1/api-keys \\\n  -H \"Authorization: Bearer $IDS_CONTROL_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"my-agent-key\",\n    \"grants\": [\n      {\n        \"tenant\": \"default\",\n        \"product\": \"memory\",\n        \"resourceType\": \"mem-store\",\n        \"resourceId\": \"<store-id>\",\n        \"actions\": [\"read\", \"write\"]\n      }\n    ]\n  }'",
      "section_id": "7-mint-an-agent-key"
    },
    {
      "id": "8-make-one-authenticated-call-ex0",
      "language": "bash",
      "code": "curl -sS -X POST \"http://localhost:9000/v1/stores/<store-id>/session-memory/events\" \\\n  -H \"Authorization: Bearer <agent-key>\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"sessionId\": \"session-001\",\n    \"actorId\": \"user-001\",\n    \"role\": \"USER\",\n    \"content\": [{\"text\": \"What is the capital of France?\"}],\n    \"createdAt\": \"2026-06-25T18:00:00Z\"\n  }'",
      "section_id": "8-make-one-authenticated-call"
    },
    {
      "id": "evaluate-locally-ex0",
      "language": "yaml",
      "code": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: ollama\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: ollama\n  template:\n    metadata:\n      labels:\n        app: ollama\n    spec:\n      containers:\n        - name: ollama\n          image: ollama/ollama:<ollama-version>   # 0.13.3 or later\n          env:\n            - name: OLLAMA_CONTEXT_LENGTH\n              value: \"8192\"\n          command: [\"/bin/sh\", \"-c\"]\n          args: [\"ollama serve & until ollama list >/dev/null 2>&1; do sleep 1; done; ollama pull qwen2.5:3b; wait\"]\n          ports:\n            - containerPort: 11434\n          resources:\n            requests:\n              cpu: \"2\"\n              memory: 4Gi\n          volumeMounts:\n            - name: models\n              mountPath: /root/.ollama\n      volumes:\n        - name: models\n          emptyDir: {}\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: ollama\nspec:\n  selector:\n    app: ollama\n  ports:\n    - port: 11434\n      targetPort: 11434",
      "section_id": "evaluate-locally"
    },
    {
      "id": "evaluate-locally-ex1",
      "language": "bash",
      "code": "kubectl -n <namespace-name> apply -f ollama.yaml",
      "section_id": "evaluate-locally"
    },
    {
      "id": "evaluate-locally-ex2",
      "language": "yaml",
      "code": "memory:\n  embedding:\n    provider: noop\n    models:\n      default_embedding_model: noop\n      dimensions: 384\n  embedders_connection_details:\n    noop:\n      protocol: noop\n  inference_providers:\n    ollama:\n      protocol: openai\n      endpoint:\n        base_url: http://ollama:11434/v1\n        timeout: 300s\n      http_client:\n        timeout: 300s\n  promote_session_memory:\n    strategies:\n      instruct:\n        llm:\n          provider: ollama\n          credentials:\n            type: static\n            api_key: ollama\n          models:\n            default_chat_model: qwen2.5:3b\ncontrolplane:\n  configData:\n    embedding:\n      dimensions: 384",
      "section_id": "evaluate-locally"
    },
    {
      "id": "evaluate-locally-ex3",
      "language": "yaml",
      "code": "metadata:\n  urls: [\"redis://<metadata-redis-host>:6379\"]\ndatabases:\n  \"1\":\n    urls: [\"redis://<store-redis-host>:6379\"]\nbackground_jobs:\n  redis:\n    urls: [\"redis://<job-redis-host>:6379\"]\n  idempotency:\n    urls: [\"redis://<job-redis-host>:6379\"]",
      "section_id": "evaluate-locally"
    }
  ]
}
