# Self-managed Lens prerequisites

```json metadata
{
  "schema_version": 2,
  "title": "Self-managed Lens prerequisites",
  "description": "Check the software, Redis databases, Identity Service, network access, and Secrets you need before you deploy Lens.",
  "categories": ["docs","operate","iris"],
  "tableOfContents": {"sections":[{"id":"what-you-need","title":"What you need"},{"id":"redis-databases","title":"Redis databases"},{"id":"network-access","title":"Network access"},{"id":"secrets","title":"Secrets"},{"id":"helm-values-that-stop-an-install","title":"Helm values that stop an install"}]}

,
  "codeExamples": []
}
```


Self-managed Lens runs on your Kubernetes cluster and depends on Redis databases, an Identity Service release, and Secrets that you set up first. The chart creates none of them. This page lists what you need before you [deploy the chart](https://redis.io/docs/latest/operate/iris/lens/self-managed/deploy).

## What you need

| Requirement | Detail |
| --- | --- |
| Kubernetes | Kubernetes 1.28 or later, and a namespace for the release. |
| Helm | Helm 3.10 or later. Helm 4 isn't supported. |
| `kubectl`, `curl`, and `jq` | For the install and administration examples. |
| Identity Service | The `iris-identity-service` chart at the same version as the Lens chart, `1.0.0`, installed as its own release. |
| Redis databases | A records database, a content database, and a metadata Redis, as described in [Redis databases](#redis-databases). |
| Container images | Docker Hub: `redislabs/iris-lens-data` (data plane and worker) and `redislabs/iris-lens-control` (control plane). |
| Helm chart | `redis-lens` chart `1.0.0` in the Redis AI Helm repository, `https://helm.redis.io/ai`. |
| License key | Contact your Redis representative or [contact sales](https://redis.io/contact/). |

## Redis databases

Lens stores its data in four roles. Map them onto your databases like this:

| Role | Holds | Requirements |
| --- | --- | --- |
| `streams` | Received steps, before the worker assembles them into turns. | A RAM database, not Redis Flex, with `maxmemory-policy noeviction`. |
| `index` | Turns, sessions, and their search indexes. | A RAM database, not Redis Flex, with the Redis Search and Redis JSON modules. Usually the same database as `streams`. |
| `content` | Captured prompts, responses, and tool payloads. | Redis Flex or RAM. It can be the same database as `streams` and `index`. |
| `metadata` | The Lens instance record. | A separate small Redis. Don't put it on a database that holds telemetry. |

Together, `streams` and `index` make up the records database. A Redis Flex records database fails index creation at startup with an error that says so. The Identity Service keeps its own metadata, separate from the Lens `metadata` role.

Nothing trims the `streams` role yet, and it must not evict keys, so its memory grows while ingest is on. Size the records database for the traffic you expect and watch it, as described in [Watch the records database](https://redis.io/docs/latest/operate/iris/lens/self-managed/operations#watch-the-records-database).

## Network access

| From | To | Why |
| --- | --- | --- |
| Agents | Data plane `9000` | Send turns. |
| Lens UI and read clients | Data plane `9000` | Read sessions and turns. |
| Operators | Control plane `9300` | Read and change the instance's retention. |
| Operators | Identity Service `9200` | Mint and revoke API keys. |
| Identity Service | Control plane `9300` | Validate key grants. |
| Data plane | Identity Service `9200` | Check API keys. |
| Data plane, worker, control plane | Redis databases | Storage. |
| Data plane and control plane | Your identity provider's JSON Web Key Set (JWKS) URL | Only when you turn on [operator sign-in](https://redis.io/docs/latest/operate/iris/lens/self-managed/authentication#operator-sign-in). |

The worker needs no Identity Service access. The chart creates no Ingress: to reach Lens from outside the cluster, publish the data plane through your own Transport Layer Security (TLS) ingress, as described in [Expose the data plane](https://redis.io/docs/latest/operate/iris/lens/self-managed/deploy#expose-the-data-plane).

The chart renders no NetworkPolicy objects. Its package includes `networkpolicy.reference.yaml`, a default-deny starting point for these flows. Replace every `<placeholder>` before you apply it.

## Secrets

Create these Secrets before you install Lens. [Deploy](https://redis.io/docs/latest/operate/iris/lens/self-managed/deploy#2-create-secrets) shows the commands.

| Secret | Holds | Mounted by |
| --- | --- | --- |
| Storage | One configuration file per process with the Redis URLs. See [Storage Secret](https://redis.io/docs/latest/operate/iris/lens/self-managed/configuration#storage-secret). | Lens |
| License | The Lens license, under the key `license`. | Lens |
| Data-plane runtime credential | A random token the data plane presents to the Identity Service. | Lens and the Identity Service |
| Control-plane internal token | A random token the Identity Service presents to the control plane. | Lens and the Identity Service |
| Identity Service metadata | The Identity Service's metadata Redis URL. | The Identity Service |
| Identity Service control token | The token operators use to mint API keys. | The Identity Service |

The chart generates the control-plane admin token for you. See [Credentials](https://redis.io/docs/latest/operate/iris/lens/self-managed/authentication#credentials).

## Helm values that stop an install

Rendering fails with a named message when:

- `tenantId`, `storage.existingSecret`, or `license.existingSecret` is missing.
- `dataplane.image.tag` or `controlplane.image.tag` is empty.
- `dataplane.identityServiceBaseURL` or `identityService.credential.existingSecret` is missing.
- `dataplane.identityServiceBaseURL` isn't `https://` and `identityService.allowInsecureTransport` isn't `true`.
- Two of the admin token, internal token, and runtime credential reference the same Secret key.
- `instance.id` doesn't match `^[A-Za-z0-9._:-]{1,128}$`.

A storage file that omits a role passes rendering, because Helm can't read the Secret. The pod then fails at startup and names the missing key, for example `create Lens streams Redis client from storage.streams.urls: redis url list is empty`.

