prole/docs/plans/junie/15-remove-dead-dashboard-consumer.md
chrisfu f83ec8169c docs(plans): file Junie briefs for queue items #2, #6, #7, #13, #15
Five self-contained work briefs in a new docs/plans/junie/ subdirectory,
each tagged against a numbered item in docs/TODO.md so Junie can take
them independently in any order.

  02-k3s-prole-rename.md            -> queue #2  (drift R5)
  06-patch-garage-script-fixes.md   -> queue #6  (drift R9)
  07-init-cnpg-gke-sa-wiring.md     -> queue #7  (drift R8)
  13-podmonitor-manual-management.md-> queue #13
  15-remove-dead-dashboard-consumer.md-> queue #15

Each brief follows the same shape: Why -> What changes (concrete file
paths + line numbers + before/after) -> Verification -> Out of scope ->
Commit shape -> Definition of done. The intent is that Junie reads cold
(no shared chat history) and lands the change without escalating
questions.

Also adds:
  - docs/plans/junie/README.md describing the convention.
  - Row in docs/plans/README.md so newcomers find the subdirectory.
  - Brief reference + "Assigned to Junie" tag on each of the five queue
    items in docs/TODO.md.

Existing in-progress assignment to Junie (Phase 2 pg_oauth) is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 16:13:20 -07:00

9.0 KiB

Junie brief — Queue #15: remove dead DASHBOARD consumer + basicauth_credentials from supabase Kong chart

Self-contained brief. Pure cleanup. The basic-auth plugin block was removed in commit 25f1b2e (oauth2-proxy → Kong fronting); the consumer + credentials it gated have no enforcer. Watch the OpenAI key trap — it lives in the same secret.dashboard block in values.yaml, so don't blanket-delete the section.


1. Why

Before commit 25f1b2e (2026-04-30, oauth2-proxy fronting), Studio was gated by Kong's basic-auth plugin against credentials in secret.dashboard.{username,password}. That gate was replaced by oauth2-proxy + Google OAuth, so the basic-auth plugin reference was removed from the Kong route definition.

Three artifacts of the old gate remain:

  1. Kong consumer named DASHBOARD in supabase/helm/knoe-supabase/templates/kong/config.yaml — has no plugin enforcing it. Dead.
  2. basicauth_credentials block in the same file — provides credentials for a consumer no plugin is checking. Dead.
  3. DASHBOARD_USERNAME / DASHBOARD_PASSWORD env vars flowing through the Kong deployment + the wrapper-script's envsubst. Dead.

The secret.dashboard.{username,password} values in values.yaml themselves are unused after this cleanup, but the secret.dashboard.openAiApiKey field is NOT dead — it's consumed by templates/studio/deployment.yaml:92 to populate OPENAI_API_KEY in the Studio pod env. Don't delete the whole secret.dashboard block. Restructure carefully so the OpenAI key still has a home.

2. The four artifacts to remove

Artifact 1 — supabase/helm/knoe-supabase/templates/kong/config.yaml

