---
id: w4/m11/t004
title: Docs + prod verification — rendered-config check, ADR012-auth.md MFA section, scripted prod smoke
worker: worker4
status: done
estimate: 20m
depends_on: [w4/m11/t003]
---

## Objective

Finish the docs and prove prod. The prod WebAuthn RP config already shipped in t001's base edit (base values ARE prod — Argo auto-syncs main; see the README's 2026-07-11 note), so this task carries no values changes: verify the rendered config (prod renders RP ID `bex.co` + origins `[https://dashboard.bex.co]`, the local overlay overrides both), write `docs/ADR012-auth.md`'s MFA section (methods, AAL policy, recovery codes, RP-ID-is-forever constraint) replacing any "no MFA" consequence, and run a scripted prod smoke.

## Context

- _2026-07-11:_ there is no prod Kratos overlay — `base/values/kratos.values.yaml` is the live prod config, which is why the RP ID/origins moved into t001; this task verifies rather than edits. Prod smoke is cheap post-rebuild: `scripts/fetch-app-kubeconfig.sh` gives direct cluster access, the auth stack is verified live (kratos-db restored, CNPG on the platform pool, nightly backups healthy — MFA credentials land in kratos-db, already covered by backups).
- Passkey RP ID pitfalls: must be a registrable parent of the domain the dashboard is served on; changing it later invalidates existing WebAuthn credentials — record that constraint in the docs.
- Markdown is CI-checked: run prettier on touched docs.

## Steps

1. Rendered-config verification (helm-template/kustomize): prod output carries RP ID `bex.co` + origins `[https://dashboard.bex.co]`; the local overlay overrides to localhost.
2. `docs/ADR012-auth.md`: MFA section (methods, AAL, recovery codes, RP-ID-is-forever constraint, second-factor `passwordless: false` decision); consequences updated.
3. Scripted prod smoke: fetch the prod kubeconfig, port-forward kratos-public (or hit `https://auth.bex.co`), assert the settings flow offers the `totp`/`webauthn`/`lookup_secret` groups and login for an enrolled test identity demands aal2.
4. Argo-diff sanity check that only Kratos config changes ship.

## Files

- `docs/ADR012-auth.md`
- `deploy/gitops/base/values/kratos.values.yaml`, `deploy/gitops/overlays/local/values/kratos.values.yaml` (verify only — edited in t001)

## Acceptance criteria

- [ ] Rendered configs show the correct RP ID/origins in prod and the localhost override locally (no values edits in this task).
- [ ] `docs/ADR012-auth.md` documents the shipped design and the RP-ID-is-forever constraint.
- [ ] Prod smoke: settings flow offers the three methods; an enrolled test identity's login demands aal2 (scripted, exit 0).

## Out of scope

- The browser passkey ceremony against prod — the one remaining manual check; perform opportunistically after deploy.
