headplane/AUTHENTIK_SETUP_GUIDE.md
Ryan Malloy 7c21720519
Some checks are pending
Build / native (push) Waiting to run
Build / nix (push) Waiting to run
Complete the Astro rewrite
Drop the entire app/ Remix tree (144 deletions) and replace with the
Astro + Alpine.js architecture under src/. The Remix entrypoint, routes,
components, layouts, server bindings, and types are all gone; the Astro
pages (acls, dns, machines, settings, terminal, users, login, index)
plus their API endpoints under src/pages/api/ now own the surface.

Other surfaces touched:
- package.json: drop react-router, react-router-hono-server, remix-utils
  and the rest of the Remix stack; pull in Astro + integrations + Alpine
- pnpm-lock.yaml: regenerated against the new dependency set
- astro.config.mjs added; vite.config.ts, react-router.config.ts dropped
- New src/lib/auth/ (oidc-client, role-mapper, session-manager) and
  src/lib/config/authentik.ts for env-driven config
- biome.json: enable VCS-aware filtering, exclude .astro/dist/data/
  upstream/ and the React Router backup
- Extensive docs (HEADY_MANIFESTO, AUTHENTIK_*, BETTER_ROLE_MAPPING* etc.)
  and example role-mapping yamls added under examples/
- New remote-access/ tree for the Guacamole-Lite integration
- terminal.astro: prerender disabled (data is request-time only)

Committed with --no-verify; biome auto-fix was applied first but there
are still lint warnings in the new code worth a separate cleanup pass.
The legacy app/ tree was never re-pushed after the rewrite, which is
why the Gitea/Docker builds were trying to compile app/routes/ssh/
console.tsx.
2026-06-06 13:05:35 -06:00

7.9 KiB

🤠 Heady + Authentik Setup Guide

Strategic VPN management with awesome authentication!

This guide walks you through setting up Authentik OIDC authentication with Heady VPN management.

🎯 Overview

Heady integrates with Authentik to provide:

  • Secure OIDC Authentication: Industry-standard OpenID Connect
  • Role-Based Access Control: Intelligent group-to-role mapping
  • Session Management: Secure HTTP-only cookies
  • Zero Configuration: Smart defaults with environment variable overrides

📋 Prerequisites

  • Authentik Instance: Running Authentik server (v2023.8+)
  • Heady Instance: This Astro + Alpine.js application
  • Domain Names: Both should be accessible via HTTPS (localhost OK for development)

🔧 Authentik Configuration

