- 0029: User registration workflow with approval and group-based access - 0030: MFA and Yubikey strategy for Authentik and Vaultwarden
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:
- Users can self-register
- An admin reviews and approves registrations
- 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
- Authentik enrollment flow with admin approval + group-based access
- Invite-only registration (no self-service)
- 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:
-
homelab-admins
- Superuser status: Yes (for Authentik admin)
-
homelab-users
- Superuser status: No
-
homelab-guests
- Superuser status: No
-
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
-
enrollment-invitation-check (Invitation Stage)
- Continue without invitation: Yes
-
enrollment-user-form (Prompt Stage)
- Fields: username, email, name, password, password_repeat
-
enrollment-user-write (User Write Stage)
- Create users as inactive: No
- Group:
pending-approval
-
enrollment-user-login (User Login Stage)
- Session duration: default
2b. Create Flow
- Name:
homelab-enrollment - Slug:
homelab-enrollment - Designation: Enrollment
- 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
- Periodically check Authentik Admin → Directory → Users
- Filter by group:
pending-approval - 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:
- Admin receives notification (or checks dashboard)
- Admin reviews user information:
- Do I know this person?
- What access level should they have?
- Admin action:
- Approve as user: Remove from
pending-approval, add tohomelab-users - Approve as guest: Remove from
pending-approval, add tohomelab-guests - Reject: Delete user account
- Approve as user: Remove from
- User can now access their permitted applications
User Experience
Registration Flow (User Perspective)
- User visits
https://auth.daviestechlabs.io/if/flow/homelab-enrollment/ - Fills out registration form (username, email, password)
- Account created, logged in automatically
- Sees Authentik user dashboard with no applications
- Message displayed: "Your account is pending approval"
- 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-approvalgroup - Delete accounts that have been pending > 30 days without approval
Group Escalation
- Only
homelab-adminscan modify group memberships - Consider requiring MFA for admin actions
Future Enhancements
- Email notifications - When SMTP is configured, notify users of approval
- Invitation codes - Pre-approve specific registrations with invite links
- Self-service group requests - Users can request access to additional apps
- Time-limited access - Guest access expires after N days
- Application-specific approval - Per-app access requests