Skip to main content
Nexus Access Vault implements a modern, cloud-native architecture designed for security, scalability, and maintainability. This document details the system’s architecture, key components, and data flows.

High-Level Architecture

The architecture follows a three-tier design:
  1. Presentation Layer: React-based SPA with TypeScript
  2. Application Layer: Supabase Edge Functions (Deno runtime)
  3. Data Layer: PostgreSQL with Row Level Security (RLS)

Core Components

Frontend Application

React SPA

Single-page application built with React 18, TypeScript, and Vite for optimal performance and developer experience.
Technology Stack:
  • Framework: React 18.3 with concurrent features
  • Language: TypeScript 5.8 with strict mode
  • Build Tool: Vite 5.4 with SWC compiler
  • Routing: React Router v6 with nested layouts
  • UI Library: shadcn/ui + Radix UI primitives
  • Styling: Tailwind CSS 3.4 with custom design system
Key Files:
  • src/App.tsx - Application entry point with routing configuration
  • src/components/AuthProvider.tsx - Authentication context and state management
  • src/components/AppSidebar.tsx - Navigation with role-based rendering
  • src/hooks/useZitadelSSO.ts - SSO authentication hook with PKCE

Component Architecture

The application follows a hierarchical component structure:
App (QueryClientProvider, AuthProvider)
├── BrowserRouter
│   ├── Auth Pages (Login, Callback)
│   ├── MainLayout
│   │   ├── AppSidebar (Navigation)
│   │   ├── Dashboard
│   │   ├── MyApplications
│   │   ├── MyDevices
│   │   ├── Sessions
│   │   └── Admin Routes
│   │       ├── Users
│   │       ├── Groups
│   │       ├── Resources
│   │       └── Settings
│   └── Special Routes (Enrollment, NotFound)
See src/App.tsx:36-81 for complete routing configuration.

State Management Strategy

Server State

React Query manages all server data with automatic caching, refetching, and synchronization.

Client State

React Context + hooks for authentication, theme, and UI state.
Authentication State (src/components/AuthProvider.tsx):
const AuthContext = createContext<AuthContextType>({
  user: null,              // Supabase user object
  session: null,           // Active session with JWT
  profile: null,           // User profile with organization
  roles: [],               // Local role assignments
  zitadelIdentity: null,   // Zitadel groups and user ID
  loading: false,
  signOut: async () => {},
  hasRole: (role) => false,
  hasZitadelGroup: (group) => false,
});
The AuthProvider automatically:
  • Listens to Supabase auth state changes
  • Fetches user profile, roles, and Zitadel identity on login
  • Provides helper functions for permission checking
  • Manages sign-out and session cleanup

Backend Services

Supabase Platform

Comprehensive backend-as-a-service providing PostgreSQL database, authentication, edge functions, and real-time subscriptions.

PostgreSQL Database

Database Schema (src/integrations/supabase/types.ts): The system uses a comprehensive relational schema with the following key tables:
  • profiles: User profiles with organization membership
  • organizations: Multi-tenant organization management
  • user_roles: Role assignments (many-to-many)
  • user_groups: Group memberships
  • resources: Applications and infrastructure resources
  • user_resource_access: Access grants with time bounds
  • zitadel_configurations: OIDC provider settings per organization
  • user_zitadel_identities: Links users to Zitadel accounts
  • zitadel_group_mappings: Maps Zitadel groups to local groups
  • authentik_configurations: Alternative SSO provider support
  • cloud_providers: AWS, Azure, GCP credentials
  • hypervisors: VMware, Proxmox, KVM connections
  • netbird_configurations: VPN network settings
  • devices: Enrolled user devices
  • sessions: Active access sessions
  • audit_logs: Comprehensive event logging
  • policies: Access policies and rules
  • enrollment_tokens: Device enrollment tokens
Row Level Security (RLS): All tables implement RLS policies to enforce organization-level data isolation:
-- Example: Users can only see resources in their organization
CREATE POLICY "Users see own org resources"
  ON resources FOR SELECT
  USING (
    organization_id IN (
      SELECT organization_id FROM profiles
      WHERE id = auth.uid()
    )
  );

Edge Functions

Serverless functions running on Deno for backend logic:

zitadel-api

Handles OIDC token exchange, userinfo retrieval, and group synchronization

device-enrollment

Manages device registration and trust verification

session-launcher

Provisions and launches resource access sessions

netbird-proxy

