Skip to content

Documentation

Telemetry Server Implementation

Technical specification for implementing the SveltyCMS telemetry receiver.

3/27/2026
3 min read Edit on GitHub

This document outlines the technical specifications for the SveltyCMS Telemetry Receiver. This server is responsible for receiving health checks from SveltyCMS instances, aggregating anonymous usage data, and returning security status updates.

1. Registration Flow

Before a client can send telemetry data, it must first register to receive a unique secret.

Registration Endpoint

  • URL: https://telemetry.sveltycms.com/api/register
  • Method: POST
  • Payload: { "installation_id": string }
  • Response: { "success": true, "secret": string }

HMAC Authentication

All telemetry requests (/api/check-update) must then be signed using this secret via HMAC-SHA256.

Replay Protection

Requests must include a timestamp (Unix milliseconds). The server MUST reject any request where the timestamp is older than 5 minutes or more than 1 minute in the future.

2. API Specification

  • URL: https://telemetry.sveltycms.com/api/check-update
  • Method: POST
  • Content-Type: application/json

Request Payload

interface TelemetryPayload {
  // Required fields
  current_version: string; // "0.9.0"
  node_version: string; // "v20.10.0"
  environment: string; // "production"
  os: string; // "linux"
  installation_id: string; // SHA256 hash of JWT_SECRET_KEY

  // Authentication fields (REQUIRED)
  timestamp: number; // Unix timestamp in milliseconds
  signature: string; // HMAC-SHA256 signature (hex)

  // ... rest of payload
}

Signature Generation

The signature is computed over the string: installation_id:current_version:timestamp using the secret obtained during registration.

const data = `${payload.installation_id}:${payload.current_version}:${payload.timestamp}`;
const signature = crypto.createHmac("sha256", clientSecret).update(data).digest("hex");

3. Implementation Logic

A robust telemetry server should perform the following steps:

  1. Validate Timestamp: Ensure the request is not a replay (5-minute window).
  2. Fetch Secret: Look up the secret for the given installation_id.
  3. Validate Signature: Recompute the HMAC and use crypto.timingSafeEqual for comparison.
  4. Data Ingestion: Log the anonymous data to your analytics database.
  5. Version Check: Compare current_version against the latest release and known vulnerabilities.

Signature Validation Code (Example)

function validateSignature(payload: TelemetryPayload, clientSecret: string): boolean {
  const { installation_id, current_version, timestamp, signature } = payload;

  // 1. Check timestamp (5-minute window)
  const age = Date.now() - timestamp;
  if (age > 5 * 60 * 1000 || age < -60 * 1000) {
    return false;
  }

  // 2. Recompute expected signature
  const data = `${installation_id}:${current_version}:${timestamp}`;
  const expected = crypto.createHmac("sha256", clientSecret).update(data).digest("hex");

  // 3. Constant-time comparison
  return crypto.timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(expected, "hex"));
}

4. Response Codes

Status Meaning
200 Telemetry accepted, signature valid
400 Invalid payload format
403 Authentication failed (invalid signature or expired timestamp)
429 Rate limited
500 Internal server error

5. Deployment

The telemetry receiver is stateless and ideal for serverless deployment on Cloudflare Workers, Vercel, or Fly.io.

6. Client Auto-Recovery & Diagnostics

  • Auto-Recovery: When the telemetry receiver returns a 403 Forbidden response (e.g. indicating database resets or desynchronized secrets), the SveltyCMS client is designed to purge its locally cached TELEMETRY_CLIENT_SECRET and immediately invoke the /api/register endpoint to start a new handshake session.
  • Client Diagnostics Route: The SveltyCMS client exposes a local route /api/telemetry/diagnose that runs a step-by-step diagnostic test (checking endpoint GET ping, registration OPTIONS availability, and real payload signature verification).

Related

telemetryserverapi
Was this page helpful?