Chapter 2

Checksum & Authentication

Every BigBlueButton API call must include a checksum calculated from the server's shared secret. This mechanism prevents unauthorized access and protects API requests from tampering.

How It Works

The BBB API uses a shared-secret model: both the server and the calling application know the same secret. The secret is never transmitted directly — instead, it is used as input for a cryptographic hash that is appended to every request as the checksum parameter.

The shared secret must never be exposed to end users. It belongs exclusively in the server-side configuration of the integrating application. Never embed it in JavaScript, mobile apps, or any other client-side code.

Retrieving the Shared Secret

The secret is stored on the BigBlueButton server in /etc/bigbluebutton/bbb-web.properties as the securitySalt property. You can retrieve it by running the following command on the server:

# On the BBB server:
sudo bbb-conf --secret

Example output:

URL: https://api-guide.bbbserver.com/bigbluebutton/
Secret: replace-with-secret

Calculating the Checksum (Step by Step)

The following example demonstrates how to calculate the checksum for a create API call using SHA-256.

— assemble all parameters except checksum:

name=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password

Prepend the API method name (without any separator):

createname=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password

Append the shared secret (without any separator):

createname=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-passwordreplace-with-secret

Compute the hash using the chosen algorithm (SHA-256 in this example):

SHA-1:   7030bd96ede6a7ac41da848fe3bfc562e52a5914
SHA-256: 7e5a0a48f1542462e56ca034dc83d741bff1deb5feab0cd9ef74fa6e009fe1fd

Append the checksum to the query string as the checksum parameter:

name=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password&checksum=7e5a0a48f1542462e56ca034dc83d741bff1deb5feab0cd9ef74fa6e009fe1fd

Supported Hash Algorithms

BigBlueButton supports several hash algorithms for checksum calculation. The following table lists all available options:

Algorithm Available Since Hash Length
SHA-1 All versions 40 characters
SHA-256 BBB 2.4 64 characters
SHA-384 BBB 2.5 96 characters
SHA-512 BBB 2.5 128 characters

The supported algorithms are configured server-side in /etc/bigbluebutton/bbb-web.properties:

supportedChecksumAlgorithms=sha256,sha384,sha512

Removing an algorithm from this list disables it on the server. By default, all four algorithms are enabled.

SHA-1 is considered deprecated. Use SHA-256 or higher for new implementations. Keep SHA-1 enabled only if you need backward compatibility with older integrations.

POST Requests

When making POST requests to the BigBlueButton API, keep the following rules in mind:

  • The checksum is calculated exclusively from the URL query string.
  • The POST body (e.g., presentation XML or clientSettingsOverride) is not included in the checksum calculation.
  • All parameters that should be part of the checksum must be placed in the query string.

Breakout Room Configuration

If you disable SHA-256 support, you must also update the checkSumAlgorithmForBreakouts setting in /etc/bigbluebutton/bbb-apps-akka.conf to ensure that breakout rooms continue to function correctly.

Security Best Practices

  • Store the shared secret only on the server side — never in JavaScript, mobile apps, or other client-side contexts.
  • Always use HTTPS to protect the checksum and parameters during transmission.
  • If you suspect the secret has been compromised, rotate it immediately using bbb-conf --setsecret <new-secret>.
  • The checksum mechanism protects against tampering but not against replay attacks. For join URLs, consider using the createTime parameter to limit validity.

When generating join links for users, include the createTime parameter from the original create response. This ensures the join link is only valid for that specific meeting instance.

Code Examples

The following examples demonstrate checksum calculation using SHA-256 to create a meeting.

Python 3

import hashlib
import urllib.parse
import requests

BBB_URL = "https://api-guide.bbbserver.com/bigbluebutton/api"
BBB_SECRET = "replace-with-secret"

def bbb_checksum(call_name: str, query_string: str) -> str:
    """Calculate the BBB API checksum (SHA-256)."""
    raw = call_name + query_string + BBB_SECRET
    return hashlib.sha256(raw.encode("utf-8")).hexdigest()

# Create a meeting
params = urllib.parse.urlencode({
    "name": "Demo",
    "meetingID": "replace-with-meeting-id",
    "attendeePW": "replace-with-password",
    "moderatorPW": "replace-with-password",
})
checksum = bbb_checksum("create", params)
response = requests.get(f"{BBB_URL}/create?{params}&checksum={checksum}")
print(response.text)

PHP

<?php
$bbbUrl    = "https://api-guide.bbbserver.com/bigbluebutton/api";
$bbbSecret = "replace-with-secret";

function bbbChecksum(string $callName, string $queryString, string $secret): string {
    return hash("sha256", $callName . $queryString . $secret);
}

// Create a meeting
$params = http_build_query([
    "name"        => "Demo",
    "meetingID"   => "replace-with-meeting-id",
    "attendeePW"  => "replace-with-password",
    "moderatorPW" => "replace-with-password",
]);
$checksum = bbbChecksum("create", $params, $bbbSecret);
$response = file_get_contents("{$bbbUrl}/create?{$params}&checksum={$checksum}");
echo $response;

JavaScript (Node.js)

const crypto = require("crypto");
const https = require("https");

const BBB_URL = "https://api-guide.bbbserver.com/bigbluebutton/api";
const BBB_SECRET = "replace-with-secret";

function bbbChecksum(callName, queryString) {
  return crypto
    .createHash("sha256")
    .update(callName + queryString + BBB_SECRET)
    .digest("hex");
}

