diff --git a/.env.example b/.env.example index 0fcbad0..6903d87 100644 --- a/.env.example +++ b/.env.example @@ -1,18 +1,21 @@ -# Copy to .env and fill in. Used by docker-compose; k8s pulls from the -# nvi-config ConfigMap (ctrl/k8s/base/configmap.yaml). +# Copy to `.env` (gitignored) and fill in. Two consumers: +# +# 1. k8s/kind path (tilt up): kustomize's secretGenerator in +# ctrl/k8s/base/kustomization.yaml reads this file and builds the +# nvi-secrets Secret. Non-secret config (DATABASE_URL, NVI_DATASET, +# *_MODEL, LANGFUSE_HOST, ...) lives in configmap.yaml — do not +# duplicate those here. +# 2. docker-compose fallback (ctrl/docker-compose.yml): compose reads +# the same file via the shell. -# Warehouse -DATABASE_URL=postgresql://nvi:nvi@postgres:5432/nvi - -# Active dataset (selects api/datasets// + Postgres schema + sqlite file). -NVI_DATASET=financial - -# LLM +# LLM API keys — set the one(s) matching your active LLM_PROVIDER. +GROQ_API_KEY= ANTHROPIC_API_KEY= -ANTHROPIC_MODEL=claude-sonnet-4-6 +# vLLM and other OpenAI-compatible self-hosted endpoints ignore auth; +# the literal placeholder is fine. +OPENAI_API_KEY=vllm-no-auth -# Langfuse — set LANGFUSE_HOST to your lng WireGuard endpoint; create an -# "nvi" project in the lng UI and paste its keys here. -LANGFUSE_HOST=http://lng.local.ar:3000 +# Langfuse (nivii project on the lng cluster). Both keys are project- +# scoped. Public key is safe by design; bundled for uniformity. LANGFUSE_PUBLIC_KEY= LANGFUSE_SECRET_KEY= diff --git a/ctrl/Tiltfile b/ctrl/Tiltfile index 522c2ec..a708843 100644 --- a/ctrl/Tiltfile +++ b/ctrl/Tiltfile @@ -16,7 +16,10 @@ if k8s_context() != 'kind-nvi': local('kubectl --context kind-nvi create namespace nvi --dry-run=client -o yaml | kubectl --context kind-nvi apply -f -') -k8s_yaml(kustomize('k8s/overlays/dev')) +# --load-restrictor=LoadRestrictionsNone: secretGenerator reads ../../../.env +# (repo root), which kustomize otherwise refuses for security. Safe here — +# it's our own repo, the path is explicit, and the only reachable file is .env. +k8s_yaml(kustomize('k8s/overlays/dev', flags=['--load-restrictor=LoadRestrictionsNone'])) # --- Images --- diff --git a/ctrl/k8s/base/api.yaml b/ctrl/k8s/base/api.yaml index 0736283..6fa025a 100644 --- a/ctrl/k8s/base/api.yaml +++ b/ctrl/k8s/base/api.yaml @@ -29,6 +29,8 @@ spec: envFrom: - configMapRef: name: nvi-config + - secretRef: + name: nvi-secrets readinessProbe: httpGet: path: /healthz diff --git a/ctrl/k8s/base/configmap.yaml b/ctrl/k8s/base/configmap.yaml index f142d40..30d3fff 100644 --- a/ctrl/k8s/base/configmap.yaml +++ b/ctrl/k8s/base/configmap.yaml @@ -12,14 +12,10 @@ data: NVI_DATASET: "financial" # LLM. Supported providers: groq, anthropic, openai. + # Secrets (*_API_KEY) live in the Secret built by kustomize from .env. LLM_PROVIDER: "groq" - GROQ_API_KEY: "REDACTED_GROQ_API_KEY" GROQ_MODEL: "llama-3.3-70b-versatile" - - ANTHROPIC_API_KEY: "" ANTHROPIC_MODEL: "claude-sonnet-4-6" # Langfuse (nivii project in the lng cluster). LANGFUSE_HOST: "http://lng.local.ar" - LANGFUSE_PUBLIC_KEY: "REDACTED_LANGFUSE_PUBLIC_KEY" - LANGFUSE_SECRET_KEY: "REDACTED_LANGFUSE_SECRET_KEY" diff --git a/ctrl/k8s/base/kustomization.yaml b/ctrl/k8s/base/kustomization.yaml index b8db436..cd992c8 100644 --- a/ctrl/k8s/base/kustomization.yaml +++ b/ctrl/k8s/base/kustomization.yaml @@ -21,3 +21,15 @@ configMapGenerator: - Caddyfile options: disableNameSuffixHash: true + +# API key Secret built from .env at the repo root. .env is gitignored; only +# .env.example is committed. The path is relative to this kustomization.yaml +# (ctrl/k8s/base/) — `../../../.env` resolves to the repo root. +# disableNameSuffixHash keeps the Secret name stable so api.yaml's secretRef +# doesn't break on every rebuild. +secretGenerator: + - name: nvi-secrets + envs: + - ../../../.env + options: + disableNameSuffixHash: true