Explita InfraExplita Infra
Tunnel

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:

  1. Passwordless Email OTP Authentication: Developers authenticate using 6-digit one-time passcodes delivered via email or displayed in server logs.
  2. 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/issue without requiring interactive steps.
  3. Multi-Device Token Management: Persists developer accounts and API tokens in PostgreSQL via Prisma with Redis-backed caching.
  4. Zero-Log Telemetry Aggregates: Records anonymous daily and system metrics without saving any user payload data.
  5. Internal Stats API: Exposes protected cluster metrics at GET /_api/stats for 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.js

2. 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:

MethodEndpointAuth / SecretDescription
POST/_api/token/request-otpPublicDispatches a 6-digit verification code to the developer's email address (or logs it in development).
POST/_api/token/verify-otpPublicValidates the OTP code, creates/fetches the developer profile, and returns an active developer token (exp_live_...).
POST/_api/token/issuePublicIssues an instant token keyed to the server IP and machine ID for headless servers and CI/CD pipelines.
GET/_api/statsx-internal-secretExposes 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_tunnel

When 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:push

The 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:

  1. Tier 1 (Redis Cache): Checks token:verified:<token>. If found, extends the key TTL to 7 days and completes the handshake in < 1ms.
  2. Tier 2 (PostgreSQL Fallback): If cache misses (e.g. after a Redis restart), queries the Token table, verifies revokedAt === null, updates lastUsedAt asynchronously, 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/stats

Response:

{
  "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.

On this page