Skip to content

Adding signed_tokens to audiobridge#3635

Merged
lminiero merged 3 commits into
meetecho:masterfrom
mirkobrankovic82:hmac-token-audiobridge
Apr 24, 2026
Merged

Adding signed_tokens to audiobridge#3635
lminiero merged 3 commits into
meetecho:masterfrom
mirkobrankovic82:hmac-token-audiobridge

Conversation

@mirkobrankovic82
Copy link
Copy Markdown
Contributor

Summary

Adds optional HMAC signed (time-limited) token enforcement for the AudioBridge plugin, aligned with the existing VideoRoom behavior when Janus core signed-token mode is enabled (token_auth + token_auth_secret in janus.jcfg).

Changes

  • New per-room flag signed_tokens: set via dynamic create and/or static janus.plugin.audiobridge.jcfg; written to config when saving permanent rooms (create/edit paths that persist the room).
  • For join and changeroom, when core signed mode is on and the room has signed_tokens, validates the message token via auth_signature_contains with descriptor room=<room_id>, before PIN and the opaque allowed list check.
  • In-source (Doxygen) docs updated for signed_tokens in the .jcfg example and the create JSON example.

Usage

  1. Enable signed tokens in Janus core (token_auth + token_auth_secret).
  2. Create or configure a room with signed_tokens: true (or signed_tokens = true in the room’s .jcfg section).
  3. On join / changeroom, pass a token whose signed payload includes janus.plugin.audiobridge and room=<id> (same signing rules as VideoRoom room tokens; see Janus auth docs).

Notes

  • If the core is not in signed-token mode, enabling signed_tokens on a room logs a warning and does not turn on enforcement (same idea as VideoRoom).
  • PIN and the existing allowed opaque token list remain unchanged; signed tokens are an extra option for server-minted, expiring join credentials.

@januscla
Copy link
Copy Markdown

Thanks for your contribution, @mirkobrankovic82! Please make sure you sign our CLA, as it's a required step before we can merge this.

@lminiero
Copy link
Copy Markdown
Member

Thanks! From a cursory glance it looks ok, I'll need to test this. As a side note, you may want to update the main documentation too, as we currently have text that says:

NOTE WELL: At the time of writing, HMAC-Signed tokens are ONLY available for the VideoRoom plugin

@mirkobrankovic82
Copy link
Copy Markdown
Contributor Author

Thanks! From a cursory glance it looks ok, I'll need to test this. As a side note, you may want to update the main documentation too, as we currently have text that says:

NOTE WELL: At the time of writing, HMAC-Signed tokens are ONLY available for the VideoRoom plugin

Thanks Lorenzo,

Pushed commit with Docs update

@mirkobrankovic82
Copy link
Copy Markdown
Contributor Author

mirkobrankovic82 commented Apr 17, 2026

@lminiero I tested it with missing HMAC token

2026-04-17 11:22:47.842787 94.03% [INFO] http.c:84 HTTP POST url=http://janus.dev.svc.cluster.local/janus json={"janus":"create","transaction":"0c7y0rQyIN6Kayj"}
2026-04-17 11:22:47.862773 94.03% [INFO] http.c:95 result={
   "janus": "error",
   "transaction": "0c7y0rQyIN6Kayj",
   "error": {
      "code": 403,
      "reason": "Unauthorized request (wrong or missing secret/token)"
   }
}

with token:

2026-04-17 11:25:08.642747 93.57% [INFO] http.c:84 HTTP POST url=http://janus.dev.svc.cluster.local/janus json={"janus":"create","transaction":"VXv207Aae9kVpWa","token":"1776425408,janus,janus.plugin.audiobridge:jr1YD4c31+accNfuwfwj0taCW/o="}
2026-04-17 11:25:08.682738 93.57% [INFO] http.c:95 result={
   "janus": "success",
   "transaction": "VXv207Aae9kVpWa",
   "data": {
      "id": 6173283002268729
   }
}

Now i'm not only sure how to test expired token usage, maybe if i set timestamp in the past?
but I tested with mod_janus for Freeswitch so would have to modify C code to make a bad timestamp :/

Also I don't understand how long should these token live, or how long the timestamp should be, cause for example mod_janus uses one session for all requests, so should I use long lasting token then ? and browsers can use how much i expect session to last max?

@lminiero
Copy link
Copy Markdown
Member

but I tested with mod_janus for Freeswitch so would have to modify C code to make a bad timestamp :/

The documentation has a Node.js snippet you can use to generate tokens. I guess you can simply modify the date they use to generate the token to generate an older one, or use a very short timeout to see it working first and then fail.

Also I don't understand how long should these token live, or how long the timestamp should be

I don't think there's a rule: it's probably up to you and application specific.

json_t *token = json_object_get(root, "token");
const char *token_text = token ? json_string_value(token) : NULL;
if(token_text == NULL || g_hash_table_lookup(audiobridge->allowed, token_text) == NULL) {
JANUS_LOG(LOG_ERR, "Unauthorized (not in the allowed list)\n");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mirkobrankovic82 one thing I noticed is that the check of token for the ACL is still there even when using signed tokens. This means that, if someone enables both signed tokens and ACL, the same token will be checked twice, and probably fail in one of the two since they're incompatible. I don't think it's an issue specific to your patch, since from what I can see it's in the VideoRoom too. Just mentioning so that we can keep track of it in the future, e.g., in a follow-up PR that should maybe check if both signed tokens and ACL are enabled when creating a room, and in case fail with an error so that we only accept one.

@lminiero
Copy link
Copy Markdown
Member

The documentation has a Node.js snippet you can use to generate tokens. I guess you can simply modify the date they use to generate the token to generate an older one, or use a very short timeout to see it working first and then fail.

@mirkobrankovic82 FYI I made a few tests doing exactly that, trying to see how I could get AudioBridge tokens to fail, and it seems to be working as expected. I created a longer token for connecting to the handle (core), and a much shorter (60s) one for joining the AudioBridge: initially I could connect, and about a minute later I couldnt. So as far as I'm concerned, this seems to be working fine, thanks!

Was there anything else you wanted to add or edit, or is this complete and good to merge for you?

@lminiero
Copy link
Copy Markdown
Member

I'll merge in the meanwhile, since it seems to be working fine for me. In case you think there's something to revisit, we can address that in other commits.

@lminiero lminiero merged commit 7e05af3 into meetecho:master Apr 24, 2026
8 checks passed
@mirkobrankovic82 mirkobrankovic82 deleted the hmac-token-audiobridge branch May 4, 2026 09:25
@mirkobrankovic82
Copy link
Copy Markdown
Contributor Author

hey @lminiero,
Sorry for not responding, I was on vacation. Thanks for merging it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants