Files
homelab-design/decisions/0029-authentik-user-registration-workflow.md
Billy D. 3580ee1223 docs: add ADRs 0029-0030 for Authentik registration and MFA
- 0029: User registration workflow with approval and group-based access
- 0030: MFA and Yubikey strategy for Authentik and Vaultwarden
2026-02-04 09:11:29 -05:00

16 KiB

Authentik User Registration and Approval Workflow

  • Status: accepted
  • Date: 2026-02-04
  • Deciders: Billy
  • Technical Story: Control access to homelab applications through vetted user registration

Context and Problem Statement

The homelab hosts applications that should only be accessible to trusted users (family, close friends). While Authentik provides SSO, we need a controlled registration process where:

  1. Users can self-register
  2. An admin reviews and approves registrations
  3. Approved users get access only to specific applications based on their role

How do we implement a user registration workflow with approval and conditional application access?

Decision Drivers

  • Self-service registration - users shouldn't need admin to create accounts
  • Admin approval - prevent unauthorized access
  • Granular access control - different users get different applications
  • Simple to manage - single admin shouldn't be overwhelmed
  • Audit trail - know who approved whom and when

Considered Options

  1. Authentik enrollment flow with admin approval + group-based access
  2. Invite-only registration (no self-service)
  3. Open registration with post-hoc restriction

Decision Outcome

Chosen option: Option 1 - Authentik enrollment flow with admin approval + group-based access

Authentik's enrollment stages allow custom registration flows. Combined with group-based application access, this provides a complete workflow:

  • Users self-register → account created but inactive/limited
  • Admin receives notification → reviews and assigns groups
  • User gets access only to applications their groups permit

Positive Consequences

  • Self-service reduces admin burden for initial registration
  • Approval step prevents unauthorized access
  • Group-based access scales well as applications grow
  • Full audit log of approvals
  • Can add MFA requirement during enrollment

Negative Consequences

  • Admin must actively monitor registration requests
  • Users experience delay between registration and access
  • Requires proper group/application mapping setup

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                           REGISTRATION FLOW                                  │
│                                                                             │
│  ┌──────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐  │
│  │  User    │───▶│  Enrollment  │───▶│   Account    │───▶│  Pending     │  │
│  │ Requests │    │    Form      │    │   Created    │    │  Approval    │  │
│  └──────────┘    └──────────────┘    └──────────────┘    └──────┬───────┘  │
│                                                                  │          │
│                         ┌────────────────────────────────────────┘          │
│                         │                                                   │
│                         ▼                                                   │
│              ┌─────────────────────┐                                        │
│              │   Admin Reviews     │                                        │
│              │   (Email/Dashboard) │                                        │
│              └──────────┬──────────┘                                        │
│                         │                                                   │
│           ┌─────────────┼─────────────┐                                     │
│           │             │             │                                     │
│           ▼             ▼             ▼                                     │
│     ┌──────────┐  ┌──────────┐  ┌──────────┐                               │
│     │  Reject  │  │  Approve │  │  Approve │                               │
│     │          │  │  Basic   │  │  Full    │                               │
│     └──────────┘  └────┬─────┘  └────┬─────┘                               │
│                        │             │                                      │
│                        ▼             ▼                                      │
│                  ┌──────────┐  ┌──────────┐                                 │
│                  │ homelab- │  │ homelab- │                                 │
│                  │  guests  │  │  users   │                                 │
│                  └──────────┘  └──────────┘                                 │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│                        APPLICATION ACCESS BY GROUP                           │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                         homelab-admins                               │    │
│  │  All applications + Authentik admin + Grafana admin                  │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                         homelab-users                                │    │
│  │  Affine, Kavita, Nextcloud, Immich, Kasm, ntfy, Vaultwarden         │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                         homelab-guests                               │    │
│  │  Kavita only                                                         │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                         pending-approval                             │    │
│  │  No applications (can only access Authentik profile)                 │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────────┘

Group Structure

Group Purpose Applications
homelab-admins Full administrative access All + Gitea, Flux UI, Authentik admin
homelab-users Trusted users (family) Affine, Immich, Kasm, Kavita, Nextcloud, ntfy, Vaultwarden
homelab-guests Limited access (friends) Kavita only
pending-approval Newly registered, not yet vetted None (Authentik profile only)

Application Access Matrix

External applications exposed via envoy-external gateway:

Application admins users guests pending
Authentik (admin)
Authentik (profile)
Affine
Gitea
Immich
Kasm
Kavita
Nextcloud
ntfy
Vaultwarden
Flux UI

Implementation

Step 1: Create Groups

