llm-redact {{ .Chart.AppVersion }} installed as release "{{ .Release.Name }}".

The FOSS core needs no license, on Kubernetes or anywhere else. A license key
matters only to llm-redact-pro subsystems; when you use them, provide it via
the Secret named "{{ .Values.license.secretName }}" (key: license-key, optional).

{{ if eq .Values.mode "standalone" -}}
Mode: STANDALONE — a shared in-cluster proxy (Deployment + Service{{ if .Values.autoscaling.enabled }} + HorizontalPodAutoscaler{{ end }}).

  Agent pods reach the proxy at:
    http://{{ include "llm-redact.fullname" . }}.{{ .Release.Namespace }}.svc:{{ .Values.service.port }}

  Point your tool at it, e.g.:
    ANTHROPIC_BASE_URL / GOOGLE_GEMINI_BASE_URL = that URL,
    OPENAI_BASE_URL = that URL + /v1.

  The proxy answers to that Service's in-cluster names (allowed_hosts). A
  request that spends a credential the proxy holds (auth = "identity", a
  routed operator key) is refused when addressed by any other name — add
  such names (an Ingress host) with allowedHosts.

{{ if .Values.autoscaling.enabled -}}
  Autoscaling: {{ .Values.autoscaling.minReplicas }}–{{ .Values.autoscaling.maxReplicas }} replicas
  (CPU target {{ .Values.autoscaling.targetCPUUtilizationPercentage }}%). Every replica shares one
  vault backend "{{ .Values.vault.backend }}" so all pods issue consistent «TYPE_NNN» tokens —
  a per-pod vault would let one pod rehydrate another's secret (never-wrong-value).
  Chain / owner / Live-handle records are written in the background; with this
  shared backend the default [vault] map_writes = "before_answer" holds an answer
  that recorded something until its write landed, so a follow-up (previous_response_id,
  a Live resumption) may reach any pod — no session affinity needed. Past the 5 s
  bound, or with map_writes = "background", a follow-up reaching another pod before
  its write landed is refused or sealed, never wrong (then use session affinity).
{{ end -}}
  SECURITY: a standalone proxy serves other pods over the network, i.e. a
  NON-LOOPBACK bind. Prefer real mutual TLS — mount the cert Secret via
  extraVolumes/extraVolumeMounts and set [tls] certfile/keyfile/client_ca via
  `extraConfig`. insecureBind={{ .Values.insecureBind }} is the documented hatch for a
  TRUSTED in-cluster network only — pair it with networkPolicy.enabled=true
  (currently {{ .Values.networkPolicy.enabled }}); see docs/threat-model.md.
{{- if and (has .Values.vault.backend (list "postgresql" "mysql" "oracle" "dbapi")) (eq .Values.image.repository "ghcr.io/asanderson/llm-redact") (not (contains "pro" (.Values.image.tag | default .Chart.AppVersion))) }}

  *** WARNING: vault.backend = "{{ .Values.vault.backend }}" but the image tag
  "{{ .Values.image.tag | default .Chart.AppVersion }}" is the STOCK Free image, which ships without
  the RDBMS drivers and crypto extras — the proxy will REFUSE to start (missing
  driver / off-box-DSN-without-fernet), and a server RDBMS vault is an
  llm-redact-pro subsystem anyway. Use the llm-redact-pro image (paired with a
  license; it adds the crypto extra and the postgresql and mysql drivers),
  tagged with the llm-redact-pro version, not this chart's appVersion. It is
  in a private registry, so the pod needs an image pull secret:
    image.repository=ghcr.io/asanderson/llm-redact-pro  image.tag=<llm-redact-pro version>
    imagePullSecrets[0].name=<your ghcr.io pull secret>
  See docs/editions.md and the llm-redact-pro repo's docs/vault-rdbms.md.
{{- end }}
{{- else -}}
Mode: SIDECAR — the proxy runs in the SAME pod as your agentic tool and BINDS
127.0.0.1: containers in a pod share the network namespace, so the tool
reaches it over loopback while other pods cannot reach it at all. This is the
secure default: one replica, no Service, no HPA (probes are exec-based —
kubelet httpGet would need a pod-IP bind).
{{- if .Values.tool.enabled }}
{{- if eq .Values.tool.image "your-registry/your-agentic-tool:latest" }}

  *** WARNING: tool.image is still the placeholder
  "your-registry/your-agentic-tool:latest" — that container will
  ImagePullBackOff. Set tool.image to your agentic tool's image.
{{- end }}

  The tool container talks to the proxy over loopback; the provider base URLs
  are already wired to http://127.0.0.1:{{ .Values.service.port }}.
{{- else }}

  tool.enabled=false: this pod runs the proxy only. Add your agentic tool as
  a second container (tool.enabled=true + tool.image), or exec in to test:
    kubectl exec -it deploy/{{ include "llm-redact.fullname" . }} -c llm-redact -- llm-redact preview --text "test@corp.example"
{{- end }}
{{- end }}
{{- $grace := int64 (include "llm-redact.terminationGracePeriodSeconds" .) }}
{{- $budget := int64 (include "llm-redact.shutdownBudgetSeconds" .) }}
{{- $preStop := int64 0 }}
{{- if eq .Values.mode "standalone" }}{{ $preStop = int64 (include "llm-redact.preStopSleepSeconds" .) }}{{ end }}
{{- if lt $grace (add $budget $preStop) }}

*** WARNING: terminationGracePeriodSeconds={{ $grace }} is below the proxy's
bounded shutdown ({{ $budget }} s after in-flight requests finish: vault map
writes, the audit sinks' final flush, the vault close){{ if $preStop }} plus the
preStop delay ({{ $preStop }} s, preStopSleepSeconds){{ end }}. A pod killed sooner
loses the sinks' in-memory START/AMEND rows and closes no database cleanly.
See docs/resilience.md, "Shutdown order".
{{- end }}
{{- if and (eq .Values.vault.backend "sqlite") (not .Values.persistence.enabled) }}

*** WARNING: vault.backend=sqlite with persistence.enabled=false — the vault
lives on an emptyDir, so a pod restart WIPES it and previously issued token
numbers get reissued (never-wrong-value depends on the dense counter
surviving). Set persistence.enabled=true with a PersistentVolumeClaim.
{{- end }}
{{- if (.Values.models | default dict).volume }}

NER models: the models volume is mounted read-only at /models, and the proxy
runs with HF_HUB_OFFLINE=1 / TRANSFORMERS_OFFLINE=1. Load its folders with the
[detection.ner.models] lines `llm-redact models pull --to DIR --as /models`
printed (extraConfig), and check the volume:
  kubectl exec deploy/{{ include "llm-redact.fullname" . }} -c llm-redact -- llm-redact models verify --dir /models
{{- if ne (.Values.image.variant | default "") "ner" }}

*** WARNING: models.volume is set but image.variant is not "ner": the stock
image ships no NER extras, so an enabled hf or gliner backend refuses to
start. Set image.variant=ner (docs/air-gapped.md).
{{- end }}
{{- end }}

Check posture once the pod is up:
  kubectl exec deploy/{{ include "llm-redact.fullname" . }} -c llm-redact -- llm-redact status
