Normal
0
Exempted
0
Bad IP
0
Offline
0
Total Clients
0

Loading clients...

Cloudflare Zero Trust Configuration

Checking...
Checking...
Checking...
How long an IP should remain exempted for configured clients
How long an IP should remain exempted for self-service and manual exemptions

Email Configuration

Email delivery is handled by the Firebase Trigger Email extension

Email service configured via Firebase
Manage in Firebase Console →

Test Email Delivery

Enter an email address to receive a test email

Slack Configuration

Configure Slack for notifications.

Checking...

User Management

Manage users who can access Kirberos (only @justzapp.com email addresses).

Name Email Status Last Login Actions

Error Logs & Debugging

View all server error logs and debugging information in real-time.

Loading error logs...

IP Management Testing

Test IP exemption add/remove operations with Cloudflare Access Policy.

Enter an IP address to test add/remove operations
Time Client Event IP Address Details

Overview

Kirberos is an IP address monitoring and management system that integrates with Cloudflare Zero Trust Access Policies. It monitors client devices, tracks IP address changes, and manages temporary exemptions in your Cloudflare Access Policy.

What Kirberos Does

  • Monitors client devices via heartbeat connections every 10 seconds
  • Tracks IP address changes as clients move between networks
  • Manages Cloudflare exemptions by adding and removing IP addresses from your Access Policy
  • Measures internet speed with download speed tests every 60 seconds
  • Sends notifications via Slack and in-app toasts for events
  • Supports self-service exemptions for users without the client script
  • Maintains logs of all activity in Firestore

Key Concepts

Configured Client
A device running the Kirberos client script, sending heartbeats every 10 seconds with IP address, ISP, and internet speed data.
Unconfigured Client
A temporary exemption for users who need remote access without installing the client script. Created via self-service link or by an administrator.
Heartbeat
A periodic message (every 10 seconds) containing the client's IP address, ISP, device information, and speed test results.
Allowed IPs
Permanently authorised IP addresses for a client. If a client's IP matches an allowed IP, no exemption is needed.
Exemption
A temporary authorisation added to your Cloudflare Access Policy. Exemptions expire after a configurable duration (default: 24 hours).
Auto-Exemption
When enabled, Kirberos automatically creates exemptions for non-allowed IPs. When disabled, the client enters "Bad IP" status.
Manual Exemption
An exemption started manually from the dashboard using the play button. Works regardless of whether auto-exemption is enabled.

Architecture

Kirberos is built on Google Firebase with the following components:

Infrastructure

Firebase App Hosting (europe-west4)
The main Node.js/Express application running on Google Cloud Run. Handles client heartbeats, API requests, and serves the dashboard.
Firebase Cloud Functions (europe-west1)
Scheduled background tasks:
  • checkExpiredExemptions – Runs every minute to expire exemptions and update Cloudflare
  • checkOfflineClients – Runs every minute to detect disconnected clients
  • checkExpiredUnconfiguredExemptions – Runs every minute for self-service exemptions
  • cleanupExemptionLinks – Runs hourly to remove expired self-service links
  • cleanupOldData – Runs daily to purge old logs
Firebase Firestore
NoSQL database storing clients, logs, settings, users, speed tests, and exemption records.
Google Cloud Secret Manager
Stores sensitive credentials (API tokens, OAuth secrets, SMTP passwords). Secrets are injected at runtime.
Cloudflare Zero Trust API
Used to add and remove IP addresses from your Access Policy.

Data Flow

  1. Client script sends heartbeat to App Hosting every 10 seconds
  2. Server processes heartbeat and checks IP against allowed list
  3. If exemption is needed, server calls Cloudflare API to add IP
  4. Cloud Functions run every minute to check expiries and offline status
  5. Notifications sent via Slack for important events
  6. All events logged to Firestore

Getting Started

Adding a Client

  1. Click "Add Client" in the top-right corner of the Dashboard
  2. Enter a descriptive name (e.g., "Warehouse PC 1", "John's Laptop")
  3. Optionally add allowed IP addresses (IPs that will not trigger exemptions)
  4. Click "Save Client"
  5. Download the client script by clicking the download icon
  6. Install and run the script on the target device

Installing the Client Script

The client script requires Node.js to be installed on the target device.

PM2 Installation (Recommended - Windows):

  1. Install Node.js (if not already installed):
    • Open PowerShell as Administrator
    • Run: choco install nodejs -y (if Chocolatey is installed)
    • Or download from nodejs.org
  2. Create folder: C:\Kirberos
  3. Move your downloaded client script to C:\Kirberos
  4. Download install-pm2.bat to C:\Kirberos
  5. Open Command Prompt as Administrator
  6. Run: cd C:\Kirberos && install-pm2.bat client_abc123.js
  7. Replace client_abc123.js with your actual script filename

The installer will set up PM2, start your client, and configure it to start automatically on boot. If you see console windows popping up, download and run fix-console-windows.bat.