In Authentik Admin → Directory → Groups, create:

  1. homelab-admins

    • Superuser status: Yes (for Authentik admin)
  2. homelab-users

    • Superuser status: No
  3. homelab-guests

    • Superuser status: No
  4. pending-approval

    • Superuser status: No
    • This is the default group for new registrations

Step 2: Create Enrollment Flow

In Authentik Admin → Flows & Stages:

2a. Create Stages

  1. enrollment-invitation-check (Invitation Stage)

    • Continue without invitation: Yes
  2. enrollment-user-form (Prompt Stage)

    • Fields: username, email, name, password, password_repeat
  3. enrollment-user-write (User Write Stage)

    • Create users as inactive: No
    • Group: pending-approval
  4. enrollment-user-login (User Login Stage)

    • Session duration: default

2b. Create Flow

  1. Name: homelab-enrollment
  2. Slug: homelab-enrollment
  3. Designation: Enrollment
  4. Bind stages in order:
    • enrollment-invitation-check
    • enrollment-user-form
    • enrollment-user-write
    • enrollment-user-login

Step 3: Configure Application Policies

For each application, create a policy binding that requires group membership:

3a. Create Group Membership Policies

In Authentik Admin → Policies:

Policy: require-homelab-users

# Expression Policy
return ak_is_group_member(request.user, name="homelab-users") or \
       ak_is_group_member(request.user, name="homelab-admins")

Policy: require-homelab-guests-or-higher

# Expression Policy
return ak_is_group_member(request.user, name="homelab-guests") or \
       ak_is_group_member(request.user, name="homelab-users") or \
       ak_is_group_member(request.user, name="homelab-admins")

Policy: require-homelab-admins

# Expression Policy
return ak_is_group_member(request.user, name="homelab-admins")

3b. Bind Policies to Applications

For each application in Applications → Applications:

Application Policy to Bind
Affine require-homelab-users
Gitea require-homelab-admins
Immich require-homelab-users
Kasm require-homelab-users
Kavita require-homelab-guests-or-higher
Nextcloud require-homelab-users
ntfy require-homelab-users
Vaultwarden require-homelab-users
Flux UI require-homelab-admins

Step 4: Admin Notification

Since no SMTP is configured (per ADR-0016), admin notification options:

Option A: Dashboard Monitoring

  1. Periodically check Authentik Admin → Directory → Users
  2. Filter by group: pending-approval
  3. Review and move to appropriate group

Option B: Webhook to Discord/Slack (Future Enhancement)

Configure Authentik event to send webhook on user creation:

# Event Rule: new-user-notification
# Trigger: Model Created (User)
# Action: Webhook to Discord

webhook_url = "https://discord.com/api/webhooks/..."
message = f"New user registration: {model.username} ({model.email})"

Step 5: Approval Process

When a new user registers:

  1. Admin receives notification (or checks dashboard)
  2. Admin reviews user information:
    • Do I know this person?
    • What access level should they have?
  3. Admin action:
    • Approve as user: Remove from pending-approval, add to homelab-users
    • Approve as guest: Remove from pending-approval, add to homelab-guests
    • Reject: Delete user account
  4. User can now access their permitted applications

User Experience

Registration Flow (User Perspective)

  1. User visits https://auth.daviestechlabs.io/if/flow/homelab-enrollment/
  2. Fills out registration form (username, email, password)
  3. Account created, logged in automatically
  4. Sees Authentik user dashboard with no applications
  5. Message displayed: "Your account is pending approval"
  6. After admin approval, applications appear on dashboard

Custom Pending Message

Create a custom user interface text in Authentik:

In Admin → Flows → Default Interface → Customization:

<!-- For users with no app access -->
<div class="pending-notice">
  <h3>Account Pending Approval</h3>
  <p>Your registration is being reviewed. You'll receive access to applications once approved.</p>
  <p>Contact the homelab admin if you need expedited access.</p>
</div>

MFA Enforcement

See ADR-0030: MFA and Yubikey Strategy for MFA configuration details.

Audit Trail

Authentik logs all changes:

  • User creation (with registration timestamp)
  • Group membership changes (who approved, when)
  • Application access attempts (granted/denied)

View in Admin → Events → Logs

Security Considerations

Rate Limiting

  • Enrollment flow should have rate limiting to prevent spam registrations
  • Configure in Flow settings or via reverse proxy

Account Cleanup

  • Periodically review pending-approval group
  • Delete accounts that have been pending > 30 days without approval

Group Escalation

  • Only homelab-admins can modify group memberships
  • Consider requiring MFA for admin actions

Future Enhancements

  1. Email notifications - When SMTP is configured, notify users of approval
  2. Invitation codes - Pre-approve specific registrations with invite links
  3. Self-service group requests - Users can request access to additional apps
  4. Time-limited access - Guest access expires after N days
  5. Application-specific approval - Per-app access requests

References