Getting Started
Quick Start Architecture
AI Agents
MSP Hunter Threat Researcher Tech Support Compliance Agent Account Manager Onboarding Agent
Compliance
HIPAA SOC 2 PCI-DSS NIST
Guides
First 30 Days Scaling
API
Overview Endpoints

Architecture Overview

🔧 Technical Reference 12 min read Updated June 2026

Gridlock is a Node.js monolith with a pure HTML/CSS/JS frontend, six AI agent services, a Better-SQLite3 database, and a Cloudflare tunnel handling all public traffic. This document describes how every layer fits together — useful for contributors, integration partners, and MSP technical staff who want to understand what is running inside the shield.

Intentional Simplicity

Gridlock deliberately avoids framework bloat. There is no React, no ORM, no message queue, and no microservice boundary. The entire product runs as a single Node.js process. This makes it fast to deploy, easy to reason about, and resilient — there is nothing to go wrong except the one thing you can see.

System Architecture

All inbound requests flow through Cloudflare's edge, through the tunnel, into the Express HTTP server running on the homeserver, where they are routed to either static file serving (the frontend) or the API layer (agents, auth, dashboard, compliance). The AI agents call out to the Z.AI provider abstraction layer, which selects the appropriate upstream model and returns structured JSON. Results are persisted to SQLite and sent back to the browser.

🌐 Browser

Pure HTML/CSS/JS frontend at public/

☁️ Cloudflare

Edge CDN + WAF + tunnel

🚀 Express

Node.js HTTP server + router

🤖 Agents

Six AI service modules

🗄️ SQLite

Better-SQLite3 persistence

Tech Stack

Every component in the stack was chosen for operational simplicity, not fashion. The constraint "never change the tech stack" exists precisely because this combination works reliably in production.

🟢

Node.js

Runtime for the HTTP server, agent services, billing webhooks, and all background jobs.

Backend

Express

Minimal HTTP framework. Routes are defined in src/routes/. Middleware handles auth, rate limiting, and error formatting.

HTTP Layer
🗄️

Better-SQLite3

Synchronous SQLite bindings. Faster than async alternatives for the read-heavy dashboard query patterns. One file, zero infra.

Database
📄

Pure HTML/CSS/JS

All frontend files live in public/. No build step, no bundler, no framework. Every page is a plain .html file with linked CSS and JS.

Frontend
🧠

Z.AI GLM-5

Primary AI provider powering all six agents. Accessed through the provider abstraction layer, which supports failover to alternate models.

AI Provider
🐛

Sentry

Error tracking and performance monitoring. All unhandled exceptions are captured with context. No stack traces ever reach API responses.

Observability
Do Not Change the Tech Stack

Adding React, Vue, an ORM, a message broker, or any frontend build tool is explicitly prohibited. The constraint exists because the current stack deploys as a single process with zero build steps, which is why uptime is so high. Complexity is the enemy of reliability.

The Six AI Agents

Each agent is a service module in src/agents/ or src/services/. Agents share no direct memory — they communicate through the database and through the dashboard UI that orchestrates execution. An agent run is triggered by a user action or a scheduled job, constructs a prompt with the relevant context, calls the AI provider, parses the response, and writes the result to the appropriate database table.

Agent Source File Trigger Primary Output
MSP Hunter src/agents/msp-hunter.js Manual execution or campaign schedule Scored lead records written to leads table with contact data and email variants
Threat Researcher src/services/threat-researcher.js Manual prompt or CVE watchlist trigger Threat brief with CVSS score, MITRE mapping, and remediation steps written to security_events
Tech Support src/services/tech-support.js Ticket submission via dashboard or API Resolution steps appended to the ticket record; escalation flag set when confidence is low
Compliance Engine src/services/compliance-engine.js Manual audit trigger or scheduled weekly run Compliance report with gap analysis written to compliance_reports
Account Manager src/services/account-manager.js Nightly scheduled job Health score, churn risk flag, and expansion signals written to the organization record
Onboarding Agent src/routes/onboarding.js New account creation; re-triggered on each wizard step Step completion events, initial security score seed, and guided tour state stored per user

AI Provider Abstraction Layer

All agent calls go through a thin abstraction layer rather than calling the AI provider SDK directly. This layer handles:

Graceful Degradation

If the AI provider is unreachable, agents return a clear error message in the dashboard rather than hanging or silently failing. The error is captured in Sentry with the full request context. Scheduled jobs back off with exponential delay and retry up to three times before marking the execution as failed.

Database Schema

Gridlock uses a single Better-SQLite3 database file. All queries use parameterized statements — there is no string concatenation in SQL calls anywhere in the codebase. The key tables are described below.

users

ColumnTypeDescription
idINTEGER PKAuto-increment primary key
emailTEXT UNIQUEUser email address (login identifier)
password_hashTEXTbcrypt hash — plain text is never stored
nameTEXTDisplay name
roleTEXTadmin or member
org_idINTEGER FKForeign key to organizations
email_verifiedINTEGER0 or 1 boolean
created_atTEXTISO 8601 timestamp

organizations