Manual Run (Testing Only):

  1. Open a terminal and navigate to the script location
  2. Run: node client_abc123.js
  3. Keep the terminal open (closing it stops the client)
  4. Note: This is only for testing. Use PM2 for production.

For detailed installation instructions, see the Client Script section below.

Client Statuses

The dashboard displays clients with colour-coded status badges:

Normal
The client is online and its current IP address is in the allowed list. No exemption is needed.
Exempted
The client is online but its IP is not in the allowed list. An exemption has been created in Cloudflare. A countdown timer shows time remaining. When the exemption expires, the client must return to an allowed IP or the status will change to "Bad IP".
Bad IP
The client's IP is not allowed and no exemption is active. This occurs when:
  • Auto-exemption is disabled for the client
  • The exemption expired and the client did not return to an allowed IP
  • The Cloudflare API failed to create an exemption
Manual intervention is required – either add the IP to the allowed list or start a manual exemption.
Awaiting
The client was created but has not connected yet. Waiting for the first heartbeat from the client script.
Offline
No heartbeat has been received for 60+ seconds. The client may be powered off, disconnected, or the script has stopped.

Visual Indicators

  • Speedometer gauge – Shows current internet download speed in Mbps
  • Red triangle icon – Appears next to IP when status is "Bad IP" (hover for details)
  • Yellow triangle icon – Appears next to IP when an exempted client is offline
  • Red exclamation circle – Replaces speedometer when client is offline
  • Countdown timer – Shows time remaining on active exemptions

Exemptions

Exemptions temporarily allow an IP address to bypass Cloudflare Zero Trust authentication. They are added to and removed from your Access Policy via the Cloudflare API.

Automatic Exemptions

When auto-exemption is enabled (toggle in client details), Kirberos:

  1. Detects when a client's IP changes to a non-allowed address
  2. Adds the new IP to the Cloudflare Access Policy
  3. Sets a countdown timer (default: 24 hours)
  4. Sends a Slack notification: "IP Automatically Exempted" (yellow)
  5. Removes the old IP if one was exempted

When the exemption expires, the Cloud Function removes the IP and checks if the client returned to an allowed IP.

Manual Exemptions

You can start a manual exemption using the play button (▶) on any client card:

  • Uses the client's current IP address
  • Works regardless of whether auto-exemption is enabled
  • Sends notification: "Manual Exemption Applied by [Admin Name]" (yellow)
  • Can be stopped early using the pause button (⏸)

Exemption Expiry

Every minute, the checkExpiredExemptions Cloud Function:

  • Removes expired IPs from Cloudflare via API
  • Checks if the client's current IP is in the allowed list
  • If returned to allowed IP: Status → Normal, green notification
  • If still on unconfigured IP: Status → Bad IP, red notification

Important Behaviour

  • Exemptions continue when offline – If a client goes offline during an exemption, the countdown continues. The exemption will still expire on schedule.
  • No automatic re-exemption from Bad IP – A client must return to an allowed IP once before being eligible for another automatic exemption. This prevents infinite exemption loops.
  • Manual exemptions always work – Manual exemptions can be started regardless of the auto-exemption setting.

Unconfigured Clients

Unconfigured clients are temporary exemptions for users who need remote access without installing the client script. They appear in the "Unconfigured" tab.

Self-Service Exemptions

End-users can request temporary exemptions through a Slack workflow:

  1. User triggers the Slack workflow, which posts their Slack user ID
  2. Kirberos sends an email with a unique exemption link (valid for 1 hour)
  3. User clicks the link from the network they want to exempt
  4. The page detects their IP and adds it to Cloudflare
  5. Confirmation email sent with exemption details
  6. Exemption expires automatically (default: 12 hours)

Admin-Created Exemptions

Administrators can create exemptions manually:

  1. Go to Dashboard → Unconfigured tab
  2. Click "Create Exemption"
  3. Enter the user's email and IP address
  4. Click "Create Exemption"

The user receives a welcome email and the IP is immediately added to Cloudflare.

Expiry and Deletion

  • Exemptions expire automatically after the configured duration
  • User receives an expiry email notification
  • Administrators can delete exemptions early (sends revocation email)
  • IP is removed from Cloudflare on expiry or deletion

Notifications

Kirberos sends notifications via Slack and in-app toast messages.

Slack Notifications

Notifications are colour-coded by severity:

🟢 Positive (Green):

  • Exemption Ended – Returned to Allowed IP
  • Client Back Online
  • IP Restored – Back to Allowed

🟡 Warning (Yellow):

  • Device First Connection
  • IP Automatically Exempted
  • Manual Exemption Applied (includes admin name)
  • New Unconfigured Exemption (Self-Service or Admin)

🔴 Critical (Red):

  • Exemption Ended – Still on Unconfigured IP
  • Client Offline
  • IP Not Allowed (auto-exemption disabled)

