Auth & Telemetry Plugin
Extend Explita Tunnel with database authentication, email OTP, instant token issuance, and zero-log telemetry using @explita/tunnel-server-plugin
When running a multi-user or enterprise tunnel server, you need a way to authenticate developers, issue revocable device tokens, and monitor cluster throughput.
The @explita/tunnel-server-plugin is an all-in-one modular Fastify plugin that hooks directly into the gateway server to provide:
- Passwordless Email OTP Authentication: Developers authenticate using 6-digit one-time passcodes delivered via email or displayed in server logs.
- Instant Zero-Friction Token Issuance: Headless environments (such as CI/CD pipelines or Explita Deploy servers) obtain tokens immediately via IP and machine ID at
POST /_api/token/issuewithout requiring interactive steps. - Multi-Device Token Management: Persists developer accounts and API tokens in PostgreSQL via Prisma with Redis-backed caching.
- Zero-Log Telemetry Aggregates: Records anonymous daily and system metrics without saving any user payload data.
- Internal Stats API: Exposes protected cluster metrics at
GET /_api/statsfor Prometheus, Datadog, or custom admin dashboards.
📦 Installation
In your tunnel gateway project:
pnpm add @explita/tunnel-server-plugin🔌 Enabling the Plugin
The tunnel gateway uses an untracked tunnel.config.js configuration file (which is in .gitignore) so your plugins, custom middleware, and configurations are never overwritten when running git pull for upstream updates.
1. Copy Configuration Template
In your cloned gateway root:
cp tunnel.config.example.js tunnel.config.js2. Configure tunnel.config.js
The generated tunnel.config.js hooks the plugin into Fastify and forwards the token validator to the gateway WebSocket engine:
import {
registerTunnelPlugin,
validateToken,
} from "@explita/tunnel-server-plugin";
/**
* Configure custom plugins and middleware for the Explita Tunnel gateway.
*
* @param {import("fastify").FastifyInstance} app - The Fastify server instance
* @param {object} context - Gateway context
* @param {any} context.registry - Active tunnel connections registry
* @param {object} context.metricsCollector - Gateway telemetry collector
*/
export default async function configure(app, context) {
// Register the auth & telemetry plugin
registerTunnelPlugin(app, {
internalSecret: process.env.INTERNAL_SECRET, // Secret for GET /_api/stats
metricsCollector: {
setPersister: (p) => context.metricsCollector.setPersister(p),
getActiveTunnelsCount: () => context.registry.size,
getSnapshot: () => context.metricsCollector.getSnapshot(),
getStats: (s) => context.metricsCollector.getStats(s),
},
// Optional SMTP credentials for email OTP verification
smtp: {
from: "Explita Tunnel <[email protected]>",
host: "smtp.example.com",
port: 587,
auth: {
user: "smtp_user",
pass: "smtp_secret_token",
},
},
});
// Forward the plugin's token validator to the WebSocket connection handler
return {
validateToken, // Checks Redis first, falls back to PostgreSQL
};
}3. Sync Database Schema
Push the plugin's pre-bundled Prisma schema to your PostgreSQL database:
pnpm db:push🌐 Exposed Endpoints
Once registered, the plugin mounts standard HTTP endpoints onto your Fastify gateway instance:
| Method | Endpoint | Auth / Secret | Description |
|---|---|---|---|
POST | /_api/token/request-otp | Public | Dispatches a 6-digit verification code to the developer's email address (or logs it in development). |
POST | /_api/token/verify-otp | Public | Validates the OTP code, creates/fetches the developer profile, and returns an active developer token (exp_live_...). |
POST | /_api/token/issue | Public | Issues an instant token keyed to the server IP and machine ID for headless servers and CI/CD pipelines. |
GET | /_api/stats | x-internal-secret | Exposes real-time active tunnel counts, daily aggregated telemetry, and lifetime cluster metrics. |
🗄️ Zero-Configuration Database Management
The plugin internally embeds and manages its own pre-generated Prisma Client and connection pooling via @prisma/adapter-pg. Your gateway server application does not need to install @prisma/client, define schemas, or run Prisma build scripts.
Simply supply the PostgreSQL connection string in your server environment, example:
DATABASE_URL=postgresql://user:password@localhost:5432/explita_tunnelWhen DATABASE_URL is detected at startup, the plugin automatically activates its internal database client, initializes the cache layers, and hooks into validateToken and metrics collection. If DATABASE_URL is omitted, the plugin gracefully falls back to in-memory mode.
Pushing Schema to PostgreSQL
For new server setups, apply the plugin's schema to your database using the built-in CLI:
# Run via npx (reads DATABASE_URL from your .env)
npx @explita/tunnel-server-plugin db:push
# Or from within your tunnel gateway project
pnpm db:pushThe CLI automatically reads DATABASE_URL from your .env file and executes Prisma's engine push without requiring extra Prisma configuration files or dependencies. You can also pass standard flags like --accept-data-loss or --force-reset.
📧 Email OTP Authentication Flow
Developers authenticate without passwords directly through the CLI or via automated scripts:
Developer Terminal Gateway Server (Plugin) PostgreSQL / Redis
│ │ │
│ 1. eta token -e [email protected] │ │
├────────────────────────────────────────────►│ │
│ POST /_api/token/request-otp │ 2. Generate 6-digit OTP code │
│ │ Store code in Redis (10m TTL) │
│ │ Send Email via Nodemailer │
│ │ │
│ 3. eta token -e [email protected] -v 849201 │ │
├────────────────────────────────────────────►│ 4. Verify code in Redis │
│ POST /_api/token/verify-otp │ Find or create Developer │
│ ├─────────────────────────────────►│
│ │ Issue Token (exp_live_...) │
│ │◄─────────────────────────────────┤
│ 5. Save Token locally (~/.explita/config) │ │
│◄────────────────────────────────────────────┤ │1. Requesting an OTP (POST /_api/token/request-otp)
curl -X POST https://tunnel.yourdomain.com/_api/token/request-otp \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'Response:
{
"success": true,
"message": "Verification code sent to [email protected]"
}[!TIP] In local development environments without an active SMTP server, the generated OTP is logged directly to the server terminal:
[tunnel-auth] [DEV MODE] OTP code for [email protected] is 849201.
2. Verifying the Code (POST /_api/token/verify-otp)
curl -X POST https://tunnel.yourdomain.com/_api/token/verify-otp \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "code": "849201"}'Response:
{
"success": true,
"token": "exp_live_a1b2c3d4e5f6...",
"email": "[email protected]"
}3. Instant Token Issuance (POST /_api/token/issue)
For headless servers (like Explita Deploy), CI/CD pipelines, or zero-configuration environments, the plugin provides an instant token issuance endpoint that identifies instances by server IP and machine ID without requiring an interactive email OTP flow:
curl -X POST https://tunnel.yourdomain.com/_api/token/issue \
-H "Content-Type: application/json" \
-d '{"ip": "92.4.154.196", "machineId": "optional-machine-uuid"}'Response:
{
"success": true,
"token": "exp_live_7c8d9e0f1a2b3c...",
"message": "Tunnel token issued successfully"
}[!TIP] If a server with the same IP or machine ID requests a token again within 30 days, the plugin automatically returns its existing active token, ensuring continuous usage metrics without generating duplicate tokens.
⚡ High-Performance Token Validation
When thousands of developers connect to the tunnel server, querying PostgreSQL on every WebSocket handshake introduces database latency.
The plugin implements a two-tier verification architecture:
- Tier 1 (Redis Cache): Checks
token:verified:<token>. If found, extends the key TTL to 7 days and completes the handshake in< 1ms. - Tier 2 (PostgreSQL Fallback): If cache misses (e.g. after a Redis restart), queries the
Tokentable, verifiesrevokedAt === null, updateslastUsedAtasynchronously, and re-warms the Redis cache.
📊 Cluster Stats API (GET /_api/stats)
The plugin registers an administrative endpoint at /_api/stats protected by the x-internal-secret header:
curl -H "x-internal-secret: your_internal_secret_here" \
https://tunnel.yourdomain.com/_api/statsResponse:
{
"activeTunnels": 18,
"lifetime": {
"totalTunnels": 14250,
"totalRequests": 9840210,
"totalBytes": 42949672960
},
"today": {
"date": "2026-10-19",
"tunnelsOpened": 320,
"requestsRouted": 148520,
"bytesTransferred": 892010440,
"activeDevelopers": 42
}
}Use this endpoint to monitor cluster capacity, track server load, or power internal usage dashboards.