MoQ for the Curious

Chapter 08

Security and Access

On this page

A secure connection protects traffic between its endpoints. A private lecture also needs rules about who may discover, watch, or publish it, and whether the relay operator may read its content.

We’ll start with what the connection protects, then decide who can watch or publish the lecture. After that, we’ll look at hiding the content from the relay, protecting cached objects, and limiting how much work a client can request. We’ll finish by testing those permissions.

What does the connection protect?

QUIC uses TLS to establish packet-protection keys and authenticate the server. When a student’s browser verifies the relay’s certificate, it checks that it reached the expected relay under the applicable trust rules. That check does not identify the student to the relay. Client authentication is a separate choice, as explained in RFC 9001 §4.4.

The lecturer and student each have a connection to the relay. The relay terminates both, so it can read the application payload unless the application adds content encryption.

flowchart LR
    accTitle: Two protected connections through a relay
    accDescr: The lecturer connects securely to a relay, and the relay connects securely to the student. These are separate connections. The relay can read the media unless the application encrypts the content end to end.
    P[Lecturer] <-->|Protected connection A| R[Relay]
    R <-->|Protected connection B| S[Student]

For a service that trusts its relay operator with the lecture, this may be the intended arrangement. The transport protects traffic between endpoints, while the relay enforces access rules. If certificate verification fails, check the hostname, certificate, and client trust configuration. Disabling verification would let the client connect without authenticating the server.

Who may discover, subscribe, or publish?

Before the relay accepts a request, it needs to answer two questions: who is asking, and are they allowed to do this? Identifying the caller is authentication. Checking their permission is authorization. A student might be allowed to watch the lecture while only the lecturer can publish it.

First, write down the intended access policy. For example, this class might use:

Participant Discover the class Subscribe to media Publish media
Lecturer Yes Yes Yes
Enrolled student Yes Yes No
Visitor No No No

The lecture service sets these permissions. To check that they work, try each action with each kind of account.

Should someone outside the class even see its title in a room list? For a private lecture, the service may need to restrict discovery as well as playback.

The application can put permissions in a credential, such as a JSON Web Token (JWT) if the implementation supports it. Before trusting its claims, the relay must verify the token’s signature or other cryptographic protection with a trusted key and an allowed algorithm. It then checks who issued it, which service it’s for, whether it has expired, and which names and actions it allows. Reading a token’s fields is not the same as validating it. RFC 8725 covers JWT validation, including issuer and audience checks.

A stolen bearer credential can also be reused while it remains valid. Expiration limits when the credential can be accepted, but the service must also decide when to end subscriptions it previously authorized. Test revocation during playback as well as rejection of new requests. MOQT discusses this replay problem in draft-21 §15.3.2.

How can content stay private from the relay?

What if we don’t want the relay operator to be able to watch the lecture either? The lecturer can encrypt the media before sending it, and the students can decrypt it after receiving it. This is end-to-end content encryption.

flowchart LR
    accTitle: Content encryption across an intermediate relay
    accDescr: The lecturer encrypts media with content keys. The relay forwards the encrypted payload using visible routing metadata. An authorized student decrypts the media with the required content keys.
    P[Lecturer encrypts media] --> R[Relay forwards encrypted payload]
    R --> S[Student decrypts media]
    N[Names and delivery metadata remain visible] -.-> R

The service must distribute keys to authorized students, authenticate the content, decide when to change keys, and define how a newly enrolled student joins. These are part of the content-encryption design; establishing QUIC connections does not supply them automatically. MOQT leaves such mechanisms outside the transport specification. See draft-21 §15.4.

The relay can still see enough metadata to forward the content. That may include names, sizes, timing, and who subscribes to whom. So even with encrypted media, think about what those details reveal about a private class.

Who may publish under a cached name?

The relay may retain objects so that another student can join quickly. This works because an object identity refers to the same payload wherever it is served within the service’s scope. If an attacker could publish different bytes under the lecturer’s identity, those bytes might reach several students through the cache.

The relay needs to check that a publisher owns the names it wants to use, as required by draft-21 §15.3.3. A legitimate publisher also needs to avoid reusing old object addresses after a restart. As we saw in the content-model chapter, it can use a fresh namespace or continue with group IDs that won’t collide with the cache.

How much work may a client request?

Even an enrolled student can ask for more than the server can handle. A client might subscribe to every rendition, repeatedly ask for discovery results, or leave streams stalled. Set limits on connections, subscriptions, queued bytes, and cached content to keep that work manageable.

Consider a low-priority video stream waiting while more urgent audio keeps arriving. Its bytes still occupy memory. In MOQT draft-21, each endpoint, whether publisher or subscriber, must cancel a stream when it reaches a resource limit, preferably its lowest-priority stream. The actual memory budget remains an implementation decision. See §15.5.

For the lecture service, a limit on concurrent track subscriptions can prevent one viewer from requesting every rendition while displaying only one. Monitoring those limits helps distinguish a slow student connection from an application that is creating more work than intended.

How do we test the access policy?

A successful playback test checks only the enrolled student’s path. Test the other roles too: a viewer attempting to publish, a student from another class attempting to subscribe, and a client beginning a request with an expired credential. Confirm that each fails at the intended boundary. Keep credentials out of copied logs and shared URLs wherever the integration permits.

For experiments, the moq.dev public anonymous relay is explicitly public and discoverable. Use public test content there. A private lecture needs a relay with deliberate access configuration, followed by the rejection tests above. The project’s development guide describes the public relay, and its production guide covers deployment access configuration.

Sources and further reading