Skip to main content
Version: Community (1.0.0)

Architecture

Architecture

How WebXTerm Works

Agent-based, zero-trust architecture. The agent connects on one port that is 8081 outbound/inbound traffic — no open ports, no VPN, no bastion hosts.

CLIENT LAYER
🌐
Browser
Web Terminal
VS Code
Extension
$_
VSAY CLI
Shell Tool
HTTPS / WSS
WebXTerm Portal
Control Hub
AuthRouterAuditRegistry
CONTROL PLANE
gRPC / mTLS
vsay-agent
On your machine
Outbound/Inbound on one port only (8081) SystemdHeartbeat
AGENT
LOCAL IPC
MACHINE LAYER
🖥
prod-server-01
Linux / x86
💻
dev-laptop
macOS / M1
bare-metal-02
Linux / ARM
Client connection (HTTPS/WSS) Agent tunnel (gRPC/mTLS) — outbound Active session

How WebXTerm Works

┌─────────────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Browser │ │ VS Code │ │ VSAY CLI │ │
│ │ Web Terminal │ │ Extension │ │ Shell Tool │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ └─────────────────┬┘──────────────────┘ │
└────────────────────────────┼────────────────────────────────────────┘
│ HTTPS / WSS

┌─────────────────────────────────────────────────────────────────────┐
│ WEBXTERM PORTAL │
│ (Control Hub :8080) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Auth │ │ Router │ │ Command │ │ Registry │ │
│ │ JWT │ │ Terminal │ │ History │ │ API Keys │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │
└────────────────────────────┬────────────────────────────────────────┘
│ gRPC + TLS (:8081)
│ Outbound/Inbound on one port only (8081) — agent initiates

┌─────────────────────────────────────────────────────────────────────┐
│ MACHINE LAYER │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ vsay-agent │ │
│ │ (On your machine) │ │
│ │ │ │
│ │ Outbound only │ Systemd service │ Heartbeat 30s │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ prod-server │ │ dev-laptop │ │ bare-metal-02 │ │
│ │ Linux / x86 │ │ macOS / M1 │ │ Linux / ARM │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────────────┘

Legend:

  • 🔵 Client connection (HTTPS/WSS)
  • 🟢 Agent tunnel (gRPC/TLS) — Outbound/Inbound on one port only (8081)
  • 🟠 Active session

Key Design Principles

1. Outbound-Only Agent Tunnel

The vsay-agent always initiates the connection outbound to the backend over gRPC. This means:

  • No open inbound ports on your machines
  • No firewall rule changes required
  • Works behind NAT, behind corporate firewalls, on any network
  • The agent auto-reconnects on network interruptions or backend restarts

2. TLS-Encrypted, API-Key Authenticated

The agent connection is encrypted with standard (server-verified) TLS — the agent verifies the backend's certificate, same as a browser verifying a website. On top of that, the agent authenticates itself with its API key on every connection:

Backend → presents TLS certificate → Agent verifies ✅
Agent → presents API key → Backend verifies ✅
  • No SSH keys to rotate — just one API key per account, regenerable from the Profile page
  • Mutual TLS (client-certificate authentication issued from a private CA) is an Enterprise Edition feature — see the Enterprise Architecture docs

3. Single-Account Model (Community)

Community Edition is single-account, not multi-user: whoever signs up owns the account and every machine registered under it. There are no roles, no per-machine access grants, and no separate admin/user distinction — that hierarchical RBAC model is an Enterprise feature (see the Enterprise docs' Architecture page).

4. Access Flow

Every terminal session goes through this verification chain:

User clicks Connect


1. JWT validated → is this a real logged-in user?


2. Agent located → is this machine online with active gRPC stream?


3. Session bridged → WebSocket ↔ gRPC stream connected


4. Command recorded → command text + timestamp saved to that machine's history

No step can be skipped — a session cannot open against a machine that is offline or without a valid token.


Component Overview

ComponentRolePort
WebXTerm BackendControl plane — auth (bcrypt+JWT), routing, command history8080 (HTTP)
vsay-agentLightweight daemon on each machineoutbound to 8081
gRPC serverAgent tunnel endpoint over TLS8081

Agent Connection Lifecycle

1. vsay-agent configure --token <API_KEY>


Agent saves the API key and backend host to /etc/vsay/agent.yaml
Agent installs itself as a systemd service

2. Every start / reconnect (restarts, network blips):
Agent opens TLS connection to backend
Agent presents its API key → Backend verifies ✅ → online
No certificate provisioning step — just the saved key

3. If the API key is regenerated:
Old key is rejected → agent goes offline
Re-run `vsay-agent configure` with the new key to reconnect
Enterprise Only

Enterprise Edition replaces this with a private-CA-issued client certificate per agent (true mTLS), so agents self-heal across CA rotations without re-entering a key. See the Enterprise Architecture docs.