Skip to content

Commit 99c330f

Browse files
authored
Merge branch 'main' into feat/restyling-publish-ui
2 parents 4f30712 + afe5867 commit 99c330f

File tree

11 files changed

+914
-122
lines changed

11 files changed

+914
-122
lines changed

.github/workflows/libmoq.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ jobs:
2525
os: macos-15-intel
2626
- target: aarch64-apple-darwin
2727
os: macos-latest
28+
- target: universal-apple-darwin
29+
os: macos-latest
2830
- target: x86_64-pc-windows-msvc
2931
os: windows-latest
3032

@@ -34,7 +36,7 @@ jobs:
3436
- name: Install Rust
3537
uses: dtolnay/rust-toolchain@stable
3638
with:
37-
targets: ${{ matrix.target }}
39+
targets: ${{ matrix.target == 'universal-apple-darwin' && 'x86_64-apple-darwin,aarch64-apple-darwin' || matrix.target }}
3840

3941
- name: Install cross-compilation tools (Linux ARM64)
4042
if: matrix.target == 'aarch64-unknown-linux-gnu'

Cargo.lock

Lines changed: 66 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/guide/authentication.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
title: moq-authentication
3+
description: Authentication for the moq-relay
4+
---
5+
6+
# MoQ authentication
7+
8+
The MoQ Relay authenticates via JWT-based tokens. Generally there are two different approaches you can choose from:
9+
- asymmetric keys: using a public and private key to separate signing and verifying keys for more security
10+
- symmetric key: using a single secret key for signing and verifying, less secure
11+
12+
## Symmetric key
13+
14+
1. Generate a secret key:
15+
```bash
16+
moq-token --key root.jwk generate --algorithm HS256
17+
```
18+
:::details You can also choose a different algorithm
19+
- HS256
20+
- HS384
21+
- HS512
22+
:::
23+
24+
2. Configure relay:
25+
:::code-group
26+
```toml [relay.toml]
27+
[auth]
28+
# public = "anon" # Optional: allow anonymous access to anon/**
29+
key = "root.jwk" # JWT key for authenticated paths
30+
```
31+
:::
32+
33+
3. Generate tokens:
34+
```bash
35+
moq-token --key root.jwk sign \
36+
--root "rooms/123" \
37+
--publish "alice" \
38+
--subscribe "" \
39+
--expires 1735689600 > alice.jwt
40+
```
41+
42+
## Asymmetric keys
43+
44+
Generally asymmetric keys can be more secure because you don't need to distribute the signing key to every relay instance, the relays only need to verifying (public) key.
45+
46+
1. Generate a public and private key:
47+
```bash
48+
moq-token --key private.jwk generate --public public.jwk --algorithm RS256
49+
```
50+
:::details You can also choose a different algorithm
51+
- RS256
52+
- RS384
53+
- RS512
54+
- PS256
55+
- PS384
56+
- PS512
57+
- EC256
58+
- EC384
59+
- EdDSA
60+
:::
61+
62+
2. Now the relay only requires the public key:
63+
:::code-group
64+
```toml [relay.toml]
65+
[auth]
66+
# public = "anon" # Optional: allow anonymous access to anon/**
67+
key = "public.jwk" # JWT key for authenticated paths
68+
```
69+
:::
70+
71+
3. Generate tokens using the private key:
72+
```bash
73+
moq-token --key private.jwk sign \
74+
--root "rooms/123" \
75+
--publish "alice" \
76+
--subscribe "" \
77+
--expires 1735689600 > alice.jwt
78+
```
79+
80+
## JWK set authentication
81+
82+
Instead of storing a public key locally in a file, it may also be retrieved from a server hosting a JWK set. This can be a simple static site serving a JSON file, or a fully OIDC compliant Identity Provider. That way you can easily implement automatic key rotation.
83+
84+
::: info
85+
This approach only works with asymmetric authentication.
86+
:::
87+
88+
To set this up, you need to have an HTTPS server hosting a JWK set that looks like this:
89+
```json
90+
{
91+
"keys": [
92+
{
93+
"kid": "2026-01-01",
94+
"alg": "RS256",
95+
"key_ops": [
96+
"verify"
97+
],
98+
"kty": "RSA",
99+
"n": "zMsjX1oDV2SMQKZFTx4_qCaD3iIek9s1lvVaymr8bEGzO4pe6syCwBwLmFwaixRv7MMsuZ0nIpoR3Slpo-ZVyRxOc8yc3DcBZx49S_UQcM76E4MYbH6oInrEP8QL2bsstHrYTqTyPPjGwQJVp_sZdkjKlF5N-v5ohpn36sI8PXELvfRY3O3bad-RmSZ8ZOG8CYnJvMj_g2lYtGMMThnddnJ49560ahUNqAbH6ru---sHtdYHcjTIaWX4HYP6Y_KjA6siDZTGTThpaEW45LKcDQWM9sYvx_eAstaC-1rz8Z_6fDgKFWr7qcP5U2NmJ0c-IGSu_8OkftgRH4--Z5mzBQ",
100+
"e": "AQAB"
101+
},
102+
{
103+
"kid": "2025-12-01",
104+
"alg": "EdDSA",
105+
"key_ops": [
106+
"verify"
107+
],
108+
"kty": "OKP",
109+
"crv": "Ed25519",
110+
"x": "2FSK2q_o_d5ernBmNQLNMFxiA4-ypBSa4LsN30ZjUeU"
111+
}
112+
]
113+
}
114+
```
115+
116+
:::tip The following must be considered:
117+
- Every JWK MUST be public and contain no private key information
118+
- If your JWK set contains more than one key:
119+
1. Every JWK MUST have a `kid` so they can be identified on verification
120+
2. Your JWT tokens MUST contain a `kid` in their header
121+
3. `kid` can be an arbitrary string
122+
:::
123+
124+
Configure the relay:
125+
:::code-group
126+
```toml [relay.toml]
127+
[auth]
128+
# public = "anon" # Optional: allow anonymous access to anon/**
129+
130+
key = "https://auth.example.com/keys.json" # JWK set URL for authenticated paths
131+
refresh_interval = 86400 # Optional: refresh the JWK set every N seconds, no refreshing if omitted
132+
```
133+
:::

flake.nix

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
"rust-src"
4141
"rust-analyzer"
4242
];
43+
targets = pkgs.lib.optionals pkgs.stdenv.isDarwin [
44+
"x86_64-apple-darwin"
45+
"aarch64-apple-darwin"
46+
];
4347
};
4448

4549
# Rust dependencies

0 commit comments

Comments
 (0)