> ## 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.

# Delegate Stream Auth to Your Own Endpoint in Red5 Pro

> Let Red5 Pro call your HTTP endpoint before every publish or subscribe. Your service returns allow or deny — integrates with any existing auth system.

Round-Trip Authentication lets Red5 Pro delegate every publish and subscribe decision to an HTTP endpoint you control. When a client attempts to start a stream, Red5 Pro sends the client's credentials and stream details to your endpoint; your service applies whatever business logic you need and responds with an allow or deny. This approach integrates seamlessly with existing user management systems and supports any level of custom access control logic.

## How it works

<Steps>
  <Step title="Client connects and provides credentials">
    When a client connects to your Red5 Pro application, it supplies `username`, `password`, and an optional `token` as connection parameters. Red5 Pro verifies that the required parameters are present; missing parameters result in an immediate rejection.
  </Step>

  <Step title="Client requests to publish or subscribe">
    Authentication is not triggered on connection alone. It fires when the client attempts an actual stream action — publish or subscribe.
  </Step>

  <Step title="Red5 Pro calls your validation endpoint">
    The `RoundTripAuthValidator` POSTs the client's credentials, the stream name, the action type (`publisher` or `subscriber`), and the optional token to your configured `validateCredentials` endpoint.
  </Step>

  <Step title="Your endpoint returns allow or deny">
    Your service evaluates the request and responds. An HTTP `200` with a valid JSON body allows the action; any other response causes Red5 Pro to reject it.
  </Step>

  <Step title="Red5 Pro calls your invalidation endpoint on disconnect">
    When a publisher stops streaming, Red5 Pro notifies your `invalidateCredentials` endpoint so your service can clean up session state.
  </Step>
</Steps>

<Note>
  Round-Trip Authentication triggers only when a client publishes or subscribes
  — not on every connection. A client that connects but takes no stream action
  is not sent to your endpoint.
</Note>

## Prerequisites

You need three components in place before configuring Round-Trip Authentication:

<CardGroup cols={3}>
  <Card title="simple-auth-plugin" icon="plug">
    The `red5pro-simple-auth-plugin` JAR must be present on your Red5 Pro server (installed by default).
  </Card>

  <Card title="Validator configuration" icon="file-code">
    The `RoundTripAuthValidator` bean configured in the application's `red5-web.xml`.
  </Card>

  <Card title="Your auth service" icon="server">
    An HTTP service exposing `/validateCredentials` and `/invalidateCredentials` endpoints that accept POST requests from Red5 Pro.
  </Card>
</CardGroup>

<Warning>
  Your authentication service must be running and reachable from your Red5 Pro
  server before you restart Red5 Pro with Round-Trip Authentication enabled.
  Verify your endpoints return the expected responses before going live.
</Warning>

## Step 1 — Implement your authentication endpoints

Your service must expose two endpoints.

### Validate credentials — `POST /validateCredentials`

Red5 Pro calls this endpoint each time a client attempts to publish or subscribe.

**Request body (sent by Red5 Pro):**

```json theme={null}
{
  "username": "testuser",
  "password": "testpass",
  "token": "mytoken",
  "type": "publisher",
  "streamId": "stream1"
}
```

| Field      | Description                                                       |
| ---------- | ----------------------------------------------------------------- |
| `username` | The username the client provided                                  |
| `password` | The password the client provided                                  |
| `token`    | Optional token the client provided (empty string if not supplied) |
| `type`     | `publisher` or `subscriber`                                       |
| `streamId` | The name of the stream being published or subscribed              |

**Expected response:**

Return HTTP `200` with a JSON body to allow the action. Return any non-`200` status to deny it.

### Invalidate credentials — `POST /invalidateCredentials`

Red5 Pro calls this endpoint when a publisher stops streaming.

```json theme={null}
{
  "username": "testuser",
  "streamId": "stream1"
}
```

## Step 2 — Configure the application

Add the `roundTripValidator` and `simpleAuthSecurity` beans to your application's context file. For the `live` application, that file is `RED5_HOME/webapps/live/WEB-INF/red5-web.xml`.

