Gateway: a challenge store (issued per endpoint or session, consumed, kept for replay detection), joule_moq::grant_proof::check_proof on every request that carries a grant (POST, and PATCH, DELETE, GET and HEAD on session URLs, GET and HEAD on endpoints when a grant is carried), a fresh WAI-Room-Challenge on every response to such a request, the two fields in CORS, admission's single-use check only on a request that opens a session. Receipts tracks renamed *_receipts. Tests: an Auth helper that proves possession; whip_publish, whep_play and codecs moved onto it. auth_and_ice.rs is still the pre-proof version and does not build against the new helpers; room_corpus does not yet run the corpus's proofs. Not built, not tested, not pushed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
60 lines
2.5 KiB
TOML
60 lines
2.5 KiB
TOML
# joule-moq-ingest: every field, with its default where it has one.
|
|
# No secret lives here: the relay token and the signing key are files the operator
|
|
# provides, and a room is its signed descriptor, which is public.
|
|
|
|
[http]
|
|
listen = "127.0.0.1:8088" # the WHIP and WHEP resources; put a TLS front before them
|
|
origin = "" # this gateway's origin as grants name it, e.g. "https://ingest.example"
|
|
cors_allow_origin = "*"
|
|
max_body_bytes = 65536
|
|
request_timeout_ms = 10000
|
|
challenge_ttl_s = 300 # how long a proof-of-possession challenge stays good
|
|
max_challenges = 65536 # challenges held at once, issued and consumed each
|
|
|
|
[media]
|
|
bind_ip = "127.0.0.1" # each session's UDP socket, and its host candidate
|
|
ice_lite = true
|
|
connect_timeout_ms = 15000
|
|
idle_timeout_ms = 20000
|
|
|
|
[relay]
|
|
addr = "127.0.0.1:4443" # the relay's native QUIC endpoint (ALPN moqt-22)
|
|
server_name = "localhost"
|
|
cert_path = "relay-cert.pem" # the relay's certificate, trusted as a root
|
|
token_path = "relay-token" # the token value the relay's grant names by SHA-256
|
|
|
|
[signing]
|
|
key_path = "gateway.key" # 32 bytes, the Ed25519 seed; absent: made at start
|
|
signer_id = "" # empty: the key's did:key
|
|
origin_label = "wai-ingest"
|
|
|
|
[[rooms]]
|
|
descriptor_path = "room.wrd1" # the room's signed descriptor (WRD1)
|
|
revoked = [] # grant digests and viewer tags the room's key log revokes
|
|
|
|
[limits]
|
|
max_whip_sessions = 64 # one more: 503 with Retry-After
|
|
max_whep_sessions = 256
|
|
max_tracks_per_session = 2 # media sections in one offer; more: 422
|
|
max_bitrate_kbps = 8000 # per WHIP session, all tracks; stated per track as b=AS
|
|
bitrate_window_ms = 2000
|
|
max_frame_bytes = 4194304
|
|
max_queue_bytes = 33554432 # a session's queue to the relay
|
|
retry_after_s = 5
|
|
|
|
[groups]
|
|
audio_group_ms = 200 # an audio group's duration
|
|
max_video_group_ms = 2000 # a longer video group asks the publisher for a keyframe
|
|
keyframe_request_interval_ms = 1000
|
|
|
|
[timeline]
|
|
max_skew_ms = 250 # |mapped time - arrival| bound; past it, re-anchor
|
|
|
|
[whep]
|
|
trust = [] # first-hop keys whose receipts WHEP accepts; empty: this gateway's
|
|
hold_ms = 5000 # how long a group's objects wait for its receipts
|
|
catalog_wait_ms = 2000
|
|
retry_after_s = 2 # what a 409 asks a player to wait
|
|
|
|
[summary]
|
|
# out_path = "sessions.jsonl" # session records, one JSON line each; absent: kept in memory only
|