From 8f4df84657895069ee1a9dc3a4f631328236fd57 Mon Sep 17 00:00:00 2001 From: "Billy D." Date: Wed, 4 Feb 2026 08:28:12 -0500 Subject: [PATCH] chore: Consolidate ADRs into decisions/ directory - Added ADR-0016: Affine email verification strategy - Moved ADRs 0019-0024 from docs/adr/ to decisions/ - Renamed to consistent format (removed ADR- prefix) --- ...0016-affine-email-verification-strategy.md | 150 ++++++++++++++++++ .../0019-handler-deployment-strategy.md | 0 .../0020-internal-registry-for-cicd.md | 0 .../0021-notification-architecture.md | 0 .../0022-ntfy-discord-bridge.md | 0 .../0023-valkey-ml-caching.md | 0 .../0024-ray-repository-structure.md | 0 7 files changed, 150 insertions(+) create mode 100644 decisions/0016-affine-email-verification-strategy.md rename docs/adr/ADR-0019-handler-deployment-strategy.md => decisions/0019-handler-deployment-strategy.md (100%) rename docs/adr/ADR-0020-internal-registry-for-cicd.md => decisions/0020-internal-registry-for-cicd.md (100%) rename docs/adr/ADR-0021-notification-architecture.md => decisions/0021-notification-architecture.md (100%) rename docs/adr/ADR-0022-ntfy-discord-bridge.md => decisions/0022-ntfy-discord-bridge.md (100%) rename docs/adr/ADR-0023-valkey-ml-caching.md => decisions/0023-valkey-ml-caching.md (100%) rename docs/adr/ADR-0024-ray-repository-structure.md => decisions/0024-ray-repository-structure.md (100%) diff --git a/decisions/0016-affine-email-verification-strategy.md b/decisions/0016-affine-email-verification-strategy.md new file mode 100644 index 0000000..58c115d --- /dev/null +++ b/decisions/0016-affine-email-verification-strategy.md @@ -0,0 +1,150 @@ +# Affine Email Verification Strategy for Authentik OIDC + +* Status: proposed +* Date: 2026-02-04 +* Deciders: Billy +* Technical Story: Affine requires email verification for users, but Authentik is not configured with SMTP for email delivery + +## Context and Problem Statement + +Affine (self-hosted note-taking/collaboration tool) requires users to have verified email addresses. When users authenticate via Authentik OIDC, Affine checks the `email_verified` claim. Currently, Authentik has no SMTP configuration, so it cannot send verification emails, causing new users to be blocked or have limited functionality in Affine. + +How can we satisfy Affine's email verification requirement without adding significant infrastructure complexity to the homelab? + +## Decision Drivers + +* Minimize external dependencies and ongoing costs +* Keep the solution self-contained within the homelab +* Avoid breaking changes on Affine upgrades +* Maintain security - don't completely bypass verification for untrusted users +* Simple to implement and maintain + +## Considered Options + +1. **Override `email_verified` claim in Authentik** - Configure Authentik to always return `email_verified: true` for trusted users +2. **Deploy local SMTP server (Mailpit)** - Run a lightweight mail capture server in-cluster +3. **Configure Affine to skip verification for OIDC users** - Use Affine's configuration to trust OIDC-provided emails + +## Decision Outcome + +Chosen option: **Option 1 (Override `email_verified` claim)** as the primary solution, with Option 3 as a fallback if Affine supports it. + +This approach requires zero additional infrastructure, works immediately, and is appropriate for a homelab where all users are trusted (family/personal use). Option 2 (Mailpit) is documented for future reference if actual email delivery becomes needed for other applications. + +### Positive Consequences + +* No additional services to deploy or maintain +* Works immediately with existing Authentik setup +* No external dependencies or costs +* Can be easily reverted if requirements change + +### Negative Consequences + +* Bypasses "real" email verification - relies on trust +* If Affine is ever exposed to untrusted users, this would need revisiting +* Other applications expecting real email verification would need similar workarounds + +## Pros and Cons of the Options + +### Option 1: Override `email_verified` Claim in Authentik + +Configure an Authentik property mapping to always return `email_verified: true` in the OIDC token for the Affine application. + +**Implementation:** +1. In Authentik Admin → Customization → Property Mappings +2. Create a new "Scope Mapping" for email_verified +3. Set expression: `return True` +4. Assign to Affine OIDC provider + +* Good, because zero infrastructure required +* Good, because immediate solution +* Good, because appropriate for trusted homelab users +* Bad, because not "real" verification +* Bad, because per-application configuration needed + +### Option 2: Deploy Local SMTP Server (Mailpit) + +Deploy Mailpit (or MailHog) as a lightweight SMTP server in the cluster that captures all emails for viewing via web UI. + +**Implementation:** +```yaml +# Example Mailpit deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mailpit + namespace: productivity +spec: + replicas: 1 + selector: + matchLabels: + app: mailpit + template: + spec: + containers: + - name: mailpit + image: axllent/mailpit:latest + ports: + - containerPort: 1025 # SMTP + - containerPort: 8025 # Web UI +``` + +Then configure Authentik SMTP settings: +- Host: `mailpit.productivity.svc.cluster.local` +- Port: `1025` +- TLS: disabled (internal traffic) + +* Good, because provides actual email flow for testing +* Good, because useful for other apps needing email (password reset, notifications) +* Good, because emails viewable via web UI +* Bad, because emails don't actually leave the cluster +* Bad, because another service to maintain +* Bad, because requires Authentik reconfiguration + +### Option 3: Configure Affine to Skip Verification for OIDC Users + +If Affine supports it, configure the application to trust email addresses from OIDC providers without requiring separate verification. + +**Potential Configuration (needs verification):** +```yaml +# In affine-config ConfigMap +AFFINE_AUTH_OIDC_EMAIL_VERIFIED: "true" +# or similar environment variable +``` + +* Good, because no Authentik changes needed +* Good, because scoped to Affine only +* Bad, because may not be supported by Affine +* Bad, because could break on Affine upgrades +* Bad, because requires research into Affine's configuration options + +## Implementation Notes + +### For Option 1 (Recommended) + +1. Access Authentik admin at `https://auth.daviestechlabs.io/if/admin/` +2. Navigate to Customization → Property Mappings +3. Create new Scope Mapping: + - Name: `Affine Email Verified Override` + - Scope name: `email` + - Expression: + ```python + return { + "email": request.user.email, + "email_verified": True, + } + ``` +4. Edit the Affine OIDC Provider → Advanced Settings → Scope Mappings +5. Replace default email mapping with the new override + +### Future Considerations + +If the homelab expands to include external users or applications requiring real email delivery: +- Revisit Option 2 (Mailpit) for development/testing +- Consider external SMTP service (SendGrid free tier, AWS SES) for production email + +## References + +* [Authentik Property Mappings Documentation](https://docs.goauthentik.io/docs/property-mappings) +* [Affine Self-Hosting Documentation](https://docs.affine.pro/docs/self-host-affine) +* [Mailpit GitHub](https://github.com/axllent/mailpit) diff --git a/docs/adr/ADR-0019-handler-deployment-strategy.md b/decisions/0019-handler-deployment-strategy.md similarity index 100% rename from docs/adr/ADR-0019-handler-deployment-strategy.md rename to decisions/0019-handler-deployment-strategy.md diff --git a/docs/adr/ADR-0020-internal-registry-for-cicd.md b/decisions/0020-internal-registry-for-cicd.md similarity index 100% rename from docs/adr/ADR-0020-internal-registry-for-cicd.md rename to decisions/0020-internal-registry-for-cicd.md diff --git a/docs/adr/ADR-0021-notification-architecture.md b/decisions/0021-notification-architecture.md similarity index 100% rename from docs/adr/ADR-0021-notification-architecture.md rename to decisions/0021-notification-architecture.md diff --git a/docs/adr/ADR-0022-ntfy-discord-bridge.md b/decisions/0022-ntfy-discord-bridge.md similarity index 100% rename from docs/adr/ADR-0022-ntfy-discord-bridge.md rename to decisions/0022-ntfy-discord-bridge.md diff --git a/docs/adr/ADR-0023-valkey-ml-caching.md b/decisions/0023-valkey-ml-caching.md similarity index 100% rename from docs/adr/ADR-0023-valkey-ml-caching.md rename to decisions/0023-valkey-ml-caching.md diff --git a/docs/adr/ADR-0024-ray-repository-structure.md b/decisions/0024-ray-repository-structure.md similarity index 100% rename from docs/adr/ADR-0024-ray-repository-structure.md rename to decisions/0024-ray-repository-structure.md