---
id: w7/m5/t001
title: Add spec.ipAllowList to the KeyValue CRD (mirror Database); regenerate manifests + deepcopy
worker: worker7
status: done
estimate: 30m
depends_on: []
---

## Objective

Give the `KeyValue` CR the same `ipAllowList` field the `Database` CR already carries, so the operator has something to project onto the public Valkey route. Field semantics mirror Render's `ipAllowList` and bex's Postgres field exactly: restricts the EXTERNAL (public) endpoint; empty ⇒ external endpoint open to all; only meaningful when `Public`.

## Context

- `lego/types/v1alpha1/database_types.go:66-71` — the reference field (`IPAllowList []string`, doc comment, `omitempty`).
- `lego/types/v1alpha1/keyvalue_types.go` — target; currently has no allowlist field.
- Codegen footgun (operator/CLAUDE.md): CRD types live in `types/`; run `make manifests generate` from `lego/operator/` after editing, keep the output (`zz_generated.deepcopy.go` + `config/crd/bases/`).

## Steps

1. Add `IPAllowList []string \`json:"ipAllowList,omitempty"\`` to the KeyValue spec, with a doc comment mirroring `database_types.go` (external-only, empty⇒open, meaningful only when Public).
2. From `lego/operator/`, run `make manifests generate`; keep the regenerated deepcopy + CRD YAML.
3. `cd lego/types && go build ./...` and `cd lego/operator && go build ./...`.

## Files

- `lego/types/v1alpha1/keyvalue_types.go`
- `lego/types/v1alpha1/zz_generated.deepcopy.go` (generated)
- `lego/operator/config/crd/bases/…keyvalue…yaml` (generated)

## Acceptance criteria

- [ ] `KeyValue.spec.ipAllowList` exists with a doc comment matching the Database field's semantics.
- [ ] `make manifests generate` produces the CRD/deepcopy changes with no other drift; both modules build.

## Out of scope

- Projecting the field onto the route (t002); surfacing it on the API (t003).
