moq-token
JWT authentication library and CLI tool for MoQ relay authentication.
Overview
moq-token provides:
- Library - Generate and verify JWT tokens in Rust
- CLI - Command-line tool for key and token management
- Multiple algorithms - HMAC, RSA, ECDSA, EdDSA
Installation
Library
Add to your Cargo.toml:
[dependencies]
moq-token = "0.1"CLI
cargo install moq-token-cliThe binary is named moq-token. moq-cli ships the same commands as moq token ..., so a machine that already has moq needs nothing extra.
Using Nix
# Run directly
nix run github:moq-dev/moq#moq-token
# Or build and find the binary in ./result/bin/
nix build github:moq-dev/moq#moq-tokenUsing Docker
docker pull moqdev/moq-token-cli
docker run -v "$(pwd):/app" -w /app moqdev/moq-token-cli:latest generate --out root.jwkMulti-arch images (linux/amd64 and linux/arm64) are published to Docker Hub.
CLI Usage
Generate a Key
# Symmetric key (HMAC)
moq-token generate --out root.jwk --algorithm HS256
# Asymmetric key pair (RSA)
moq-token generate --algorithm RS256 --out private.jwk --public public.jwk
# Asymmetric key pair (EdDSA)
moq-token generate --algorithm EdDSA --out private.jwk --public public.jwk
# Scoped key: may only ever sign tokens that publish below project/live
# and subscribe below project/watch
moq-token generate --root project --publish live --subscribe watch --out scoped.jwkA key's scope is fixed at generation and enforced when signing and when verifying, so widening it means generating a new key. A key without a scope is unrestricted.
Sign a Token
moq-token sign --key root.jwk \
--root "rooms/123" \
--publish "alice" \
--subscribe "" \
--expires 1735689600 > alice.jwtVerify a Token
moq-token verify --key root.jwk < alice.jwtSupported Algorithms
Symmetric (HMAC):
- HS256
- HS384
- HS512
Asymmetric (RSA):
- RS256, RS384, RS512
- PS256, PS384, PS512
Asymmetric (Elliptic Curve):
- EC256, EC384
- EdDSA
Library Usage
rs/moq-token/examples/basic.rs- Generate a symmetric key, sign a token, verify it, and round-trip the keyrs/moq-token/examples/asymmetric.rs- Generate an ECDSA key pair, extract the public key for the relay, sign and verify
For the TypeScript equivalent, see js/token/examples/sign-and-verify.ts.
Token Claims
| Claim | Type | Description |
|---|---|---|
root | string? | Root path for all operations, defaulting to the top-level path |
put | string | string[]? | Publishing permission paths, relative to root |
get | string | string[]? | Subscription permission paths, relative to root |
exp | number? | Expiration (Unix timestamp) |
iat | number? | Issued at (Unix timestamp) |
A token is checked in two steps. Key::verify checks the signature and expiry, then Claims::authorize scopes the claims to the path a client dialed, returning the publish/subscribe prefixes relative to it. The relay does both; authorize is available on its own so an auth service can apply the same rules. The TypeScript @moq/token package mirrors this API.
Integration with moq-relay
Configure the relay to use your key:
[auth]
key = "root.jwk"
public = "anon" # Optional: anonymous accessSee Relay Authentication for details.
Security Considerations
- Symmetric keys should only be used when the same entity signs and verifies
- Asymmetric keys are preferred for distributed systems (relay only needs public key)
- Token expiration should be set appropriately for your use case
- Secure transmission - Only transmit tokens over HTTPS
- Secure storage - Keep private keys secure
JWK Set Support
For key rotation, use the relay's key_dir option pointing to a directory or URL. The relay resolves keys on demand by extracting the kid (key ID) from the JWT header and fetching the corresponding {kid}.jwk file. See Relay Authentication for configuration details.
API Reference
Full API documentation: docs.rs/moq-token
Next Steps
- Configure Relay Authentication
- Deploy a Relay Server
- Learn about Authentication