Backend interview: How would you design a secure WHIP WebRTC ingest endpoint?
Prompt and context
You need a WHIP (WebRTC-HTTP Ingestion Protocol) endpoint for an encoder or media producer. The client sends an application/sdp offer with HTTP POST; the server negotiates ICE and DTLS and returns an SDP answer. Explain the API, session lifecycle, authentication, resource protection, and observability. Assume one-way media ingest; recording and transcoding are out of scope.
What the interviewer evaluates
- Whether HTTP signaling resources and WebRTC media resources are modeled separately.
- Whether one POST leads to a concrete order for authentication, limits, timeouts, and cleanup.
- Whether the candidate understands the boundary between HTTPS, ICE, DTLS-SRTP, and browser APIs instead of treating WHIP as a media transport.
- Whether retries, duplicate creation, half-open sessions, and malicious SDP are covered.
Clarifying questions
- Is the publisher a controlled encoder or an open user? Can credentials be short-lived and single-stream?
- Is the endpoint regional or multi-region? Can session state move between regions?
- Is low latency the priority, or must recording completeness and replayability be guaranteed?
- Will trickle ICE or another WHIP extension be supported, and who owns its negotiation and authorization?
30-second answer
I would split the endpoint into an authentication gateway, a session control plane, and WebRTC media nodes. The gateway verifies a short-lived credential, request limits, and tenant quota before passing the SDP offer to the session service. The service allocates bounded resources, completes ICE/DTLS, and returns 201 Created, an SDP answer, and a session Location. Every incomplete negotiation must release resources; DELETE is idempotent, and limits apply per tenant and source. I would measure HTTP signaling, ICE/DTLS state, and first-media-packet latency separately instead of using POST success as the availability metric.
Step-by-step solution
- Set the protocol boundary. WHIP performs one HTTP offer/answer exchange; WebRTC carries the media afterward. W3C exposes browser controls, while the server still handles ICE, DTLS, and media reception.
- Do cheap checks first. Before allocating ICE or media nodes, check HTTPS, authentication, tenant status,
Content-Type: application/sdp, request size, channel authorization, and rate quota. Rejection must not trigger expensive SDP parsing or connection allocation. - Model a session resource. Use a random, non-enumerable session URL with
pending → connected → closing → closed. Creation returns201 Created,Location, and an SDP answer; errors should be diagnosable without exposing internal topology. - Bound half-open work. Set separate deadlines for SDP parsing, ICE/DTLS establishment, and the first media packet. RFC 9725 calls out POST flooding: a credentialed attacker can force allocation and wait for ICE/DTLS timeouts. Enforce edge rate limits, session concurrency quotas, and timeout reclamation.
- Handle retries and deletion. Network retries can send the same offer more than once. Bind credentials to a channel or idempotency key; if sameness cannot be proven, create a new session only under the concurrency limit. Make
DELETE /sessionidempotent and return the same terminal state on repeat calls. - Protect transport and credentials. RFC 9725 requires HTTPS to preserve the WebRTC security model. Keep credentials out of query strings and log only hashed session identifiers. Media nodes should accept short-lived authorization from the session service rather than a widely copied channel key.
- Negotiate extensions explicitly. If trickle ICE or server events are supported, advertise the capability through mechanisms such as
Link; clients must not assume every WHIP server supports it. On extension failure, fall back to the base exchange or terminate explicitly. - Test the real readiness boundary. Track tenant-level POST acceptance, SDP parse failures, ICE success, DTLS setup time, first-media latency, timeout reclamation, and DELETE latency. Inject duplicate POSTs, oversized SDP, unreachable ICE, node restarts, and credential revocation.
Model answer
I would first frame this as a control-plane endpoint: HTTP POST hands an SDP offer to the session service, while WebRTC carries media afterward. The gateway verifies HTTPS, a short-lived credential, channel permission, content type, size, and tenant concurrency before parsing SDP; every rejection happens before media resources are allocated. A successful request creates a non-enumerable session, returns 201 Created, Location, and the answer, and enters a timed pending state. If ICE or DTLS never completes, the service reclaims candidates and nodes so half-open sessions cannot exhaust capacity. DELETE is idempotent, and short-lived credentials plus an idempotency key bound retries. I would separate HTTP, ICE/DTLS, and first-media metrics, then load-test POST floods, hostile SDP, restarts, and credential revocation to prove both safety and recovery.
Common mistakes
- Treating WHIP as the media channel → ICE, DTLS, and node state disappear from the design → separate control and media planes.
- Allocating a full node on every POST → hostile requests accumulate half-open work → cheap checks and staged quotas first.
- Using only a global rate limit → one tenant or channel affects everyone → limit by tenant, credential, channel, and source.
- Logging raw SDP → addresses and topology may leak → record a digest, error class, and correlation ID.
- Making DELETE non-idempotent → retries create cleanup races and noisy 404s → define terminal states and repeatable responses.
- Returning HTTP 200 for every outcome → clients cannot distinguish creation, rejection, and retry → use semantic statuses and safe error bodies.
Follow-ups and responses
An attacker has a valid credential and keeps posting. How do you protect the service?
Bind the credential to a tenant, channel, and expiry; apply a token bucket and concurrency ceiling at the edge, then cap pending sessions and total wait time in the control plane. Revoke credentials that repeatedly cross the threshold and retain audit evidence.
ICE succeeds but DTLS never does. Do you retry or report success?
ICE success is not media readiness. Keep the session pending until DTLS and a first-media condition pass; on timeout, close it, return a retryable failure class, and release candidates and nodes.
The client sends the same SDP offer twice. How do you avoid duplicate ingest?
Require a short-lived idempotency key and bind it to the credential, channel, and offer digest. Return the original session for a proven duplicate. If equivalence cannot be proven, create a new session only within the concurrency quota.
Can a WHIP session move to another region during an outage?
An established ICE/DTLS session generally cannot be moved transparently. The new endpoint should issue a new session URL, the client should POST again, and the old session should be released by timeout or explicit DELETE. Replicated credential state must not broaden the exposure scope.