In-App Notifications

  • Toast messages appear in the top-right corner
  • Notification history accessible via the bell icon
  • Auto-dismiss after 5 seconds

Deduplication

Identical notifications within 5 seconds are suppressed to prevent duplicates.

Client Script

The Kirberos client script is a Node.js application that runs on monitored devices and sends heartbeats to the server every 10 seconds.

Features

  • Heartbeats every 10 seconds with IP, ISP, and device information
  • Internet speed tests every 60 seconds (using Cloudflare's speed test)
  • Request timeouts (15 seconds) to prevent hanging
  • Exponential backoff on failures (10s → 20s → 40s → up to 2 minutes)
  • Graceful shutdown handling
  • Automatic recovery from errors
  • Cross-platform support (Windows, macOS, Linux)

Data Collected

Each heartbeat includes:

  • Public IP address
  • ISP information
  • Device model and OS version
  • Download speed (Mbps)

Resilience

The client script is designed to run indefinitely without manual intervention:

  • Timeouts prevent hanging during server deployments
  • Exponential backoff reduces load during outages
  • Automatic recovery when server returns
  • Uncaught exceptions are logged but do not crash the script
  • No manual restart required after server updates

Installation (Windows - Recommended: PM2)

PM2 is the recommended way to run the client script. It's simple, reliable, and handles auto-restart automatically.

Step 1: Add Client in Dashboard
  1. Go to Dashboard → Click "Add Client"
  2. Enter a descriptive name (e.g., "Warehouse PC 1", "John's Laptop")
  3. Click "Download Script"
  4. Save the downloaded script file (e.g., client_abc123.js)
Step 2: Prepare Installation Files
  1. Create directory: C:\Kirberos
  2. Move your downloaded client script to C:\Kirberos
  3. Download the installation script: Save it to C:\Kirberos
Step 3: Install Node.js (if not already installed)

Open PowerShell as Administrator and run:

# Install Chocolatey (if needed)
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

# Install Node.js
choco install nodejs -y
Step 4: Run the Installer

Open Command Prompt as Administrator:

cd C:\Kirberos
install-pm2.bat client_abc123.js

Replace client_abc123.js with your actual client script filename.

The installer will:

  • Install PM2 globally (if not already installed)
  • Start your client script with PM2
  • Configure it to start automatically on boot
  • Set up hidden console windows (no pop-ups)
Step 5: Fix Console Windows (if they appear)

If you see CMD windows popping up, download and run:

Then run:

cd C:\Kirberos
fix-console-windows.bat

This will restart PM2 without showing console windows.

Managing Your Client

Use these PM2 commands to manage your client:

  • pm2 list – View running processes
  • pm2 logs kirberos-client – View logs (real-time)
  • pm2 logs kirberos-client --lines 100 – View last 100 lines
  • pm2 stop kirberos-client – Stop the client
  • pm2 restart kirberos-client – Restart the client
  • pm2 delete kirberos-client – Remove from PM2
  • pm2 monit – Monitor CPU and memory usage
Deploying to Multiple Sites

PM2 makes deploying to multiple sites very simple:

  1. On each machine, create C:\Kirberos directory
  2. Copy your client script and install-pm2.bat to each machine
  3. On each machine, run:
    npm install -g pm2
    cd C:\Kirberos
    install-pm2.bat client_abc123.js
  4. If console windows appear, run fix-console-windows.bat on each machine
Uninstalling

To remove the client:

  1. Download: uninstall-pm2.bat
  2. Run: uninstall-pm2.bat

Alternative: Windows Service (Advanced)

If you prefer to use Windows Services instead of PM2, download:

See WINDOWS_INSTALL.md in the repository for detailed instructions. However, PM2 is recommended as it's simpler and more reliable.

Troubleshooting

Console Windows Popping Up

If CMD windows appear every few seconds:

  1. Download and run fix-console-windows.bat (see Step 5 above)
  2. Or manually stop and restart using the VBScript wrapper:
    pm2 stop kirberos-client
    pm2 delete kirberos-client
    wscript start-client-hidden.vbs client_abc123.js
    pm2 save
Client Not Connecting

If the client shows as "awaiting" status:

  • Check if PM2 is running: pm2 list
  • Check logs: pm2 logs kirberos-client
  • Verify the client script is the correct one for this client
  • Check network connectivity to the server
PM2 Not Starting on Boot

If PM2 doesn't start automatically:

  1. Run pm2-startup install again
  2. Or set up Task Scheduler manually (see PM2_INSTALL.md in repository)

Settings

The Settings page allows you to configure Kirberos. It is organised into tabs:

Cloudflare Tab

  • Test Mode – Simulates Cloudflare API calls without making real changes
  • Configuration Status – Shows whether API Token, Account ID, and Policy ID are configured
  • Exemption Duration (Configured) – How long exemptions last for configured clients (default: 24 hours)
  • Exemption Duration (Unconfigured) – How long exemptions last for self-service exemptions (default: 12 hours)
  • Test Connection – Verifies your Cloudflare API credentials

Mail Tab

  • Email Configuration – Shows the email service configuration (Firebase extension with Gmail)
  • Test Email – Sends a test email to verify email delivery is working

Notifications Tab

  • Slack Token Status – Shows whether the Slack token is configured
  • Channel ID – The Slack channel where notifications are sent
  • Enable/Disable – Toggle Slack notifications

Users Tab (Admin Only)

  • View all authorised users
  • Add new users (must have @justzapp.com email)
  • Edit user details
  • Enable/disable user accounts
  • Delete users

Testing Tab

  • Test adding an IP to Cloudflare
  • Test removing an IP from Cloudflare
  • List all IPs currently in the Access Policy

Debugging Tab

  • Error Logs – View application error logs
  • Auto-refresh – Automatically refresh logs every 5 seconds
  • Clear Logs – Remove all error logs from Firestore

7. Troubleshooting

7.1 Client Not Connecting

Symptoms: Client shows as "awaiting" status, no heartbeats received.

Possible Causes & Solutions:

  • Client script not running:
    • Check if the Node.js process is running on the client device
    • Verify the script was started correctly: node [script-name].js
    • Check for error messages in the terminal
    • Ensure Node.js is installed: node --version
  • Network connectivity issues:
    • Verify the client can reach the server URL
    • Test with: curl https://yourdomain.com/api/heartbeat
    • Check firewall rules aren't blocking outbound HTTPS connections
    • Verify DNS resolution is working
  • Invalid token:
    • Ensure you downloaded the correct client script for this client
    • Verify the token in the script matches the client's token in the dashboard
    • Re-download the client script if unsure
  • Server not responding:
    • Check server logs for errors
    • Verify the server is running and accessible
    • Check if the server process crashed

7.2 Exemption Creation Failing

Symptoms: Client shows "bad_ip" status, exemption errors in logs.

Possible Causes & Solutions:

  • Cloudflare API token invalid or expired:
    • Go to Settings → Cloudflare tab
    • Check the API Token status indicator
    • Click "Test Connection" to verify
    • If failed, create a new API token and update the environment variable
  • Incorrect Account ID or Policy ID:
    • Verify the Account ID and Policy ID in Settings
    • Ensure they match your Cloudflare configuration
    • Use the Testing tab to verify access to the policy
  • API token lacks permissions:
    • Verify the token has "Zero Trust → Edit" permission
    • Verify the token has "Access: Apps and Policies → Edit" permission
    • Check token restrictions (account/zone filters)
  • Policy doesn't exist or was deleted:
    • Verify the Policy ID is correct
    • Check that the policy still exists in Cloudflare
    • If policy was recreated, update the Policy ID
  • Network issues:
    • Check server can reach Cloudflare API: curl https://api.cloudflare.com
    • Verify no firewall is blocking outbound HTTPS
    • Check server logs for connection errors

7.3 Client Showing as Offline

Symptoms: Client status is "offline", no recent heartbeats.

Possible Causes & Solutions:

  • Client script stopped:
    • Check if the Node.js process is still running
    • Restart the client script
    • Install it as a Windows service for persistent running
  • Device powered off or sleeping:
    • Wake the device or power it on
    • Check power management settings
    • Disable sleep mode if the device should always be online
  • Network connectivity lost:
    • Check the device's network connection
    • Verify internet connectivity on the device
    • Check router/firewall status
  • Client script error:
    • Check the terminal/console where the script is running
    • Look for error messages
    • Check server logs for any clues
    • Try restarting the client script

7.4 IP Not Being Exempted Automatically

Symptoms: IP changes but status goes to "bad_ip" instead of "exempted".

Possible Causes & Solutions:

  • Auto-exemption disabled:
    • Open the client details modal
    • Check the "Auto-Exemption" toggle
    • Enable it if it's disabled
  • Exemption creation failed:
    • Check the Activity Logs for exemption failure errors
    • Follow the "Exemption Creation Failing" troubleshooting steps above
    • Manually start an exemption to test
  • IP is in allowed list:
    • If the IP is in the allowed list, no exemption is needed
    • Status should be "normal", not "exempted"
    • This is expected behaviour

7.5 Exemption Not Expiring

Symptoms: Exemption countdown shows expired but IP still in Cloudflare policy.

Possible Causes & Solutions:

  • Removal failed silently:
    • Check Activity Logs for "EXEMPTION_REMOVAL_FAILED" events
    • Verify Cloudflare API token still has permissions
    • Manually remove the IP using the Testing tab
  • Cron job not running:
    • Check Cloud Functions logs in Firebase Console
    • Verify the server process is running
    • Restart the server if necessary
  • Manual exemption active:
    • Manual exemptions don't auto-expire
    • You must manually stop them using the pause button
    • Check if the exemption button shows a pause icon

7.6 Slack Notifications Not Working

Symptoms: No messages appearing in Slack channel.

Possible Causes & Solutions:

  • Slack not enabled:
    • Go to Settings → Slack tab
    • Ensure "Enable Slack Notifications" is toggled on
  • Token not configured:
    • Check the Slack Token status indicator
    • Verify SLACK_TOKEN environment variable is set
    • Ensure the token starts with xoxb-
  • Invalid Channel ID:
    • Verify the Channel ID is correct
    • Ensure the bot has been invited to the channel
    • Check the bot has permission to post messages
  • Token expired or revoked:
    • Generate a new bot token in Slack
    • Update the SLACK_TOKEN environment variable
    • Restart the server

7.7 Authentication Issues

Symptoms: Cannot log in, redirected to login page, session expires immediately.

Possible Causes & Solutions:

  • Google OAuth not configured:
    • Verify GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set
    • Check the callback URL matches Google Cloud Console
    • Ensure your email is authorised in the Users table
  • Email not authorised:
    • Contact an administrator to add your email
    • Ensure your email ends with @justzapp.com
    • Check the Users tab in Settings (admin only)
  • Account disabled:
    • Contact an administrator to enable your account
    • Check the Users tab to see account status
  • Session cookie issues:
    • Clear browser cookies for the site
    • Try a different browser
    • Check if cookies are being blocked
    • Verify SESSION_SECRET is set

8. Frequently Asked Questions

8.1 General Questions

Q: What happens if the server goes down?
A: If the server is unavailable, clients will continue trying to send heartbeats but will fail. Existing exemptions in Cloudflare will remain active until they expire naturally. Once the server is back online, clients will reconnect automatically and the system will resume normal operation.
Q: Can I monitor multiple devices with the same client?
A: No, each device should have its own client entry and run its own client script. Each client has a unique token that identifies it to the server. Running the same script on multiple devices will cause conflicts.
Q: How often does the client send data?
A: By default, clients send a heartbeat every 10 seconds. This includes IP address, system statistics, and process information. The interval is hardcoded in the client script template.
Q: What data is stored about my devices?
A: Kirberos stores: client name, current IP address, ISP information, device type/OS/model, internet speed test results, exemption details, and connection logs. All data is stored in Firebase Firestore.
Q: Is my data secure?
A: All authentication uses Google SSO. Sensitive credentials (API tokens, secrets) are stored in environment variables, not in the database. The database is stored locally on your server. All communication between client and server uses HTTPS.

8.2 IP Address & Exemption Questions

Q: What's the difference between allowed IPs and exemptions?
A: Allowed IPs are permanently authorised IPs that don't require exemptions. If a client's IP matches an allowed IP, the status is "normal" and no Cloudflare action is taken. Exemptions are temporary authorisations added to Cloudflare when the IP is not in the allowed list. Exemptions expire after a configured duration.
Q: Can I add IP ranges to the allowed list?
A: Currently, Kirberos supports exact IP matches and basic CIDR-like matching. You can add IPs like 192.168.1.0/24 to match a range, though the matching is simplified. For complex ranges, consider adding individual IPs or using exemptions.
Q: What happens when an exemption expires?
A: When an exemption expires, the system automatically removes the IP from the Cloudflare Access Policy. If the client's current IP is in the allowed list, status changes to "normal". If not, status changes to "bad_ip" and a new exemption must be created (manually or automatically, depending on settings).
Q: Can I exempt an IP that's already in the allowed list?
A: No, the system prevents this. If an IP is in the allowed list, it's already authorised and doesn't need an exemption. Attempting to manually exempt an allowed IP will result in an error.
Q: What if my IP changes while I'm exempted?
A: When a new IP is detected, the old exemption is automatically removed and a new exemption is created for the new IP (if auto-exemption is enabled). The exemption timer resets for the new IP.
Q: How do I stop a manual exemption early?
A: Click the pause button (⏸) on the client card. This will immediately remove the IP from Cloudflare and stop the exemption. The client status will update based on whether the IP is in the allowed list.

8.3 Cloudflare Integration Questions

Q: Will Kirberos modify other parts of my Cloudflare configuration?
A: No, Kirberos only modifies the specific Access Policy you configure. It only adds or removes IP addresses from that policy's include rules. It does not modify any other Cloudflare settings, zones, or policies.
Q: Can I use Kirberos with multiple Cloudflare policies?
A: Currently, Kirberos is configured to work with a single Access Policy. All clients use the same policy. If you need multiple policies, you would need to run multiple instances of Kirberos with different configurations.
Q: What happens if someone manually removes an IP from Cloudflare?
A: If an IP is manually removed from Cloudflare, Kirberos will detect it as missing on the next heartbeat (if the client is still using that IP). The system will attempt to re-add it if the client is still exempted. If the exemption has expired in Kirberos but the IP was manually removed, the status will update accordingly.
Q: Can I test the Cloudflare integration without making real changes?
A: Yes! Enable "Test Mode" in Settings → Cloudflare tab. This simulates all Cloudflare API calls without actually modifying your policies. Perfect for testing and demonstrations.

8.4 Client Script Questions

Q: Do I need to keep the terminal open for the client script?
A: If running directly with node, yes. For production use on Windows, install it as a Windows service using node-windows. The script includes automatic recovery features and will continue running through server deployments.
Q: Can I run the client script on Windows?
A: Yes, the client script works on Windows, macOS, and Linux. It automatically detects the operating system and uses appropriate commands for system monitoring.
Q: What permissions does the client script need?
A: The script needs network access to send HTTP requests and read system information (CPU, memory, disk, processes). On Unix-like systems, it may need permissions to read /sys for device information. It does not require administrator/root privileges for basic operation.
Q: Can I modify the client script?
A: Yes, you can modify the script, but be careful not to break the heartbeat format or token authentication. If you modify it significantly, test thoroughly before deploying.
Q: What if the client script crashes?
A: The device will stop sending heartbeats and will be marked as offline after 60 seconds. The script is designed to recover automatically from most errors. For persistent running, install it as a Windows service.

8.5 User Management Questions

Q: Who can access Kirberos?
A: Only users with email addresses ending in @justzapp.com who have been added to the Users table by an administrator can access Kirberos.
Q: What's the difference between admin and regular users?
A: Admin users can access the Users tab in Settings to manage user accounts (add, edit, delete, enable/disable). Regular users can view the dashboard, manage clients, and view logs, but cannot manage users.
Q: Can I change a user's email address?
A: Yes, administrators can edit user details including email addresses. However, the new email must still end with @justzapp.com.
Q: What happens if I disable a user's account?
A: The user will be immediately logged out and unable to log back in until an administrator re-enables their account. Their existing session will be invalidated.
Q: Can I delete the default admin user?
A: Technically yes, but it's not recommended. Ensure you have at least one other admin user before deleting the default admin. If you delete all admin users, you'll need to manually add one back via the database.

9. Advanced Topics

9.1 Database Structure

Kirberos uses Firebase Firestore with the following collections:

clients
Stores client information: name, token, status, current IP, allowed IPs (JSON), exemption details, device information, timestamps.
logs
Event log entries: client_id, event_type, ip_address, details, timestamp. Foreign key to clients with CASCADE delete.
system_stats
Historical system statistics: client_id, cpu_usage, memory_usage, disk_usage, uptime, load_average, timestamp. Used for charts.
connectivity_logs
Connection/disconnection events: client_id, event_type, ip_address, isp, speed metrics, latency, timestamp.
processes
Process snapshots: client_id, process name, PID, CPU percentage, memory usage, timestamp.
users
User accounts: email, name, google_id, photo_url, enabled, is_admin, last_login, timestamps.
settings
Application settings: exemption_duration, test_mode, slack_channel_id, slack_enabled. Single row with id=1.

9.2 API Endpoints

Kirberos provides a REST API for client communication and dashboard operations:

POST /api/heartbeat
Client heartbeat endpoint. Requires token in request body. Returns status and exemption information.
GET /api/clients
Get all clients (requires authentication). Returns client list with system stats.
GET /api/clients/:id
Get single client details (requires authentication).
POST /api/clients
Create new client (requires authentication).
PUT /api/clients/:id
Update client (requires authentication).
DELETE /api/clients/:id
Delete client (requires authentication).
POST /api/clients/:id/manual-exempt
Start manual exemption (requires authentication).
DELETE /api/clients/:id/manual-exempt
Stop manual exemption (requires authentication).
GET /api/download/:token
Download client script for a specific client token. No authentication required (token is in URL).
GET /api/logs
Get activity logs (requires authentication). Supports ?limit parameter.
GET /api/settings
Get application settings (requires authentication).
PUT /api/settings
Update settings (requires authentication). Only non-sensitive settings can be updated.

9.3 Background Tasks (Cloud Functions)

Kirberos uses Firebase Cloud Functions for scheduled tasks:

checkExpiredExemptions (Every minute)
Checks clients for expired exemptions. Removes expired IPs from Cloudflare and updates client status.
checkOfflineClients (Every minute)
Checks clients for missing heartbeats. Marks clients as offline if no heartbeat received for 60+ seconds.
checkExpiredUnconfiguredExemptions (Every minute)
Checks unconfigured clients for expired exemptions.
cleanupExemptionLinks (Hourly)
Removes expired self-service exemption links.
cleanupOldData (Daily)
Purges old logs and data to keep the database clean.

9.4 IP Normalisation

Kirberos normalises IP addresses for consistent comparison:

  • Removes CIDR notation (e.g., 192.168.1.1/32192.168.1.1)
  • Converts to lowercase
  • Trims whitespace
  • Cloudflare stores IPs with /32 suffix, but Kirberos works with base IPs

9.5 Error Handling & Resilience

Kirberos includes several resilience features:

  • Graceful Degradation: If Cloudflare API fails, clients are marked "bad_ip" but system continues operating
  • Retry Logic: Failed exemption removals are retried on the next Cloud Function run
  • Idempotency: Adding an IP that already exists in Cloudflare is treated as success
  • Validation: All IP addresses are validated before processing
  • Error Logging: All errors are logged with context for troubleshooting

9.6 Performance Considerations

  • Database: Firestore scales automatically and handles concurrent operations
  • Heartbeat Frequency: 10-second intervals provide a balance between responsiveness and server load
  • Data Cleanup: Old data is automatically cleaned up by the cleanupOldData Cloud Function
  • Cloudflare API: Rate limits apply; Kirberos handles these gracefully
  • Concurrent Clients: The system handles multiple concurrent heartbeats efficiently

9.7 Security Best Practices

  • Environment Variables: Never commit sensitive values to version control
  • Session Security: Use strong, random SESSION_SECRET in production
  • HTTPS: Always use HTTPS in production. Set FORCE_HTTPS=true
  • API Tokens: Use least-privilege tokens with minimal required permissions
  • Database: Ensure database file has appropriate file permissions (not world-readable)
  • Client Scripts: Keep client scripts secure. Tokens in scripts provide full access to that client
  • User Management: Regularly review and disable unused accounts

9.8 Backup & Recovery

  • Database: Firestore data is automatically backed up by Google Cloud
  • Secrets: Ensure secrets in Secret Manager are documented securely
  • Client Scripts: Client scripts can be regenerated from the dashboard
  • Recovery: Firestore data persists automatically; redeploy via Firebase if needed

9.9 Customisation & Extension

Kirberos can be extended in several ways:

  • Custom Notifications: Modify sendSlackNotification or add new notification channels
  • Additional Monitoring: Extend client script to collect additional system metrics
  • Custom Statuses: Add new client statuses by modifying database schema and logic
  • Webhooks: Add webhook support to notify external systems of events
  • Reporting: Add reporting endpoints for analytics or compliance

10. Client Installation Guide

For detailed step-by-step instructions on installing the Kirberos client on Windows, see the instructions above.

Quick Start

  1. Install Node.js:
    • Open PowerShell as Administrator
    • Install Chocolatey (if needed): Remove-Item -Path "C:\ProgramData\chocolatey" -Recurse -Force -ErrorAction SilentlyContinue; Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
    • Install Node.js: choco install nodejs -y
  2. Add Client in Dashboard:
    • Go to Dashboard → Click "Add Client"
    • Enter client name and download the script
  3. Download Files:
  4. Configure install-service.js:
    • Open install-service.js in a text editor
    • Update line 7 with your client script filename
  5. Install Service:
    • Open Command Prompt as Administrator
    • cd C:\Kirberos
    • npm install -g node-windows
    • npm link node-windows
    • node install-service.js

Download Links:

Uninstalling the Service

To remove the Kirberos client service:

  1. Open Command Prompt as Administrator
  2. Navigate to C:\Kirberos
  3. Download uninstall-service.js and save to C:\Kirberos
  4. Run: node uninstall-service.js
  5. Wait for confirmation and press any key to exit

Credits & Attributions

Every component, library, and technology that makes Kirberos possible

About Kirberos

Kirberos is an IP address monitoring and management system that integrates with Cloudflare Zero Trust Access Policies. It watches over client devices like a vigilant guardian, tracking IP address changes and managing temporary exemptions so authorised users can always access protected resources.

The system runs client scripts on monitored devices that send heartbeats every 10 seconds with IP, ISP, and internet speed data. When a client's IP changes to something not on the allowed list, Kirberos automatically adds it to your Cloudflare Access Policy for a configurable duration. Users can also request self-service exemptions through Slack without installing any software.

Cloud Functions handle the background work – checking for expired exemptions, detecting offline clients, and cleaning up old data. Slack notifications keep administrators informed of important events, and the dashboard provides real-time visibility into all monitored devices.

This system was built using modern cloud technologies and draws upon tools and libraries from the global developer community.

Core Technologies

🟢

Node.js 18+

Server-side JavaScript Runtime

The engine that powers the entire backend, handling client heartbeats, API requests, and keeping everything running smoothly. JavaScript on the server – because apparently one runtime wasn't enough.

Created by: Ryan Dahl / OpenJS Foundation

License: MIT

🚂

Express.js

Web Application Framework

The minimalist web framework that handles all our API routes, middleware, and serves the dashboard. It's been around since 2010 and somehow still hasn't been replaced by the framework of the week.

Created by: TJ Holowaychuk

License: MIT

🔥

Firebase

Backend-as-a-Service Platform

Google's all-in-one platform hosting our database, running our Cloud Functions, and deploying the application. It's like having a DevOps team without actually having to hire a DevOps team.

Created by: Google LLC

License: Various / Proprietary

🗄️

Cloud Firestore

NoSQL Document Database

Our primary database storing all client data, logs, settings, and exemption records. A NoSQL database that actually scales without us having to think about it. Revolutionary.

Created by: Google LLC

License: Proprietary

Cloud Functions v2

Serverless Compute Platform

Running scheduled tasks every minute to check expired exemptions, detect offline clients, and clean up old data. Serverless computing – because managing servers is so 2015.

Created by: Google LLC

License: Proprietary

Integrations

🛡️

Cloudflare Zero Trust

Access Management Platform

The whole reason this system exists. We add and remove IP addresses from Access Policies via their API. Cloudflare's security might be paranoid, but that's exactly why we love it.

Created by: Cloudflare, Inc.

License: Proprietary

💬

Slack API

Team Communication Platform

Sending notifications about client status changes, exemptions, and important events. Because apparently we can't just check the dashboard – everything needs to be in Slack now.

Created by: Slack Technologies / Salesforce

License: Proprietary

🔐

Google OAuth 2.0

Authentication Protocol

Handling user authentication with single sign-on. No passwords to forget, no accounts to manage – just click the Google button and pray your session doesn't expire mid-task.

Created by: Google LLC

License: Google APIs Terms of Service

🔑

Secret Manager

Secrets Storage Service

Keeping our API tokens, OAuth secrets, and SMTP passwords secure. Because hardcoding credentials in environment variables is so passé.

Created by: Google Cloud

License: Proprietary

Libraries & Packages

📧

Nodemailer

Email Sending Library

Handling all email communications for self-service exemptions – link emails, confirmations, and expiry notifications. Because SMTP is definitely not complicated enough on its own.

Created by: Andris Reinman

License: MIT

🌐

Axios

HTTP Client Library

Making HTTP requests to Cloudflare, Slack, and various IP lookup services. Fetch is fine, but Axios has better error handling and we're not savages.

Created by: Matt Zabriskie

License: MIT

🎫

Passport.js

Authentication Middleware

Handling Google OAuth authentication with elegant simplicity. Making authentication feel less like a root canal and more like a minor inconvenience.

Created by: Jared Hanson

License: MIT

🆔

UUID

Unique Identifier Generator

Generating unique tokens for clients and exemption links. Because sequential IDs are too predictable and we need our identifiers to look properly random and professional.

Created by: Robert Kieffer

License: MIT

Frontend Technologies

📊

Chart.js

JavaScript Charting Library

Creating beautiful charts for internet speed history in the client details modal. Because numbers are boring but colourful lines going up and down? That's data visualisation.

Created by: Chart.js Contributors

License: MIT

🔤

Google Fonts

Typography Library

Delivering the Manrope font family for that clean, modern look. Zapp's branding demands nothing less than premium typography, even if it means loading fonts from Google's servers.

Created by: Google

License: SIL Open Font License

🌐

HTML5 & CSS3

Markup & Styling Languages

The foundation of the entire dashboard. No frameworks, no build tools – just good old fashioned HTML and CSS. Sometimes the classics are classics for a reason.

Created by: W3C

License: Open Standard

Vanilla JavaScript

Client-side Scripting

All the interactivity without a single npm install. No React, no Vue, no Angular – just JavaScript the way Brendan Eich intended (probably).

Created by: Brendan Eich / ECMA International

License: Open Standard

Development Tools

🤖

Cursor AI

AI-Powered Code Editor

The AI coding assistant that helped build this entire system. From complex Cloud Functions to elegant CSS animations, it's like pair programming with someone who's read every Stack Overflow post ever written.

Created by: Anysphere Inc.

License: Proprietary

🔧

Git & GitHub

Version Control & Collaboration

Managing source code, tracking changes, and enabling collaborative development. Because emailing ZIP files of code back and forth is apparently no longer acceptable in polite society.

Created by: Linus Torvalds (Git), GitHub Inc.

License: GPL v2 / MIT

🔥

Firebase CLI

Command Line Deployment Tool

Deploying Cloud Functions, managing Firestore rules, and generally making deployment feel like it's 2025 instead of manually FTPing files like it's 1999.

Created by: Google LLC

License: Apache 2.0

External Services

🌍

ipify.org

Public IP Detection API

Helping client scripts figure out their public IP address. Simple, reliable, and doesn't ask questions about why we need to know.

Created by: Randall Degges

License: Free API

📡

ipapi.co & ip-api.com

IP Geolocation Services

Looking up ISP information for client connections. With multiple fallbacks because apparently no single IP lookup service can be trusted to stay online 100% of the time.

Created by: Various

License: Free Tier

Cloudflare Speed Test

Internet Speed Measurement

Running download speed tests from client devices every 60 seconds. Using Cloudflare's own infrastructure to measure speeds – it's like asking the postman how fast he can run.

Created by: Cloudflare, Inc.

License: Free