Proxies requests to Netbird API for VPN management
Zitadel API Function (supabase/functions/zitadel-api/index.ts): This critical function handles the SSO callback flow:
// Token exchange action
case 'sso-callback':
  // 1. Exchange authorization code for tokens
  const tokenResponse = await fetch(tokenEndpoint, {
    method: 'POST',
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code: authCode,
      code_verifier: codeVerifier,
      client_id: clientId,
      redirect_uri: redirectUri,
    }),
  });

  // 2. Fetch user information
  const userinfoResponse = await fetch(userinfoEndpoint, {
    headers: { Authorization: `Bearer ${accessToken}` },
  });

  // 3. Get user's Zitadel groups
  const groups = userInfo['urn:zitadel:iam:user:resourceowner:grants'] || [];

  // 4. Create/update user in Supabase
  const { data: authUser, error } = await supabase.auth.admin.createUser({
    email: userInfo.email,
    email_confirm: true,
    user_metadata: { full_name: userInfo.name },
  });

  // 5. Link Zitadel identity
  await supabase.from('user_zitadel_identities').upsert({
    user_id: authUser.id,
    zitadel_user_id: userInfo.sub,
    zitadel_groups: groups,
  });

  // 6. Sync groups to local groups (if enabled)
  if (config.sync_groups) {
    await syncZitadelGroups(authUser.id, groups);
  }
See IMPLEMENTATION_SUMMARY.md:9-105 for complete authentication flow details.

External Integrations

Zitadel

OIDC identity provider for SSO authentication

Netbird

Mesh VPN for secure network connectivity

Headscale

Self-hosted Tailscale control plane

Zitadel Integration

Configuration (ZITADEL_NETBIRD_SETUP.md): Zitadel provides enterprise SSO with comprehensive OIDC support:
  • Issuer URL: https://manager.kappa4.com
  • Client Type: Public (PKCE)
  • Scopes: openid profile email urn:zitadel:iam:org:project:id:zitadel:aud
  • Claims: Groups/roles, organization ID, user metadata
Authorization Flow:
1

Initiate Login

User clicks “Sign in with Kappa4 Manager”, portal generates PKCE parameters
2

Redirect to Zitadel

Browser redirects to Zitadel with code challenge and state
3

User Authentication

User authenticates at Zitadel (username/password, MFA, etc.)
4

Authorization Grant

Zitadel redirects back with authorization code
5

Token Exchange

Edge function exchanges code for tokens using code verifier
6

User Provisioning

Edge function creates/updates user and syncs groups
7

Local Sign-In

Frontend signs in with Supabase using temporary password
See IMPLEMENTATION_SUMMARY.md:78-109 for detailed flow documentation.

Netbird VPN Integration

Netbird provides a WireGuard-based mesh VPN that eliminates the need for traditional VPN concentrators. Each device connects peer-to-peer with automatic NAT traversal.
Network Architecture:
Internet

    ├─── Netbird Management Server (manager.kappa4.com)
    │    └─── Coordination, ACLs, Device Registry

    └─── Mesh Network (100.64.0.0/10)
         ├─── Portal Server (100.64.0.10)
         ├─── User Device 1 (100.64.0.25)
         ├─── User Device 2 (100.64.0.26)
         └─── Resource Server (100.64.0.50)
Features:
  • Automatic peer discovery
  • NAT traversal with STUN/TURN
  • End-to-end encryption (WireGuard)
  • Access control lists (ACLs)
  • Network routes and DNS
API Integration (supabase/functions/netbird-proxy): The portal proxies Netbird API requests for:
  • Device enrollment and key management
  • ACL synchronization based on user access grants
  • Network route management
  • DNS configuration

Data Flow Diagrams

Authentication Flow

Resource Access Flow

Group Synchronization Flow

When a user logs in via Zitadel SSO, their groups are automatically synchronized:
async function syncZitadelGroups(userId: string, zitadelGroups: string[]) {
  // 1. Fetch group mappings
  const { data: mappings } = await supabase
    .from('zitadel_group_mappings')
    .select('zitadel_group, local_group_id')
    .in('zitadel_group', zitadelGroups);

  // 2. Map Zitadel groups to local groups
  const localGroupIds = mappings.map(m => m.local_group_id);

  // 3. Remove user from old groups
  await supabase
    .from('user_groups')
    .delete()
    .eq('user_id', userId);

  // 4. Add user to new groups
  await supabase
    .from('user_groups')
    .insert(localGroupIds.map(groupId => ({
      user_id: userId,
      group_id: groupId,
    })));

  // 5. Update last sync timestamp
  await supabase
    .from('user_zitadel_identities')
    .update({ last_synced: new Date().toISOString() })
    .eq('user_id', userId);
}

Security Architecture

Defense in Depth

