diff --git a/deploy-k3s/manifests/kratos/configmap.yaml b/deploy-k3s/manifests/kratos/configmap.yaml index 3a2bb80..313e185 100644 --- a/deploy-k3s/manifests/kratos/configmap.yaml +++ b/deploy-k3s/manifests/kratos/configmap.yaml @@ -207,14 +207,26 @@ data: // returns the name on the very first authorization and not in the ID // token claims, so only email is mapped here. // - // NOTE: we intentionally do NOT carry Apple's email_verified across via - // verified_addresses. Product decision: every account-creation flow — - // including Sign in with Apple — must complete an email verification step. + // Sign in with Apple emails are marked verified UNCONDITIONALLY: completing + // SIWA cryptographically proves the user controls that Apple ID, and Apple + // owns/verifies the (relay or real) email, so a 6-digit code would be + // redundant. We deliberately do NOT gate this on Apple's `email_verified` + // claim — Apple omits that claim on many authorizations (only sends it on + // the first grant), which made auto-verification random: sometimes verified, + // sometimes a surprise code prompt (observed 2026-06-03). Marking it + // verified on every SIWA makes the behaviour consistent: Apple users never + // see a code; password sign-ups still verify via the honeyDue API flow. local claims = std.extVar('claims'); { identity: { traits: { email: claims.email, }, + verified_addresses: std.prune([ + if 'email' in claims then { + via: 'email', + value: claims.email, + }, + ]), }, }