Skip to content

Stream Authentication

Monibuca v6 supports two stream auth modes:

  1. Built-in signature auth (v5-compatible)
  2. Custom auth handler (higher priority)

Auth is enforced at protocol entry points. Current coverage:

  • Publish: rtmp, webrtc(whip), webtransport, srt, rtsp(record/announce)
  • Subscribe: rtmp, webrtc(whep), flv/http-flv/ws-flv, hls, webtransport, srt, rtsp(describe/play)
global:
enableauth: true
publish:
key: "your-publish-key"
secretargname: secret
expireargname: expire
subscribe:
key: "your-subscribe-key"

Notes:

  • Set enableauth=true to enable stream auth checks
  • Publish uses publish.key
  • Subscribe uses subscribe.key
  • Parameter names are configurable via secretargname / expireargname (defaults: secret / expire)
secret = md5(key + streamPath + expireHex)

Where:

  • key: publish.key or subscribe.key
  • streamPath: stream path without query, e.g. live/test
  • expireHex: Unix timestamp in hex (seconds)

Validation rules:

  • expire must be a valid hex timestamp and not expired
  • secret length must be 32
  • secret must match server-side hash (case-insensitive)

For live/test:

rtmp://host/live/test?secret=...&expire=...
http://host:8180/flv/live/test.flv?secret=...&expire=...
http://host:8180/hls/live/test/index.m3u8?secret=...&expire=...
http://host:8180/webrtc/push/live/test?secret=...&expire=...
http://host:8180/webrtc/play/live/test?secret=...&expire=...
srt://host:6000?streamid=publish:/live/test?secret=...&expire=...

Use a custom handler when integrating with external IAM, ACL services, or one-time tickets.

Priority order:

  1. Custom handler (if registered)
  2. Built-in secret+expire auth

Once a custom handler returns a result, that result is final.

StreamManagerApi provides:

  • set_stream_auth_handler(handler)

Handler input:

  • StreamAuthRequest
    • plugin_name
    • stream_path
    • query_string
    • params (parsed query map)
    • is_publish

Handler output:

  • Ok(()): allow
  • Err(...): deny
manager.set_stream_auth_handler(Some(Arc::new(|req| {
if req.plugin_name == "rtmp" && req.is_publish {
let token = req.params.get("token").cloned().unwrap_or_default();
if token == "allow" {
return Ok(());
}
return Err(sdk::MonibucaError::InvalidInput("auth failed".into()));
}
Ok(())
})));

The Admin “Push URL” dialog can generate v5-style auth params automatically:

  • expire (hex timestamp)
  • secret (md5(key + streamPath + expire))

Then appends them to the generated URL query string.

The server exposes a signing helper endpoint:

GET /api/secret/{publish|subscribe}/{streamPath...}?expire=<hex>&plugin=<pluginName>

Parameters:

  • type: publish or subscribe
  • streamPath: stream path (URL-encoded supported)
  • expire: optional hex Unix timestamp; defaults to now + 30 minutes
  • plugin: optional plugin name (default global, using global inherited keys)

Example response:

{
"code": 0,
"message": "success",
"data": {
"type": "publish",
"plugin": "rtmp",
"streamPath": "live/test",
"expire": "6610f4a0",
"secret": "0123456789abcdef0123456789abcdef"
}
}