Step 1: Create Application in Authentik

  1. Login to Authentik Admin (https://your-authentik.domain/if/admin/)

  2. Navigate to Applications → Applications

  3. Create a new Application:

    Name: Heady VPN Management
    Slug: heady
    Provider: Create new provider
    
  4. Create OIDC Provider:

    Name: Heady OIDC Provider
    Authorization flow: default-authorization-flow (Authorize with password)
    Client type: Confidential
    Client ID: heady-production (save this)
    Client Secret: <generated secret> (save this)
    Redirect URIs: https://your-heady-domain.com/api/auth/callback
    Scopes: openid, email, profile, groups
    
  5. Save and note:

    • Client ID: heady-production
    • Client Secret: ak-<random-string>
    • Issuer URL: https://your-authentik.domain/application/o/heady/

Step 2: Configure Groups (Optional)

Create Authentik groups for role mapping:

Admin Groups:
- heady-admins
- admin
- administrators

Network Groups:
- heady-network
- devops
- sre
- network-ops

Owner Groups:
- heady-owners
- ceo
- founders

Step 3: Assign Users to Groups

  1. Navigate to Directory → Users
  2. Select user → Groups tab
  3. Add user to appropriate groups

🚀 Heady Configuration

Environment Variables

Create a .env file or set environment variables:

# Required: Authentik Configuration
AUTHENTIK_ISSUER="https://your-authentik.domain/application/o/heady/"
AUTHENTIK_CLIENT_ID="heady-production"
AUTHENTIK_CLIENT_SECRET="ak-your-secret-here"

# Required: Public URL for redirects
PUBLIC_URL="https://your-heady-domain.com"

# Required: Session Security
SESSION_SECRET="your-32-character-session-secret"
SESSION_LIFETIME="24h"

# Optional: Custom Role Mapping
HEADY_OWNER_GROUPS="ceo,founders,executives"
HEADY_ADMIN_GROUPS="admin,administrators,managers"
HEADY_NETWORK_GROUPS="devops,network,sre,infrastructure"
HEADY_IT_GROUPS="helpdesk,support,it"
HEADY_AUDITOR_GROUPS="audit,compliance,security"

Generate Session Secret

# Generate secure session secret
openssl rand -base64 32

# Or use Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"

🏃‍♂️ Quick Start

Development Setup

# Clone and install
git clone <heady-repo>
cd heady
pnpm install

# Configure environment
cp .env.example .env
# Edit .env with your Authentik settings

# Start development server
pnpm dev

Production Deployment

# Build application
pnpm build

# Start production server
pnpm start

🔐 Role Mapping

Heady maps Authentik groups to roles using two methods:

# Exact group matching (case-insensitive)
HEADY_ADMIN_GROUPS="admin,heady-admins,administrators"
HEADY_NETWORK_GROUPS="devops,network,sre"

Method 2: Convention-Based Mapping

Automatic pattern recognition:

Authentik Group Heady Role Pattern
admin, administrators admin Contains "admin"
devops, network, sre network_admin Contains network terms
ceo, owner, founders owner Contains ownership terms
helpdesk, support, it it_admin Contains IT support terms
audit, compliance, security auditor Contains audit terms
All others member Default role

🧪 Testing Your Setup

1. Check Service Status

# Check authentication service
curl https://your-heady-domain.com/api/auth/status

# Expected response:
{
  "service": "Heady Authentication",
  "status": "healthy",
  "authentik_configured": true,
  "authentication": {
    "provider": "Authentik OIDC",
    "issuer": "https://your-authentik.domain/application/o/heady/"
  }
}

2. Test Login Flow

  1. Visit https://your-heady-domain.com/login
  2. Click "Login with Authentik"
  3. Authenticate with your Authentik credentials
  4. Verify redirect to dashboard with correct role

3. Test API Endpoints

# Test protected endpoint (should redirect to login)
curl -I https://your-heady-domain.com/api/auth/profile

# Test login endpoint (should redirect to Authentik)
curl -I https://your-heady-domain.com/api/auth/login

🛠️ Troubleshooting

Common Issues

"Authentication configuration error"

Problem: Missing or invalid environment variables

Solution:

# Check required variables are set
echo $AUTHENTIK_ISSUER
echo $AUTHENTIK_CLIENT_ID
echo $AUTHENTIK_CLIENT_SECRET

# Verify issuer URL is accessible
curl $AUTHENTIK_ISSUER/.well-known/openid-configuration

"Token exchange failed"

Problem: Wrong client credentials or redirect URI

Solution:

  1. Verify AUTHENTIK_CLIENT_ID and AUTHENTIK_CLIENT_SECRET
  2. Check redirect URI in Authentik matches {PUBLIC_URL}/api/auth/callback
  3. Ensure Authentik and Heady can communicate

"Access denied"

Problem: User not in required groups

Solution:

  1. Check user's groups in Authentik
  2. Verify role mapping configuration
  3. Check console logs for mapping details

Debug Mode

Enable detailed logging:

# Add to .env
NODE_ENV=development
DEBUG=true

# Check logs in browser console and server logs

Log Analysis

Heady provides detailed authentication logs:

✓ OIDC Authentication successful for user@company.com
  Groups found: admin, developers
  Assigned role: admin (environment mapping)
  Session created: abc123... (expires: 2024-01-16T10:30:00Z)

🔒 Security Best Practices

Production Deployment

  1. Use HTTPS Everywhere

    • Authentik instance must use HTTPS
    • Heady instance must use HTTPS
    • Set cookie_secure: true in production
  2. Secure Session Secret

    • Use cryptographically secure random string
    • Minimum 32 characters
    • Store securely (environment variables, not code)
  3. Network Security

    • Restrict Authentik admin access
    • Use firewall rules for service communication
    • Monitor authentication logs

Group Management

  1. Principle of Least Privilege

    • Start users with member role
    • Grant higher roles only as needed
    • Regular access reviews
  2. Group Naming Convention

    • Use clear, descriptive group names
    • Avoid special characters
    • Consider prefixes: heady-admin, heady-network

📊 Monitoring & Analytics

Authentication Metrics

Check authentication statistics:

# Admin endpoint (requires admin role)
curl -H "Cookie: heady_session=..." \
  https://your-heady-domain.com/api/auth/status?stats=true

Response includes:

  • Active sessions by role
  • Recent login activity
  • Session statistics
  • System health

Log Monitoring

Monitor these events:

  • Successful authentications
  • Failed login attempts
  • Role mapping decisions
  • Session expirations

🆘 Support

Heady Support

  • Documentation: Heady Docs
  • Issues: GitHub repository
  • Community: Discord/Forum

Authentik Support


🎉 Congratulations! You now have secure, awesome VPN management with Authentik authentication!

"Strategic VPN management that's actually awesome to use" - Heady Manifesto