ColumnTypeDescription
idINTEGER PKAuto-increment primary key
nameTEXTOrganization display name
industryTEXTIndustry vertical slug
team_sizeINTEGERApproximate headcount
planTEXTstarter, pro, or ultimate
security_scoreINTEGERLatest composite security score (0–100)
ls_customer_idTEXTLemonSqueezy customer identifier
created_atTEXTISO 8601 timestamp

security_events

ColumnTypeDescription
idINTEGER PKAuto-increment primary key
org_idINTEGER FKOwning organization
typeTEXTEvent category (e.g. threat, dns_anomaly, compliance_gap)
severityTEXTcritical, high, medium, or low
titleTEXTShort human-readable event title
descriptionTEXTFull event detail and AI-generated context
resolvedINTEGER0 or 1 boolean
created_atTEXTISO 8601 timestamp

agent_executions

ColumnTypeDescription
idINTEGER PKAuto-increment primary key
org_idINTEGER FKOwning organization
agent_idTEXTAgent slug (e.g. threat-researcher)
statusTEXTpending, running, completed, or failed
input_promptTEXTUser-supplied prompt text
outputTEXTStructured JSON result from the agent
tokens_usedINTEGERTotal tokens consumed (prompt + completion)
duration_msINTEGERWall-clock time of the AI call in milliseconds
created_atTEXTISO 8601 timestamp

Other Key Tables

Security Architecture

Gridlock is a security product — it must be hardened against the same threats it helps customers detect. The security model is defense in depth across five layers:

Edge (Cloudflare) WAF rules, DDoS mitigation, bot management, and TLS termination before traffic reaches the origin server. IP-level blocking for known malicious ranges.
Transport All traffic travels over TLS 1.3 minimum. The Cloudflare tunnel uses mutual TLS between Cloudflare's edge and the origin. HSTS enforced.
Authentication JWT tokens (HS256) with 24-hour expiry. Tokens are invalidated server-side on logout and password change. Rate limiting on all auth endpoints (10 req/min). No session cookies — bearer token only.
Authorization Role checks on every authenticated route. Every database query is scoped to org_id — even if a token is valid, it cannot access another organization's data. Admin-only routes enforce role separately from authentication.
Application Parameterized SQL everywhere. Input validation on all request bodies. XSS prevention via output escaping before any user data is rendered in HTML. CSRF tokens on all state-changing requests. No stack traces in production API responses.

Audit Logging

Every sensitive action is written to the audit_log table synchronously before the response is returned: user registrations, logins and logouts, password changes, agent executions, compliance report generation, billing events, team member additions and removals, and API key operations. Each record includes the user ID, IP address, user agent, action type, and a JSON payload with the relevant context. The audit log is append-only — no delete routes exist for it.

API Keys vs. JWT Tokens

JWT tokens are for interactive dashboard sessions and expire in 24 hours. API keys (available at Dashboard → Settings → API Keys) are long-lived machine credentials for integration use. API keys can be scoped to read-only or read-write and revoked at any time. Never use a JWT token in automated scripts — use an API key instead.

Billing Integration

Gridlock uses LemonSqueezy for subscription management. The billing flow works as follows:

  1. When a user upgrades, the frontend redirects them to a LemonSqueezy-hosted checkout page with the organization's customer ID pre-filled.
  2. On successful payment, LemonSqueezy fires a webhook to POST /api/billing/webhook.
  3. The webhook handler verifies the request signature using the shared secret, then updates the organization's plan field in the database.
  4. Subscription changes (upgrades, downgrades, cancellations) and payment failures all arrive via the same webhook endpoint and are handled by event type.
  5. All billing webhook events are written to the audit log regardless of outcome.
Webhook Signature Verification

Every incoming webhook request is verified using HMAC-SHA256 with the LemonSqueezy webhook secret before any processing occurs. Requests with invalid or missing signatures return 401 Unauthorized and are logged. No billing state is ever mutated without a valid signature.

Deployment

Production runs on a homeserver at 100.70.240.55, accessible publicly via a Cloudflare tunnel. The full deployment path from browser to database looks like this:

Browser

lockthegrid.com

Cloudflare Edge

WAF + CDN

cloudflared

Tunnel daemon

NSSM Service

Auto-restart wrapper

Node.js

Express server

SQLite

On-disk DB

NSSM Service

The Node.js process runs as a Windows service managed by NSSM (Non-Sucking Service Manager). NSSM handles:

Cloudflare Tunnel

The tunnel runs as a separate cloudflared process that maintains an outbound connection to Cloudflare's edge. There are no inbound ports open on the homeserver's firewall — all traffic enters through the tunnel. This means:

Deploying an Update

  1. Push to master on GitHub.
  2. SSH or RDP into 100.70.240.55.
  3. Navigate to C:\builds\gridlock and run git pull origin master.
  4. Run npm install if package.json changed.
  5. Restart the NSSM service: nssm restart gridlock.
  6. Verify the health endpoint: curl https://lockthegrid.com/api/dashboard/health.
Live Production Users

lockthegrid.com has live production users and live Stripe keys. Never push breaking changes without testing locally first. Test with npm test before every deploy. If a migration changes the database schema, test the migration on a copy of the production database file before running it on the server.