mirror of https://github.com/telemt/telemt.git
API Docs V1
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
parent
f7d451e689
commit
1236505502
|
|
@ -0,0 +1,149 @@
|
|||
# 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
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"data": {},
|
||||
"revision": "sha256-of-config"
|
||||
}
|
||||
```
|
||||
|
||||
### Error Envelope
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
Loading…
Reference in New Issue