Auth was structurally broken — the api's Kratos middleware was pointing
at http://kratos:4433 but Kratos wasn't deployed. The only thing keeping
users logged in was a 5-min Redis cache; once it expired the middleware
called Whoami → no DNS → 401 → forced relogin with no path back.
This commit deploys Kratos for real:
Manifests:
- kratos.yaml + migrate-job.yaml: pin oryd/kratos:v26.2.0@sha256:92eedc...
(CalVer current stable as of 2026-06-03)
- configmap.yaml: drop Google OIDC provider (not in scope); fill the
Apple provider with real Services ID / Team ID / Key ID — Apple now
sits at providers[0]
- kratos.yaml: drop the Google-secret env binding; rebind APPLE_PRIVATE_KEY
to PROVIDERS_0_APPLE_PRIVATE_KEY (shifted from index 1)
- network-policies.yaml: add a kratos egress rule to allow-egress-from-api.
Without this, even with kratos running, the api gets "connection refused"
on http://kratos:4433 (post-DNAT NetworkPolicy enforcement — runbook §9.2).
Operator prerequisites that were completed alongside this commit:
- Neon kratos database created (separate from honeyDue, owner neondb_owner)
- Cloudflare DNS for auth.myhoneydue.com (3 A records, proxied)
- kratos: block added to config.yaml (gitignored): DSN to the Neon DIRECT
endpoint, cookie + cipher secrets generated, Fastmail SMTPS URI,
.p8 contents inline
Out of scope intentionally:
- Google sign-in (additive; can append providers[] later)
- Migrating existing auth_user rows onto Kratos identities — pre-prod;
existing users will need to sign in fresh, which creates a new Kratos
identity and a new local user row (per migration plan in
manifests/kratos/README.md).
Verified end-to-end:
- 338 schema migrations applied successfully
- 2/2 kratos pods Ready
- api → kratos:4433/sessions/whoami returns 401 for invalid token (was
"connection refused" before this commit's NetworkPolicy patch)
- auth.myhoneydue.com resolves through CF; cloudflare-only middleware
keeps the origin protected exactly like the other hostnames
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
First phase of replacing the hand-rolled auth (internal/services/auth_service.go
et al.) with Ory Kratos. This commit is infrastructure only — Kratos will run
but nothing consumes it yet; the Go API still does its own auth until phase 2.
Adds deploy-k3s/manifests/kratos/:
- configmap.yaml — kratos.yml, identity schema, Google/Apple OIDC claim
mappers (no secrets in the ConfigMap)
- migrate-job.yaml — `kratos migrate sql`, run before the Deployment
- kratos.yaml — Deployment (x2), Service, NetworkPolicies
- ingress.yaml — auth.myhoneydue.com -> Kratos public API :4433
- README.md — operator prerequisites + deploy runbook
Wiring:
- 02-setup-secrets.sh creates kratos-secrets, gated on a config.yaml `kratos:`
block (DSN, cookie/cipher, SMTP URI, OIDC client secret, Apple key).
- 03-deploy.sh applies the Kratos manifests + runs the migrate Job, gated on
the kratos-secrets Secret existing.
Both gates mean the existing stack deploys completely unaffected until the
operator completes the prerequisites (Neon `kratos` DB, auth.myhoneydue.com
DNS, Apple/Google OAuth apps, Kratos image version). Pre-production, so no
user-data migration — see manifests/kratos/README.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>