The system implements multiple security layers:
VPN-Only Access: Portal accessible only via Netbird VPN
  • Server binds to internal interface only
  • Firewall rules block external access
  • No public DNS records
# Bind to Netbird interface only
server: {
  host: "100.64.0.10",
  port: 8080,
}
Multi-Factor SSO: Zitadel OIDC with MFA enforcement
  • PKCE flow (SHA-256)
  • State parameter (CSRF protection)
  • Nonce parameter (replay protection)
  • Token rotation
See src/hooks/useZitadelSSO.ts for implementation.
Role-Based + Group-Based Access Control
  • Local roles: global_admin, org_admin, support, user
  • Zitadel groups: admin, support, developers, etc.
  • Combined checks for hybrid authorization
// Check both local role and Zitadel group
const canAccessAdmin = 
  hasRole('org_admin') || hasZitadelGroup('admin');
See src/components/AppSidebar.tsx:54-90 for permission logic.
Row Level Security (RLS): PostgreSQL policies enforce data boundaries
  • Organization-level isolation
  • User can only see own organization’s data
  • Admins restricted to their organization
  • Global admins see all (with policy exception)
Comprehensive Audit Trail: All security events logged
  • Authentication attempts (success/failure)
  • Authorization decisions
  • Resource access grants/revocations
  • Administrative actions
  • Configuration changes
Logs include: timestamp, user, IP, action, details, result.

Security Best Practices

Production Deployment Checklist:✓ Deploy behind Netbird VPN only✓ Configure firewall to block external access✓ Enable MFA in Zitadel for all users✓ Rotate service account tokens quarterly✓ Review audit logs weekly✓ Keep all dependencies updated✓ Use HTTPS with valid certificates✓ Implement backup and disaster recovery

Deployment Architecture

Development Environment

# Local development with hot reload
npm run dev

# Environment variables (.env)
VITE_SUPABASE_URL="https://your-project.supabase.co"
VITE_SUPABASE_PUBLISHABLE_KEY="your-anon-key"
VITE_ZITADEL_ISSUER_URL="https://manager.kappa4.com"
VITE_ZITADEL_CLIENT_ID="your-client-id"
VITE_ZITADEL_REDIRECT_URI="http://localhost:8080/auth/callback"
VITE_NETWORK_MODE="development"

Production Environment

1

Build Application

npm run build
# Output: dist/ directory with optimized assets
2

Deploy to Server

# Copy dist/ to server
scp -r dist/* user@server:/var/www/portal/
3

Configure Web Server

server {
  listen 100.64.0.10:8080;
  server_name portal.internal;
  
  root /var/www/portal;
  index index.html;
  
  location / {
    try_files $uri $uri/ /index.html;
  }
}
4

Configure Firewall

# Allow only Netbird network
sudo ufw allow from 100.64.0.0/10 to 100.64.0.10 port 8080
sudo ufw deny 8080

Infrastructure Components

Application Server

Specs: 2 CPU, 4GB RAM, 20GB SSDSoftware: Nginx, Node.js (build only)Network: Netbird client connected

Database Server

Platform: Supabase Cloud or Self-HostedSpecs: PostgreSQL 15, 4GB RAM minimumBackup: Daily automated backups

Identity Provider

Platform: Zitadel at manager.kappa4.comConfig: OIDC application with PKCEMFA: Enforced for all users

VPN Infrastructure

Platform: Netbird management serverNetwork: 100.64.0.0/10 address spaceEncryption: WireGuard end-to-end

Scalability Considerations

Horizontal Scaling

The architecture supports horizontal scaling at multiple levels:
  • Frontend: Static assets served via CDN (future)
  • Edge Functions: Auto-scale based on load (Supabase)
  • Database: Read replicas for query distribution
  • VPN: Mesh architecture scales with devices

Performance Optimizations

Code Splitting

React lazy loading and route-based chunking reduce initial bundle size

React Query Cache

Intelligent caching reduces API calls and improves UX

Database Indexing

Indexes on foreign keys and frequently queried columns

Connection Pooling

Supabase Pooler for efficient database connections

Monitoring & Observability

Logging Strategy

  • Browser console (development)
  • Sentry or similar (production)
  • Error boundaries for graceful failures

Future Architecture Enhancements

Microservices

Split monolithic edge functions into specialized microservices

Event Bus

Implement event-driven architecture for real-time updates

GraphQL API

Add GraphQL layer for flexible client queries

Multi-Region

Deploy across multiple regions for global availability

Features Overview

Explore all system capabilities and features

Getting Started

Deploy your first instance

Configuration Guide

Configure SSO, VPN, and integrations

Database Schema

Complete database schema reference

Build docs developers (and LLMs) love