```xml theme={null}
<!-- RED5_HOME/webapps/live/WEB-INF/red5-web.xml -->

<bean id="roundTripValidator"
      class="com.red5pro.server.plugin.simpleauth.datasource.impl.roundtrip.RoundTripAuthValidator"
      init-method="initialize">
    <property name="adapter"                      ref="web.handler" />
    <property name="context"                      ref="web.context" />
    <property name="protocol"                     value="${server.protocol}" />
    <property name="host"                         value="${server.host}" />
    <property name="port"                         value="${server.port}" />
    <property name="validateCredentialsEndPoint"   value="${server.validateCredentialsEndPoint}" />
    <property name="invalidateCredentialsEndPoint" value="${server.invalidateCredentialsEndPoint}" />
    <property name="clientTokenRequired"           value="false" />
</bean>

<bean id="simpleAuthSecurity" class="com.red5pro.server.plugin.simpleauth.Configuration">
    <property name="active"                     value="true" />
    <property name="rtmp"                       value="true" />
    <property name="rtsp"                       value="true" />
    <property name="rtc"                        value="true" />
    <property name="rtmpAllowQueryParamsEnabled" value="true" />
    <property name="allowedRtmpAgents"           value="*" />
    <property name="validator"                   ref="roundTripValidator" />
</bean>
```

Set `clientTokenRequired` to `true` if you want Red5 Pro to reject connections that do not include a `token` parameter.

## Step 3 — Set endpoint properties

Add the following section to `RED5_HOME/webapps/live/WEB-INF/red5-web.properties`. These values are substituted into `red5-web.xml` at runtime.

```properties theme={null}
# RED5_HOME/webapps/live/WEB-INF/red5-web.properties

server.protocol=http://
server.host=192.168.1.100
server.port=3000
server.validateCredentialsEndPoint=/validateCredentials
server.invalidateCredentialsEndPoint=/invalidateCredentials
```

Replace `server.host` with the IP address or hostname of your authentication service. If the service runs on the same instance as Red5 Pro, use the private IP address of that instance.

### Validator bean properties reference

| Property                        | Type    | Description                                                                       |
| ------------------------------- | ------- | --------------------------------------------------------------------------------- |
| `protocol`                      | String  | HTTP protocol to use: `http://` or `https://`                                     |
| `host`                          | String  | Hostname or IP address of your auth service                                       |
| `port`                          | String  | Port your auth service listens on                                                 |
| `validateCredentialsEndPoint`   | String  | URI path for the validation endpoint                                              |
| `invalidateCredentialsEndPoint` | String  | URI path for the invalidation endpoint                                            |
| `clientTokenRequired`           | Boolean | When `true`, Red5 Pro rejects connections that do not include a `token` parameter |

## Step 4 — Connect clients with credentials

Clients pass `username`, `password`, and optionally `token` as connection parameters. The credentials are forwarded to your endpoint on each stream action — your service decides what they mean.

<Tabs>
  <Tab title="WebRTC (HTML5 SDK)">
    ```javascript theme={null}
    var baseConfiguration = {
      host: 'your-server.com',
      app: 'live',
      iceServers: iceServers,
      bandwidth: desiredBandwidth,
      connectionParams: {
        username: 'testuser',
        password: 'testpass',
        token: 'mytoken'      // optional unless clientTokenRequired=true
      }
    };
    ```
  </Tab>

  <Tab title="RTMP — FFmpeg">
    Embed credentials in the RTMP URL as query parameters:

    ```bash theme={null}
    ffmpeg -re -stream_loop -1 -i input.mp4 \
      -c:v h264 -bsf:v h264_mp4toannexb -profile:v baseline \
      -c:a aac -b:a 128k -ar 44100 \
      -f flv "rtmp://your-server.com:1935/live?username=testuser&password=testpass&token=mytoken/myStream"
    ```
  </Tab>

  <Tab title="RTSP — Android">
    ```java theme={null}
    R5Configuration config = new R5Configuration(
        R5StreamProtocol.RTSP,
        TestContent.GetPropertyString("host"),
        TestContent.GetPropertyInt("port"),
        TestContent.GetPropertyString("context"),
        TestContent.GetPropertyFloat("buffer_time"));

    config.setParameters("username=testuser;password=testpass;token=mytoken;");
    R5Connection connection = new R5Connection(config);
    ```
  </Tab>

  <Tab title="RTSP — iOS">
    ```swift theme={null}
    func getConfig() -> R5Configuration {
        let config = R5Configuration()
        config.host        = Testbed.getParameter("host") as! String
        config.port        = Int32(Testbed.getParameter("port") as! Int)
        config.contextName = Testbed.getParameter("context") as! String
        config.parameters  = "username=testuser;password=testpass;token=mytoken;"
        config.protocol    = 1
        config.buffer_time = Testbed.getParameter("buffer_time") as! Float
        return config
    }
    ```
  </Tab>
