Skip to content

Repository files navigation

Zero Trust Guard

A self-hosted security gateway that protects your applications behind a single, enforceable rule:

Every HTTP/HTTPS request must carry a token the gateway verifies. No token → no server response.

Built on Node.js + TypeScript with a shadCN UI dashboard, a CLI, a demo upstream API, Docker, tests, and a benchmark. Every component shares one type system via npm workspaces.

Why

Too many services expose their own auth, so enforcement is scattered and weak. Zero Trust Guard centralizes authentication, authorization, device binding, and rate limiting at the perimeter — the upstream server never sees an unverified request.

How it works

Client ── Bearer <access JWT> ──▶ Gateway ──▶ Upstream
                                  │
  1. token signature + expiry      │
  2. server-side session check     │  (revocation is instant)
  3. account status                │
  4. device binding                │
  5. policy (roles, deny, ratelimit)
  6. reverse proxy (injects x-ztg-*)

A failed check returns a clean 401/403 before any upstream round trip. Sessions, devices, and rate counters live in Valkey/Redis (with an in-memory dev fallback); the audit trail lives in PostgreSQL (with an NDJSON file fallback).

Features

  • Layered zero-trust gate: JWT signature → session → account → device.
  • Short-lived access tokens (HS256 via node:crypto) + rotating refresh tokens.
  • Immediate revocation of sessions and devices.
  • Policy engine: role requirements, explicit deny rules, per-route rate limits.
  • Per-IP login and global rate limiting.
  • Admin control plane: manage sessions, devices, routes, policies, audit, metrics.
  • Live dashboard over WebSocket (/ws): audit events + metrics pushed in real time.
  • Demo upstream that refuses to answer unless x-ztg-verified is present.
  • CLI (ztg) for scriptable administration.
  • Docker Compose stack (postgres + valkey + gateway + dashboard + demo).

Getting started

Docker (recommended)

cp .env.example .env    # set ZTG_JWT_SECRET
docker compose up --build
  • Dashboard: http://localhost:3000
  • Gateway health: curl http://localhost:8080/health
  • Demo credentials: admin/admin123 (admin), user/user123, blocked/blocked123 (suspended)

React + Express demo ("why do we need this if we already have HTTPS?")

A self-contained demo (demo-react + demo-express) showing the gateway standing between a React frontend and an Express backend — and why that matters beyond HTTPS.

React app ──Bearer JWT──▶ Zero Trust Gateway ──x-ztg-verified──▶ Express API

Run it locally

npm install
npm run build -w @ztg/demo-express -w @ztg/demo-react

node demo-express/dist/index.js                     # terminal A :4000
env ZTG_REDIS_URL="" ZTG_DATABASE_URL="" ZTG_PORT=8080 node src/gateway/dist/index.js  # terminal B
npm run dev -w @ztg/demo-react                       # terminal C http://localhost:5173

In the browser: log in as admin/admin123, then try calling /demo/secret with the real token, no token, and a forged token; revoke your own live session and watch the next request die with 401 despite HTTPS + a still-valid token; finally open the deliberately-insecure /demo/insecure route to see the "trusted HTTPS only" failure mode. Full explanation: docs/why-zerotrust-over-https.md.

Local development

npm install
npm run build
npm run dev -w @ztg/dashboard

Start the gateway with the in-memory fallback (single instance, dev only):

env ZTG_REDIS_URL="" ZTG_DATABASE_URL="" ZTG_PORT=8080 node src/gateway/dist/index.js

CLI examples

node src/cli/dist/index.js login admin admin123
node src/cli/dist/index.js metrics
node src/cli/dist/index.js session list
node src/cli/dist/index.js route list

Repository layout

src/shared      shared types, errors, config, logger, utils   (@ztg/shared)
src/gateway     the zero-trust security gateway                (@ztg/gateway)
src/cli         ztg command-line tool                          (@ztg/cli)
dashboard       Next.js + Tailwind + shadCN UI                 (@ztg/dashboard)
demo            demo upstream (refuses unverified traffic)     (@ztg/demo)
demo-express    Express backend for the React+Express demo     (@ztg/demo-express)
demo-react      React frontend for the React+Express demo     (@ztg/demo-react)
configs         users.json, routes.json, policies.json
docs            architecture, security, threat model, ADRs, performance, deployment

Configuration

All settings are environment-driven (ZTG_*), see .env.example and docs/deployment.md. Users, routes, and policies load from configs/ at boot (ZTG_CONFIG_DIR); route upstreams may use env:NAME so the same config runs locally and in Docker.

Tests & benchmarks

npm test                          # all workspaces
npm run test -w @ztg/gateway      # unit + integration tests
npm run bench -w @ztg/gateway     # benchmark (see docs/performance.md)

Documentation

About

A self-hosted security gateway that protects your applications behind a single, enforceable rule:

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages