> ## Documentation Index
> Fetch the complete documentation index at: https://red5.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Red5 Backend SDK: Secure Token Generation (Node, Java, Go)

> Generate secure conference and chat access tokens on your server with the Red5 Backend SDK for Node.js, Java, or Go. Keeps master credentials off the client.

The Red5 Backend SDKs let your server generate secure access tokens for video conferences and chat messaging. Available for Node.js, Java, and Go, they give you a simple API to create short-lived tokens that clients pass to the iOS SDK, Android SDK, or Conference SDK when joining a room or channel. Your master credentials stay on your server and are never exposed to end users.

## Why you need it

When a user wants to join a video conference or send a chat message, the client SDK needs to authenticate against Red5 Cloud. If you hardcode master credentials in your app, anyone who decompiles or inspects your client can extract them. Instead, your backend uses the Backend SDK to mint a signed token scoped to a specific user, room, and role — the token carries only the minimum permissions needed, and it expires after a configurable time window.

<Note>
  Your master key and secret are available on the **Dev Resources** page in the [Red5 Cloud dashboard](https://cloud.red5.net). Store them as environment variables on your server and never commit them to source control.
</Note>

## Token types

**Conference token** — authorizes a user to join a specific video room with a given role (`admin`, `publisher`, or `subscriber`). Pass this token to `client.join()` in the Conference SDK, or to the `setToken()` method in the iOS or Android SDK.

**Chat token** — authorizes a user to read and/or write on a specific PubNub channel. Pass this token to `setChatToken()` on the iOS or Android SDK client.

## Installation

<Tabs>
  <Tab title="Node.js">
    ```bash theme={null}
    npm install red5-bcs-node
    ```

    <Note>
      The `red5-bcs-node` package is not yet published to the npm registry. Contact Red5 support to obtain the package.
    </Note>
  </Tab>

  <Tab title="Java">
    **Maven:**

    ```xml theme={null}
    <dependency>
        <groupId>net.red5</groupId>
        <artifactId>red5-bcs-java</artifactId>
        <version>1.0.0</version>
    </dependency>
    ```

    **Gradle:**

    ```gradle theme={null}
    implementation 'net.red5:red5-bcs-java:1.0.0'
    ```

    <Note>
      The `red5-bcs-java` package is not yet published to Maven Central. Contact Red5 support to obtain the package.
    </Note>
  </Tab>

  <Tab title="Go">
    ```bash theme={null}
    go get github.com/red5pro/red5-bcs-go
    ```

    <Note>
      The `red5-bcs-go` module is not yet published to pkg.go.dev. Contact Red5 support to obtain the module.
    </Note>
  </Tab>
</Tabs>

## Conference token generation

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    import Red5Client from 'red5-bcs-node';

    const client = new Red5Client(
      process.env.RED5_MASTER_KEY,
      process.env.RED5_MASTER_SECRET
    );

    const token = await client.getConferenceToken(
      'user-123',    // userId
      'room-abc',    // roomId
      'publisher',   // role: 'admin' | 'publisher' | 'subscriber'
      60             // expirationMinutes
    );

    console.log(token); // pass this to the client SDK
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    import net.red5.sdk.Red5Client;

    Red5Client client = new Red5Client(
        System.getenv("RED5_MASTER_KEY"),
        System.getenv("RED5_MASTER_SECRET")
    );

    String token = client.getConferenceToken(
        "user-123",    // userId
        "room-abc",    // roomId
        "publisher",   // role: "admin" | "publisher" | "subscriber"
        60             // expirationMinutes
    );

    System.out.println(token);
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    package main

    import (
        "fmt"
        "log"
        "os"
        "github.com/red5pro/red5-bcs-go"
    )

    func main() {
        client, err := red5bcs.NewRed5Client(
            os.Getenv("RED5_MASTER_KEY"),
            os.Getenv("RED5_MASTER_SECRET"),
        )
        if err != nil {
            log.Fatal(err)
        }

        token, err := client.GetConferenceToken(
            "user-123",  // userId
            "room-abc",  // roomId
            "publisher", // role: "admin" | "publisher" | "subscriber"
            60,          // expirationMinutes
        )
        if err != nil {
            log.Fatal(err)
        }

        fmt.Println(token)
    }
    ```
  </Tab>
</Tabs>

## Chat token generation

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const chatToken = await client.getChatToken(
      'user-123',        // userId
      'channel-global',  // channelId
      true,              // read permission
      true,              // write permission
      30                 // ttlMinutes
    );

    console.log(chatToken);
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    String chatToken = client.getChatToken(
        "user-123",       // userId
        "channel-global", // channelId
        true,             // read permission
        true,             // write permission
        30                // ttlMinutes
    );

    System.out.println(chatToken);
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    chatToken, err := client.GetChatToken(
        "user-123",       // userId
        "channel-global", // channelId
        true,             // read permission
        true,             // write permission
        30,               // ttlMinutes
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(chatToken)
    ```
  </Tab>
</Tabs>

## Roles

| Role         | Permissions                                |
| ------------ | ------------------------------------------ |
| `admin`      | Full room access and conference management |
| `publisher`  | Publish audio and video streams            |
| `subscriber` | View and listen only                       |

## Full example

The following shows a complete server handler that issues both a conference token and a chat token for a single user request.

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    import Red5Client from 'red5-bcs-node';

    async function issueTokens(userId, roomId, channelId) {
        const client = new Red5Client(
            process.env.RED5_MASTER_KEY,
            process.env.RED5_MASTER_SECRET
        );

        const conferenceToken = await client.getConferenceToken(
            userId, roomId, 'publisher', 60
        );

        const chatToken = await client.getChatToken(
            userId, channelId, true, true, 60
        );

        return { conferenceToken, chatToken };
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    import net.red5.sdk.Red5Client;

    public class TokenService {
        private final Red5Client client;

        public TokenService() {
            this.client = new Red5Client(
                System.getenv("RED5_MASTER_KEY"),
                System.getenv("RED5_MASTER_SECRET")
            );
        }

        public String getConferenceToken(String userId, String roomId) throws Exception {
            return client.getConferenceToken(userId, roomId, "publisher", 60);
        }

        public String getChatToken(String userId, String channelId) throws Exception {
            return client.getChatToken(userId, channelId, true, true, 60);
        }
    }
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    package main

    import (
        "fmt"
        "log"
        "os"
        "github.com/red5pro/red5-bcs-go"
    )

    func main() {
        client, err := red5bcs.NewRed5Client(
            os.Getenv("RED5_MASTER_KEY"),
            os.Getenv("RED5_MASTER_SECRET"),
        )
        if err != nil {
            log.Fatal(err)
        }

        confToken, err := client.GetConferenceToken("userA", "room1", "publisher", 120)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(confToken)

        chatToken, err := client.GetChatToken("userA", "channel1", true, true, 60)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(chatToken)
    }
    ```
  </Tab>
</Tabs>

## Using tokens with client SDKs

Once your backend issues a token, pass it to the appropriate client SDK method:

* **Conference SDK** — pass as the `token` argument to `client.join()`
* **iOS SDK** — pass to `.setToken()` or `.setAuthToken()` on `Red5WebrtcClientBuilder`
* **Android SDK** — pass to `.setToken()` on `IRed5WebrtcClient.builder()`
* **Chat (iOS)** — pass to `.setPubnubAuthKey()` on `Red5WebrtcClientBuilder`
* **Chat (Android)** — pass to `.setChatToken()` on `IRed5WebrtcClient.builder()`

## Security best practices

<Warning>
  Never generate tokens on the client or expose your master credentials in frontend code. Always call token generation from your backend over a server-to-server connection.
</Warning>

* Store master credentials as environment variables, not in source code
* Use HTTPS for all token delivery endpoints
* Keep token lifetimes short — 30 to 60 minutes is a reasonable default
* Validate the requesting user's identity on your backend before issuing a token
* Use the minimum role required (`subscriber` instead of `publisher` for view-only users)
