headplane/DEBUGGING_ANALYSIS_REPORT.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

12 KiB

Headplane Debugging Analysis Report

Executive Summary

This report provides a systematic debugging analysis of identified bug-related issues in Headplane, a web UI for Headscale. The analysis covers authentication, permissions, configuration management, and UI interaction bugs using root cause analysis methodologies.

Methodology

This analysis employs:

  • Root Cause Analysis: 5 Whys methodology and causal chain analysis
  • Pattern Recognition: Identifying common themes across bugs
  • System Architecture Analysis: Understanding component interactions
  • Code Flow Analysis: Tracing execution paths for bug reproduction

Critical Bug Analysis

1. Issue #310: NixOS Module OIDC Configuration Bug

Category: Configuration Management / Authentication Impact: High - Prevents OIDC authentication setup in NixOS deployments

Root Cause Analysis

Problem: NixOS module doesn't properly handle OIDC configuration validation and data directory creation.

Evidence from Code:

  • /home/rpm/claude/headplane/nix/module.nix - Missing data directory creation logic
  • Configuration schema validation issues in /home/rpm/claude/headplane/app/server/config/schema.ts
  • OIDC client creation in /home/rpm/claude/headplane/app/server/web/oidc.ts has strict validation

Causal Chain:

  1. User configures OIDC in NixOS module
  2. Module generates config but doesn't ensure required directories exist
  3. Headplane service starts but can't write OIDC user storage file
  4. Authentication fails silently or with permission errors
  5. User sees "no permissions" behavior

5 Whys Analysis:

  • Why does OIDC fail? → Data directory doesn't exist or has wrong permissions
  • Why doesn't the directory exist? → NixOS module doesn't create it
  • Why doesn't the module create it? → Missing directory creation logic in systemd service
  • Why is this missing? → Module focuses on service definition, not data directory management
  • Why wasn't this caught? → Testing likely done with manual directory creation

Reproduction Steps

  1. Configure NixOS module with OIDC settings
  2. Deploy without manual data directory creation
  3. Attempt OIDC login
  4. Observe authentication failure

Fix Strategy

  • Add StateDirectory and StateDirectoryMode to systemd service configuration
  • Ensure proper ownership assignment in NixOS module
  • Add validation for required directories in startup process

2. Issue #299: No Permissions with OIDC Login

Category: Authentication / Authorization Impact: High - Users can authenticate but have no access rights

Root Cause Analysis

Problem: OIDC users are created without proper role assignment, defaulting to 'member' role with zero capabilities.

Evidence from Code:

  • /home/rpm/claude/headplane/app/server/web/roles.ts shows 'member' role has 0 capabilities
  • /home/rpm/claude/headplane/app/routes/auth/oidc-callback.ts doesn't assign roles during user creation
  • No automatic role elevation logic for first-time OIDC users

Causal Chain:

  1. User authenticates via OIDC successfully
  2. User object created with default 'member' role
  3. Member role has 0 capabilities (line 126 in roles.ts)
  4. User session established but UI access blocked
  5. User sees blank/restricted interface

5 Whys Analysis:

  • Why do users have no permissions? → They get 'member' role with 0 capabilities
  • Why do they get member role? → Default assignment without admin intervention
  • Why no automatic elevation? → No first-user admin logic implemented
  • Why isn't this documented? → OIDC configuration docs don't mention role management
  • Why no UI feedback? → No clear permission denied messages

Fix Strategy

  • Implement first-user-admin logic for OIDC deployments
  • Add role management UI for OIDC administrators
  • Improve error messaging for permission denied scenarios
  • Document role assignment process

3. Issue #278: NixOS Module - Create dataDir Automatically

Category: Configuration Management / File System Impact: Medium - Deployment friction and manual intervention required

Root Cause Analysis

Problem: Services expect data directories to exist but NixOS module doesn't create them.

Evidence from Code:

  • Default paths in config schema expect /var/lib/headplane/ directories
  • NixOS module runs services as headscale user but doesn't ensure directory ownership
  • No StateDirectory directive in systemd service configuration

Architectural Issue: Mismatch between application expectations and deployment automation.

Fix Strategy

  • Add StateDirectory = "headplane" to systemd service
  • Ensure proper user/group ownership
  • Add validation checks in application startup

4. Issue #266: Automated Ownership Permissions Rework

Category: System Security / File Permissions Impact: Medium - Security and operational issues

Root Cause Analysis

Problem: Inconsistent file ownership and permission handling across different deployment methods.

Evidence from Code:

  • Services run as headscale user but may create files as different users
  • No systematic permission validation at startup
  • Integration modules (Docker, Kubernetes, proc) have different permission requirements

Fix Strategy

  • Implement startup permission validation
  • Standardize file ownership patterns
  • Add permission repair functionality

Code-Level Bug Analysis

1. Menu onAction Called Twice (app/components/Menu.tsx:27)

Category: UI/UX Bug Impact: Low-Medium - Potential double execution of actions

Root Cause Analysis

Problem: React event handling in Menu component triggers action callbacks multiple times.

Evidence from Code:

// Line 27: TODO: onAction is called twice for some reason?

Likely Causes:

  • Event bubbling in nested React components
  • useMenuTrigger and useMenuItem both handling same events
  • cloneElement pattern may be duplicating event handlers

Debugging Strategy:

  1. Add console.log to track event propagation
  2. Use React DevTools to inspect event handlers
  3. Check if useMenuTrigger and useMenuItem have conflicting event handling