Lines 19-20 (the wrapper-script's sed replacements):

    -e "s|\${DASHBOARD_USERNAME}|${DASHBOARD_USERNAME}|" \
    -e "s|\${DASHBOARD_PASSWORD}|${DASHBOARD_PASSWORD}|" \

Delete both lines.

Lines 30-32 (the consumer):

    {{- if .Values.secret.dashboard }}
      - username: DASHBOARD
    {{- end }}

Delete all three lines (the if-end pair around the consumer).

Lines 44-49 (the credentials block):

    {{- if .Values.secret.dashboard }}
    basicauth_credentials:
      - consumer: DASHBOARD
        username: ${DASHBOARD_USERNAME}
        password: ${DASHBOARD_PASSWORD}
    {{- end }}

Delete all six lines.

Artifact 2 — supabase/helm/knoe-supabase/templates/kong/deployment.yaml

Lines 74-92 (the two env-var blocks): both DASHBOARD_USERNAME and DASHBOARD_PASSWORD env-from-secret references. They're both wrapped in {{- if .Values.secret.dashboard }} ... {{- end }}. Delete the whole conditional block (both env vars, the wrapper, the inner conditional for secretRef vs default secret).

After deletion, verify the surrounding env list still parses (Kong deployment manifest must still be a valid Pod spec).

Artifact 3 — supabase/helm/knoe-supabase/values.yaml

Lines 104-118 (the secret.dashboard section):

  ## Studio dashboard credentials
  ##
  dashboard:
    username: "supabase"
    password: "this_password_is_insecure_and_should_be_updated"
    openAiApiKey: "key_super_secret"
    ## Reference to existing secret
    # secretRef: ""
    ## Map to actual keys inside secretRef if they differ
    # secretRefKey:
    #   username: username
    #   password: password
    #   openAiApiKey: openAiApiKey

Restructure — don't delete. Two paths:

Path A (recommended): rename the section to openai. Remove username/password. Rename dashboard: to openai:. Update the one consumer (templates/studio/deployment.yaml:92) to read from .Values.secret.openai.apiKey (renamed from openAiApiKey). Update the secretRefKey mapping similarly. Cleanest.

  ## OpenAI API key — passed to Studio's AI Assist sidebar.
  ## Optional; if absent, the AI Assist panel renders an error toast but
  ## the rest of Studio works fine. We default to a placeholder string so
  ## helm template doesn't fail; replace via secretRef in production.
  openai:
    apiKey: "key_super_secret"
    # secretRef: ""
    # secretRefKey:
    #   apiKey: apiKey

Path B (minimal): drop username/password only. Keep the section name dashboard: since renaming touches more files. End up with a dashboard: section that holds only openAiApiKey. Slightly confusing name vs. contents, but the diff is smaller.

Pick Path A unless the touch surface scares you. The if .Values.secret.dashboard conditional in the kong-deployment env block goes away in Path A naturally; in Path B, replace those ifs with explicit if .Values.secret.dashboard.username / .password checks before removing the env vars (since the block-level check used to mean "any field set"; now it must be field-specific).

Artifact 4 — supabase/helm/knoe-supabase/templates/studio/deployment.yaml

If you take Path A above, update the env-var binding at line 92:

            - name: OPENAI_API_KEY
              valueFrom:
                secretKeyRef:
                  {{- if .Values.secret.openai.secretRef }}
                  name: {{ .Values.secret.openai.secretRef }}
                  key: {{ .Values.secret.openai.secretRefKey.apiKey | default "apiKey" }}
                  {{- else }}
                  name: {{ include "supabase.secret.openai" . }}
                  key: apiKey
                  {{- end }}

(rename dashboardopenai, openAiApiKeyapiKey).

Also rename or re-source the helper template supabase.secret.dashboard (if it exists in _helpers.tpl) to supabase.secret.openai. If the helper doesn't exist (the grep earlier returned no match), skip.

Artifact 5 — supabase/helm/knoe-supabase/ci/example.yaml

Has a parallel secret.dashboard.openAiApiKey for chart CI. Update to match Path A or B.

3. Don't break

  • OpenAI API key flow: pre-and-post-cleanup the Studio pod must receive OPENAI_API_KEY from a Secret, identically. Verify with helm template before vs. after.
  • Existing live deployments using secretRef — if any production deploy uses secret.dashboard.secretRef to point at an existing K8s Secret with username/password/openAiApiKey keys, that secret needs renaming too. Grep for secret.dashboard.secretRef in any real values overrides (not just the chart defaults). If found, ASK before proceeding.

4. Verification

  1. helm template the chart and diff for OPENAI_API_KEY:

    helm template supabase/helm/knoe-supabase \
      | grep -A 6 'name: OPENAI_API_KEY'
    

    Expected: env var still binds to a Secret. The Secret name + key may differ from before (if you renamed); the flow must still resolve.

  2. helm template the chart and confirm DASHBOARD is gone:

    helm template supabase/helm/knoe-supabase | grep -i DASHBOARD
    

    Expected: no output.

  3. helm lint the chart:

    helm lint supabase/helm/knoe-supabase
    

    Expected: clean.

  4. No stale references in the rest of the repo:

    grep -rni DASHBOARD_USERNAME supabase/ k8s/ deploy/ etc/
    grep -rni DASHBOARD_PASSWORD supabase/ k8s/ deploy/ etc/
    

    Expected: no output (or only docs explaining the old flow that you then update / remove).

  5. OpenAI key still works in Studio: hard to verify without rolling out, but a helm template showing the env var still bound is sufficient for chart correctness. Live re-roll of supabase-studio is out of scope; flag it as a manual follow-up if anything changes about the secret name.

5. Out of scope

  • Don't roll out the chart change to live knoe-dev-0. Chart cleanup is code-only; the current live deployment uses the OLD chart (with secret.dashboard), and migrating production secret structure is a separate decision.
  • The Studio fork (queue item #12) — totally separate.
  • Any other Kong route changes — leave the file alone outside the surgical lines listed.

6. Commit shape

If Path A:

chore(supabase): remove dead DASHBOARD consumer + basic-auth credentials

The basic-auth plugin was retired in commit 25f1b2e (oauth2-proxy
took over Studio gating via Google OAuth). Three artifacts of the
old gate remained as no-op config:

  - Kong consumer named DASHBOARD
  - basicauth_credentials block
  - DASHBOARD_USERNAME / DASHBOARD_PASSWORD env in kong deployment

All removed.

The secret.dashboard.openAiApiKey field — the only LIVE consumer
of secret.dashboard — was migrated to secret.openai.apiKey. Studio's
OPENAI_API_KEY env binding updated; helm template diff confirms
the same Secret-source flow.

Closes queue item #15 in docs/TODO.md.

If Path B: simpler subject — chore(supabase): drop dead DASHBOARD username/password.

7. Definition of done

  • Four artifacts removed from kong/config.yaml, kong/deployment.yaml, values.yaml, ci/example.yaml.
  • OpenAI key still resolves through helm template.
  • helm lint clean.
  • grep -rni DASHBOARD_USERNAME returns nothing in repo.
  • docs/TODO.md queue item #15 archived to Done.