// Create a meeting
const params = new URLSearchParams({
    name: "Demo",
    meetingID: "replace-with-meeting-id",
    attendeePW: "replace-with-password",
    moderatorPW: "replace-with-password",
}).toString();

const checksum = bbbChecksum("create", params);
https.get(`${BBB_URL}/create?${params}&checksum=${checksum}`, (res) => {
  let data = "";
  res.on("data", (chunk) => (data += chunk));
  res.on("end", () => console.log(data));
});

Java

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public class BbbApi {
    static final String BBB_URL = "https://api-guide.bbbserver.com/bigbluebutton/api";
    static final String BBB_SECRET = "replace-with-secret";

    static String bbbChecksum(String callName, String queryString) throws Exception {
        String raw = callName + queryString + BBB_SECRET;
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(raw.getBytes(StandardCharsets.UTF_8));
        StringBuilder hex = new StringBuilder();
        for (byte b : hash) hex.append(String.format("%02x", b));
        return hex.toString();
    }

    public static void main(String[] args) throws Exception {
        String params = "name=" + URLEncoder.encode("Demo", "UTF-8")
            + "&meetingID=replace-with-meeting-id"
            + "&attendeePW=replace-with-password"
            + "&moderatorPW=replace-with-password";
        String checksum = bbbChecksum("create", params);
        String url = BBB_URL + "/create?" + params + "&checksum=" + checksum;
        System.out.println(url);
    }
}

Ruby

require "digest"
require "uri"
require "net/http"

BBB_URL    = "https://api-guide.bbbserver.com/bigbluebutton/api"
BBB_SECRET = "replace-with-secret"

def bbb_checksum(call_name, query_string)
  Digest::SHA256.hexdigest(call_name + query_string + BBB_SECRET)
end

# Create a meeting
params = URI.encode_www_form(
    name: "Demo",
    meetingID: "replace-with-meeting-id",
    attendeePW: "replace-with-password",
    moderatorPW: "replace-with-password"
)
checksum = bbb_checksum("create", params)
uri = URI("#{BBB_URL}/create?#{params}&checksum=#{checksum}")
puts Net::HTTP.get(uri)

curl (Bash)

BBB_URL="https://api-guide.bbbserver.com/bigbluebutton/api"
BBB_SECRET="replace-with-secret"

CALL="create"
PARAMS="name=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password"
CHECKSUM=$(echo -n "${CALL}${PARAMS}${BBB_SECRET}" | sha256sum | awk '{print $1}')

curl -s "${BBB_URL}/${CALL}?${PARAMS}&checksum=${CHECKSUM}"

Full Example: Create and Join a Meeting (curl)

#!/bin/bash
BBB_URL="https://api-guide.bbbserver.com/bigbluebutton/api"
BBB_SECRET="replace-with-secret"

bbb_checksum() {
  echo -n "${1}${2}${BBB_SECRET}" | sha256sum | awk '{print $1}'
}

# 1. Create a meeting
CREATE_PARAMS="name=Demo&meetingID=replace-with-meeting-id&attendeePW=replace-with-password&moderatorPW=replace-with-password"
CREATE_CS=$(bbb_checksum "create" "$CREATE_PARAMS")
curl -s "${BBB_URL}/create?${CREATE_PARAMS}&checksum=${CREATE_CS}"

# 2. Generate moderator join URL
JOIN_PARAMS="meetingID=replace-with-meeting-id&fullName=Admin&role=MODERATOR&redirect=true"
JOIN_CS=$(bbb_checksum "join" "$JOIN_PARAMS")
echo ""
echo "Moderator URL: ${BBB_URL}/join?${JOIN_PARAMS}&checksum=${JOIN_CS}"

# 3. Generate viewer join URL
JOIN_PARAMS2="meetingID=replace-with-meeting-id&fullName=Guest&role=VIEWER&redirect=true"
JOIN_CS2=$(bbb_checksum "join" "$JOIN_PARAMS2")
echo "Viewer URL: ${BBB_URL}/join?${JOIN_PARAMS2}&checksum=${JOIN_CS2}"

# 4. Check meeting status
INFO_CS=$(bbb_checksum "getMeetingInfo" "meetingID=replace-with-meeting-id")
curl -s "${BBB_URL}/getMeetingInfo?meetingID=replace-with-meeting-id&checksum=${INFO_CS}"

Frequently Asked Questions

The checksum is a cryptographic hash appended to every API request. It proves that the caller knows the shared secret without transmitting the secret itself. Without a valid checksum, the BigBlueButton server rejects the request.

Use SHA-256 or higher for all new implementations. SHA-1 is supported for backward compatibility but is considered deprecated. SHA-384 and SHA-512 are available starting with BigBlueButton 2.5.

No. The checksum is calculated exclusively from the URL query string. The POST body (such as presentation XML or client settings overrides) is not included in the checksum calculation.

Run the command bbb-conf --setsecret <new-secret> on your BigBlueButton server. After changing the secret, update all integrating applications immediately, as the old secret will no longer be accepted.

Yes. Edit the supportedChecksumAlgorithms property in /etc/bigbluebutton/bbb-web.properties and remove the algorithms you want to disable. If you disable SHA-256, also update the checkSumAlgorithmForBreakouts setting in bbb-apps-akka.conf.

Since the checksum includes the shared secret as part of the hash input, any modification to the query parameters will produce a different hash. The server recalculates the checksum on its end and rejects the request if the values do not match.

No. The checksum mechanism does not include a timestamp or nonce by default. To mitigate replay attacks on join URLs, include the createTime parameter from the original create response. This ties the join link to a specific meeting instance.