Fix Strategy

  • Add event.stopPropagation() in appropriate handlers
  • Consolidate event handling logic
  • Add unit tests for action execution count

2. API Generation Issues (app/routes/auth/oidc-callback.ts:49)

Category: Authentication / API Management
Impact: High - API key proliferation and database bloat

Root Cause Analysis

Problem: OIDC authentication generates new API keys without cleanup, causing database accumulation.

Evidence from Code:

// TODO: This is breaking, to stop the "over-generation" of API
// keys because they are currently non-deletable in the headscale
// database. Look at this in the future once we have a solution

Architectural Issue: Headscale API key management limitations combined with session management needs.

Fix Strategy

  • Implement API key reuse for existing users
  • Add key rotation/cleanup strategy
  • Investigate Headscale API key deletion capabilities

3. Headscale API Problems (app/routes/auth/login/action.ts:86)

Category: API Integration / Error Handling Impact: Medium - Poor error handling and debugging difficulty

Root Cause Analysis

Problem: Inconsistent and unclear error responses from Headscale API.

Evidence from Code:

// TODO: What in gods name is wrong with the headscale API?
if (error.status === 401 || error.status === 403 || 
    (error.status === 500 && error.response.trim() === 'Unauthorized'))

Issue: Headscale returns HTTP 500 with "Unauthorized" text instead of proper 401/403 codes.

Fix Strategy

  • Normalize error handling across all Headscale API interactions
  • Add retry logic for transient failures
  • Improve error logging and user feedback

Cross-Cutting Issues and Patterns

1. Configuration Validation Gaps

Pattern: Inconsistent validation between schema definition and runtime validation.

Evidence:

  • Strong schema validation in app/server/config/schema.ts
  • Runtime failures due to missing directories/permissions
  • NixOS module doesn't validate generated configurations

Impact: Silent failures and difficult debugging

2. Error Handling Inconsistencies

Pattern: Mixed error handling strategies across the codebase.

Evidence:

  • Some components use try/catch with detailed logging
  • Others use simple error returns
  • Inconsistent user-facing error messages

3. Integration Permission Complexity

Pattern: Different deployment methods (Docker, Kubernetes, NixOS, proc) have varying permission requirements.

Evidence:

  • Each integration has different systemd/container security contexts
  • No unified permission validation strategy
  • Manual intervention often required

Testing and Quality Assurance Gaps

1. Integration Testing Deficiencies

Missing Coverage:

  • End-to-end OIDC authentication flows
  • NixOS module deployment scenarios
  • Permission boundary validation
  • API key lifecycle management

2. Error Condition Testing

Missing Scenarios:

  • Missing directory permissions on startup
  • Malformed OIDC responses
  • Headscale API downtime/errors
  • Role assignment edge cases

Risk Assessment

High Risk Issues

  1. OIDC Authentication Failures - Blocks user access entirely
  2. Permission Escalation Gaps - Users stuck with no permissions
  3. API Key Proliferation - Database performance degradation

Medium Risk Issues

  1. Configuration Deployment Friction - Increases support burden
  2. Error Handling Inconsistencies - Poor debugging experience
  3. UI Action Reliability - User experience degradation

Low Risk Issues

  1. TODO Comments - Technical debt accumulation
  2. Logging Inconsistencies - Debugging difficulty

1. Systematic OIDC Flow Testing

Approach:

  • Create minimal reproducible environment for OIDC testing
  • Implement comprehensive logging at each authentication step
  • Add health check endpoints for OIDC configuration validation

Tools:

  • Add OIDC flow tracing middleware
  • Implement configuration validation API endpoints
  • Create automated integration tests

2. Permission System Audit

Approach:

  • Audit all permission checks across the application
  • Implement permission debugging UI for administrators
  • Add startup permission validation with clear error reporting

3. Error Handling Standardization

Approach:

  • Create unified error handling middleware
  • Implement structured error logging
  • Add user-friendly error message system

Prevention Strategies

1. Development Process Improvements

  • Pre-commit Hooks: Add validation for TODO comments that indicate bugs
  • Integration Testing: Mandatory OIDC and permission flow testing
  • Documentation: Update deployment guides with troubleshooting sections

2. Monitoring and Observability

  • Health Checks: Add comprehensive application health endpoints
  • Metrics: Track authentication success/failure rates
  • Alerts: Monitor API key creation patterns and permission errors

3. Configuration Management

  • Validation: Add runtime configuration validation with clear error messages
  • Migration: Implement configuration migration and validation tools
  • Documentation: Provide troubleshooting guides for common deployment issues

Conclusion

The analyzed bugs primarily stem from:

  1. Configuration and deployment complexity across different platforms
  2. Authentication and authorization system gaps particularly around OIDC
  3. Error handling inconsistencies that make debugging difficult
  4. Integration testing gaps that allow regressions

The recommended approach focuses on systematic testing, improved error handling, and better deployment automation to prevent these classes of issues from recurring.

Priority Fix Order:

  1. OIDC permission assignment (Issue #299)
  2. NixOS data directory creation (Issue #278, #310)
  3. API key lifecycle management (oidc-callback.ts:49)
  4. Error handling standardization (login/action.ts:86)
  5. UI event handling (Menu.tsx:27)

This systematic approach will improve both user experience and maintainability while reducing the support burden for common deployment issues.