</Tabs>

<Note>
  Authentication is transparent to clients — they simply provide their
  credentials as connection parameters. They do not need to know that Red5 Pro
  is making a server-to-server call to validate them.
</Note>

## Passing custom parameters

If your authentication logic requires parameters beyond `username`, `password`, and `token`, encode additional values inside the `token` field as a query string or JSON string.

```javascript theme={null}
// WebRTC example: custom parameters encoded in the token field
var baseConfiguration = {
  host: 'your-server.com',
  app: 'live',
  iceServers: iceServers,
  bandwidth: desiredBandwidth,
  connectionParams: {
    username: 'anonymous',
    password: 'anonymous',
    token: 'sessionId=abc123&expires=1716307200&sig=xyz'
  }
};
```

Your `/validateCredentials` endpoint receives the raw `token` string and decodes it however your service expects.

<Tip>
  If you use `username: 'anonymous'` and `password: 'anonymous'` with a
  meaningful `token`, your validation endpoint can ignore the dummy credentials
  and base its decision entirely on the token contents.
</Tip>

## Testing with the mock Node.js service

Red5 Pro provides a [mock authentication backend](https://github.com/red5pro/mock-authentication-backend) built in Node.js to help you test your configuration before writing your own service.

<Steps>
  <Step title="Download and install the mock service">
    Clone the repository onto the server where you want to run the service, then install Node.js:

    ```bash theme={null}
    sudo apt-get install nodejs-legacy
    ```
  </Step>

  <Step title="Edit index.js">
    Open `index.js` and update the two variables under `BEGINNING OF CONFIGURATION`:

    * `host` — set to the private IP address of the server running Node.js
    * `port` — the port the service should listen on (default: `3000`); ensure this port is open in your firewall inbound rules
  </Step>

  <Step title="Start the service">
    ```bash theme={null}
    node index.js
    ```
  </Step>

  <Step title="Verify the service is reachable">
    Open `http://<host>:<port>` in a browser to access the built-in test forms. Use these forms to confirm the endpoints respond before configuring Red5 Pro.
  </Step>

  <Step title="Configure Red5 Pro to point at the mock service">
    Set `server.host` and `server.port` in `red5-web.properties` to match the mock service, then restart Red5 Pro.
  </Step>
</Steps>

When the mock service receives a validation request, its console prints the received parameters:

```
validate credentials called
type: publisher
username: testuser
password: testpass
streamID: stream1
```

The mock service accepts any input and always returns success — it confirms your Red5 Pro configuration is correctly reaching the endpoint, not that the credentials are valid.

## Use case patterns

<AccordionGroup>
  <Accordion title="Registered users (username/password)">
    Users hold accounts on your system. Pass `username` and `password` directly; your endpoint looks them up in your user database and checks permissions.

    This is the simplest pattern and works out of the box with the `RoundTripAuthValidator`.
  </Accordion>

  <Accordion title="One-to-many broadcast (publisher + anonymous subscribers)">
    The publisher authenticates with real credentials. Subscribers pass `username: 'anonymous'` and `password: 'anonymous'` — your endpoint grants subscribe access to everyone or checks a signed token to implement session-based access.
  </Accordion>

  <Accordion title="Session-based anonymous access">
    Issue short-lived signed tokens from your backend after users complete a checkout or registration flow. Pass the signed token in the `token` field. Your endpoint decodes and validates the token without requiring a stored credential pair.
  </Accordion>

  <Accordion title="Custom multi-parameter authentication">
    Encode multiple values (session ID, expiry timestamp, signature) into the `token` field as a query string or JSON. Your endpoint decodes the composite token and applies complex business rules.
  </Accordion>
</AccordionGroup>

## When to use Round-Trip Authentication

<CardGroup cols={2}>
  <Card title="Good fits" icon="circle-check">
    * Integrating with an existing user management or session system
    * One-to-many broadcasts requiring publisher/subscriber role separation
    * Applications that need real-time validation (e.g., check if a subscription is still active at publish time)
    * Complex or custom access control logic that cannot be expressed in JWT claims
    * Anonymous or session-based access patterns
  </Card>

  <Card title="Poor fits" icon="circle-x">
    * High-throughput deployments where the per-stream HTTP round trip would create latency or become a bottleneck — consider [JWT Authentication](/red5-pro/authentication/jwt-auth) for local, low-latency validation
    * Simple deployments with a fixed user list — use [Simple Authentication](/red5-pro/authentication/simple-auth) instead
  </Card>
</CardGroup>
