telemt/docs/API.md

4.0 KiB

Telemt Control API

Purpose

This document specifies the control-plane HTTP API used for:

  • runtime statistics access,
  • user management,
  • safe configuration mutations.

The data-plane (MTProto proxy traffic) is out of scope.

Design Principles

  1. Keep data-plane isolated. The API must not affect MTProto hot paths.

  2. Keep configuration authoritative. config.toml is the single source of truth for managed entities.

  3. Make writes safe. All config mutations are validated and persisted atomically.

  4. Be explicit about concurrency. Mutating endpoints support optimistic concurrency through revision matching.

  5. Prefer fail-fast contract errors. Input validation errors are returned with machine-readable error codes.

Runtime and Configuration

Control API runtime is configured under [server.api].

Parameters:

  • enabled: bool
  • listen: "IP:PORT"
  • whitelist: [CIDR, ...]
  • auth_header: string (exact match against Authorization header; empty disables header auth)
  • request_body_limit_bytes: usize
  • read_only: bool

Backward compatibility:

  • server.admin_api is accepted as an alias while server.api is canonical.

Operational note:

  • Changes in server.api require process restart to take effect.

Protocol Contract

  • Transport: HTTP/1.1
  • Payload format: JSON (application/json; charset=utf-8)
  • API prefix: /v1

Success Envelope

{
  "ok": true,
  "data": {},
  "revision": "sha256-of-config"
}

Error Envelope

{
  "ok": false,
  "error": {
    "code": "machine_code",
    "message": "human-readable text"
  },
  "request_id": 1
}

Revision / Concurrency Contract

  • Mutating operations MAY include If-Match: <revision>.
  • If provided and stale, API returns 409 revision_conflict.
  • Revision is a SHA-256 hash of current config file content.

Endpoints

Read endpoints

  • GET /v1/health
  • GET /v1/stats/summary
  • GET /v1/stats/users
  • GET /v1/users
  • GET /v1/users/{username}

Mutating endpoints

  • POST /v1/users
  • PATCH /v1/users/{username}
  • POST /v1/users/{username}/rotate-secret
  • DELETE /v1/users/{username}

Entity Contract: User

Managed user fields:

  • username
  • secret (32 hex chars)
  • user_ad_tag (32 hex chars, optional)
  • max_tcp_conns (optional)
  • expiration_rfc3339 (optional)
  • data_quota_bytes (optional)
  • max_unique_ips (optional)

Derived runtime fields (read-only in API responses):

  • current_connections
  • active_unique_ips
  • total_octets

Validation Rules

  • username must match [A-Za-z0-9_.-], length 1..64.
  • secret must be exactly 32 hexadecimal characters.
  • user_ad_tag must be exactly 32 hexadecimal characters.
  • Request body size must not exceed request_body_limit_bytes.

Security Model

  1. Network perimeter. Access is limited by CIDR whitelist.

  2. Optional application header auth. If auth_header is configured, Authorization must match exactly.

  3. Read-only mode. If read_only = true, mutating endpoints are rejected with 403.

Mutation Approach

  1. Acquire mutation lock.
  2. Load config from disk.
  3. Validate optional If-Match revision.
  4. Apply in-memory mutation.
  5. Run config validation.
  6. Persist via atomic write (tmp + fsync + rename).
  7. Return updated revision.

Runtime apply path:

  • Existing config watcher picks up persisted changes and applies them through the standard hot-reload path.

Known Limitations

  1. Built-in TLS/mTLS is not provided by this API server. Use loopback bind plus reverse proxy for external exposure.

  2. No pagination/filtering for user list in current version.

  3. PATCH updates present fields only. Field deletion semantics are not implemented as explicit nullable operations.

  4. Config comments and manual formatting are not preserved after mutation. Config is serialized from structured state.

  5. API configuration itself (server.api) is not hot-applied. Restart is required.

  6. Atomic file replacement can conflict with external editors/tools writing the same config concurrently. Use revision checks to reduce race impact.