76 lines
2.4 KiB
Markdown
76 lines
2.4 KiB
Markdown
# TURN REST Credentials (Ephemeral) — Usage & Operations
|
||
|
||
This document explains the **TURN REST credential** strategy for `niom-turn` (MVP → production-capable path).
|
||
|
||
## Why TURN REST?
|
||
|
||
- You want to issue *short-lived* TURN logins for WebRTC (e.g. 5–10 minutes).
|
||
- Your TURN server does not store per-user passwords.
|
||
- Your backend can mint tokens later; until then you can generate tokens locally/ops-side.
|
||
|
||
## Scheme (compatible with common WebRTC stacks)
|
||
|
||
**Username**: `<expiry_unix_seconds>` or `<expiry_unix_seconds>:<opaque_user_id>`
|
||
|
||
- Example: `1735412345:alice`
|
||
- `expiry_unix_seconds` is a Unix timestamp in seconds.
|
||
|
||
**Credential (password)**:
|
||
|
||
$$\n\text{credential} = \text{base64}(\text{HMAC-SHA1}(\text{secret}, \text{username}))\n$$
|
||
|
||
This `credential` is then used as the TURN password in your ICE server configuration.
|
||
|
||
## Server side (`niom-turn`)
|
||
|
||
Configuration in [appsettings.example.json](../appsettings.example.json):
|
||
|
||
- `auth.rest_secret`: shared secret (must stay secret)
|
||
- `auth.rest_max_ttl_seconds`: maximum acceptable TTL window into the future. If a token is too far in the future, it is rejected (safety measure).
|
||
|
||
Important:
|
||
- The server accepts TURN REST credentials as a fallback **only if** the username is not found in the credential store.
|
||
- Expiry/TTL rules:
|
||
- `expiry` must be >= `now`
|
||
- and `expiry - now <= rest_max_ttl_seconds`
|
||
|
||
## Generate tokens locally (without a backend)
|
||
|
||
This repo includes a small CLI:
|
||
|
||
- Binary: [src/bin/turn_rest_cred.rs](../src/bin/turn_rest_cred.rs)
|
||
|
||
Examples:
|
||
|
||
1) Simple (stdout as env-like lines)
|
||
|
||
`cargo run --bin turn_rest_cred -- --secret "SUPER_SECRET" --user alice --ttl 600`
|
||
|
||
2) JSON output
|
||
|
||
`cargo run --bin turn_rest_cred -- --secret "SUPER_SECRET" --user alice --ttl 600 --json`
|
||
|
||
You get:
|
||
- `username` → use as `iceServers[].username` in WebRTC
|
||
- `credential` → use as `iceServers[].credential` in WebRTC
|
||
|
||
## WebRTC example (frontend)
|
||
|
||
In your app you typically set:
|
||
|
||
- URLs (at least UDP + TLS):
|
||
- `turn:your-domain:3478?transport=udp`
|
||
- `turn:your-domain:3478?transport=tcp`
|
||
- `turns:your-domain:5349?transport=tcp`
|
||
|
||
and then:
|
||
- `username`: from the generator/backend
|
||
- `credential`: from the generator/backend
|
||
|
||
## Operational notes
|
||
|
||
- **Secret rotation**: plan rotation (e.g. two secrets in parallel) or in-flight tokens will break.
|
||
- **Keep TTL small**: 5–10 minutes is typical.
|
||
- **Logs**: never log the `secret` or full credentials.
|
||
- **Rate limits/quotas**: add them to avoid open-relay abuse.
|