Broadcast Box
Overview
Broadcast Box is an open source WebRTC live streaming server. It implements WHIP for ingest and WHEP for playback, the two standards that carry video over the same real-time transport a video call uses. The delay between something happening in front of the camera and a viewer seeing it is a fraction of a second, rather than the ten to thirty seconds that a traditional segmented streaming pipeline imposes.
You broadcast from OBS Studio or any encoder that speaks WHIP, or directly from a browser tab. Viewers watch in any modern browser with no plugin, no app and no third-party streaming service in the video path. This guide covers deploying and configuring Broadcast Box on Ubuntu 24.04 on Azure from the SecureAnyCloud Azure Marketplace image.
What you get:
- Compiled from the pinned upstream release. The image is compiled at build time, and the compilers and source tree are then removed. What ships is a single static Go binary at
/usr/local/bin/broadcast-boxplus the built web interface. It runs under systemd as the non-rootbroadcastboxuser. - Publishing is closed by default. This is a deliberate departure from the upstream default, and it is the most important thing to understand about this image. Broadcast Box normally runs with
STREAM_PROFILE_POLICY=ANYONE_WITH_RESERVED, under which any anonymous caller may publish to any stream key that has not been reserved. On a virtual machine with a public address, that is an open media relay: a stranger who finds your instance can push video through your bandwidth. This image shipsSTREAM_PROFILE_POLICY=RESERVEDinstead. - Every publish requires a bearer token that belongs to a reserved stream profile. Exactly one such profile exists, and it is created on this VM's first boot. An anonymous publish attempt, or one with a wrong credential, is refused.
- The admin portal requires a separate token, also generated on first boot. The portal and the whole
/api/admin/*surface return HTTP 401 without it. - No credential of any kind is baked into the image. Two machines launched from the same image get different tokens.
- Playback is open to anyone holding the stream key, which is what makes a player link shareable. The stream key is random per VM, so it is not guessable, but treat it as a capability: anyone you give it to can watch. Mint additional reserved profiles from the admin portal if you need to revoke access for one audience without disturbing another.
- Broadcast Box, compiled from the pinned upstream release and run under systemd as the unprivileged
broadcastboxuser (broadcast-box.service). - The web interface on port 80: stream discovery, browser publishing, a player with cinema mode, a statistics page and an admin portal.
- All WebRTC media muxed onto a single UDP port (3478), so you open one UDP port rather than an ephemeral range.
- A per-VM admin token and a per-VM reserved stream profile, generated on first boot and written to a root-only credentials file.
- A shipped round-trip self-test that proves the auth model end to end, including that an anonymous publish is refused.
- Ubuntu 24.04 LTS, patched at build time, with unattended security upgrades enabled.
Prerequisites
- An active Azure subscription.
- An SSH public key.
- A VNet and subnet in the target region.
- A subscription to the Broadcast Box listing on Azure Marketplace.
- Network Security Group rules that allow TCP 22 (admin), TCP 80 (web interface and WHIP/WHEP signaling) and UDP 3478 (all WebRTC media).
- The recommended virtual machine size is
Standard_B2s(2 vCPU, 4 GB RAM), which is ample for a handful of concurrent viewers. Broadcast Box forwards media without transcoding, so its cost is bandwidth rather than CPU. Increase the size for large viewer counts.
Deploy from the Azure Portal
In Azure Marketplace, search for Broadcast Box, select the SecureAnyCloud publisher, and choose Create.
Configure the Network Security Group to allow TCP 80 and UDP 3478 from the networks your broadcasters and viewers will connect from, and TCP 22 for administration. For internet exposure, front port 80 with TLS (see Step 10).
Deploy from the Azure CLI
RG="broadcast-box-prod"; LOCATION="eastus"; VM_NAME="broadcastbox1" IMAGE_URN="sac1647283583153:broadcast-box-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:broadcast-box-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$IMAGE_URN" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard \
--os-disk-delete-option Delete --nic-delete-option Delete
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 80 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 3478 --protocol Udp --priority 1002Both rules matter. Opening TCP 80 alone produces the classic WebRTC failure. The page loads and the player appears to connect, but no video ever arrives, because signaling succeeds over HTTP while the media plane is silently blocked. If a stream never starts, check the UDP rule first.
First boot
On first boot, the image generates a unique admin token, stream key and publish bearer token for this VM. It writes the single reserved stream profile, records the machine's public address so that WebRTC advertises a reachable path, and arms the service. Nothing is shared between VMs.
Read your credentials over SSH:
sudo cat /root/broadcast-box-credentials.txt# Broadcast Box — Per-VM Instance Info
# Generated: Sun Jul 19 13:34:42 UTC 2026
#
# There are NO default credentials. Every value below was generated uniquely on
# THIS VM's first boot and was never baked into the image. Keep this file secret # (root only). # broadcastbox.url=http://<your-vm-ip>/ broadcastbox.admin_url=http://<your-vm-ip>/admin broadcastbox.admin_token=**** broadcastbox.stream_key=cimg-95680abd4df2fa38 broadcastbox.stream_token=**** broadcastbox.whip_endpoint=http://<your-vm-ip>/api/whip broadcastbox.player_url=http://<your-vm-ip>/cimg-95680abd4df2fa38The file also records the OBS settings and the network rules you need. Keep it secret: the stream token is your publishing credential.
Confirm the server is running
systemctl is-active broadcast-box ss -tln | grep -E ':80 |:22 ' ss -uln | grep ':3478 'active LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* LISTEN 0 4096 [::]:22 [::]:* LISTEN 0 4096 *:80 *:* UNCONN 0 0 10.0.0.8:3478 0.0.0.0:*The listener set is deliberately small. The Broadcast Box HTTP server on port 80 and sshd on port 22 are the only externally bound TCP services, and UDP 3478 carries all WebRTC media for both publishing and playback.
No database is installed, because Broadcast Box is stateless. Streams are live sessions held in memory, and nothing is recorded to disk.
The server binds port 80 as a non-root user through a single Linux capability, rather than running as root:
systemctl show -p User -p AmbientCapabilities -p ProtectSystem -p NoNewPrivileges --value broadcast-box.servicecap_net_bind_service broadcastbox strict yesRun the round-trip self-test
The image ships a self-test that proves the access control actually works, rather than merely that a port is open. A liveness check would pass on an image that lets the whole internet publish.
The self-test authenticates with the per-VM admin token and confirms that the per-VM stream token is accepted for publishing. It then runs the negative controls that matter.
sudo bash /usr/local/lib/sac/broadcast-box-roundtrip.shROUNDTRIP OK: the frontend (200) and public status API (200) serve; the per-VM admin token authenticated against /api/admin/login (200) while a missing header and a wrong token were both rejected (401); an ANONYMOUS WHIP publish was refused, an EMPTY bearer was refused 401, and a WRONG bearer was refused 401 by STREAM_PROFILE_POLICY=RESERVED, proving the ingest endpoint is not an open relay; and the per-VM reserved stream token passed WHIP authorisation (HTTP 400, not 401), proving the customer's own publish credential works. Stream key cimg-95680abd4df2fa38 is the reserved playback path.Verify the auth model yourself
You do not have to take the self-test's word for it. These five requests are the whole security model, and you can run them directly.
echo "admin login, correct token: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Authorization: Bearer <BB_ADMIN_TOKEN>' http://127.0.0.1/api/admin/login)"
echo "admin login, wrong token: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Authorization: Bearer wrong' http://127.0.0.1/api/admin/login)"
echo "publish, anonymous: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/sdp' --data-binary 'v=0' http://127.0.0.1/api/whip)"
echo "publish, wrong bearer: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/sdp' -H 'Authorization: Bearer not-a-reserved-token' --data-binary 'v=0' http://127.0.0.1/api/whip)"
echo "publish, your stream token: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/sdp' -H 'Authorization: Bearer <BB_STREAM_TOKEN>' --data-binary 'v=0' http://127.0.0.1/api/whip)"admin login, correct token: 200 admin login, wrong token: 401 publish, anonymous: 400 publish, wrong bearer: 401 publish, your stream token: 400Reading those results:
The admin portal is closed. The correct token authenticates, and anything else returns 401.
Publishing is closed. An anonymous attempt is refused (400, Authorization was not set). A wrong bearer token is refused with 401 by the reserved stream policy. On a stock Broadcast Box deployment, that wrong bearer token would have been accepted and would have started a stream.
Your own token gets through authorization. It returns 400 rather than 401, because v=0 is not a negotiable WebRTC offer, so the request fails later, during media negotiation. That is exactly as it should be. The distinction between 400 and 401 is the whole point: 401 means the request was rejected at the door, and 400 means it was admitted and then given nonsense. A real encoder sends a real offer and streams.
Inspect your reserved stream profile
The admin API lists the reserved profiles that the server has loaded. This is the authoritative check that your publish credential is live.
curl -s -H 'Authorization: Bearer <BB_ADMIN_TOKEN>' http://127.0.0.1/api/admin/profiles echo
curl -s -o /dev/null -w 'admin status, with token: %{http_code}\n' -H 'Authorization: Bearer <BB_ADMIN_TOKEN>' http://127.0.0.1/api/admin/status
curl -s -o /dev/null -w 'admin status, no token: %{http_code}\n' http://127.0.0.1/api/admin/status[{"streamKey":"cimg-95680abd4df2fa38","token":"****","isPublic":true,"motd":"sac Broadcast Box"}] admin status, with token: 200 admin status, no token: 401Broadcast with OBS Studio
OBS Studio 30 and later speaks WHIP natively. In Settings > Stream, set:
- Service: WHIP
- Server:
http://<your-vm-ip>/api/whip - Bearer Token: the
broadcastbox.stream_tokenvalue from your credentials file
Choose OK, then Start Streaming. WebRTC is latency-sensitive rather than bitrate-hungry, so a moderate bitrate and a short keyframe interval give the best experience. Viewers then watch at:
http://<your-vm-ip>/<your-stream-key>Any WHIP-capable encoder works the same way, such as ffmpeg 8 and later, GStreamer with the appropriate plugins, or a browser tab through the publish page.
You can also publish straight from the browser by opening http://<your-vm-ip>/publish/<your-stream-key>. The page captures your screen or webcam without any software installed.
Use the web interface
The home page lists the streams that are currently live on this instance, and it doubles as the entry point for viewers.
Opening a stream key as a path shows the player. With no broadcaster connected, the player says so plainly. Once an encoder connects, video appears in well under a second.
Switching the toggle to I want to stream turns the same panel into the publishing form. Enter your stream key and start broadcasting directly from a browser tab, capturing a screen, a window or a webcam with nothing installed.
The statistics page reports stream uptime and subscriber counts. The admin portal at /admin asks for the admin token before it shows active publishers and subscribers or lets you manage reserved stream profiles.
Front the server with TLS for internet exposure
Browsers restrict camera and screen capture to secure contexts, so publishing from a browser tab requires HTTPS on anything other than localhost. Playback works over plain HTTP, but you should terminate TLS for any internet-facing deployment regardless.
Point a DNS record at the VM, then place a TLS-terminating proxy in front of port 80.
Alternatively, Broadcast Box accepts SSL_CERT and SSL_KEY directly, so it can terminate TLS itself. Set them in /etc/broadcast-box/broadcast-box.env and restart the service.
Whichever route you take, UDP 3478 must remain open, because media never travels over the TLS connection.
Security recommendations
Keep the stream token secret. It is the publishing credential. Anyone who holds it can broadcast on your instance.
Treat the stream key as a viewing capability. Playback is deliberately open to whoever holds the key, so that links are shareable. If different audiences must not share access, create a separate reserved profile for each audience in the admin portal and revoke them individually.
Scope your Network Security Group. Restrict TCP 80 and UDP 3478 to the networks that genuinely need them, rather than the whole internet, especially while testing.
Rotate tokens from the admin portal if a credential is ever exposed. The credentials file records the values generated at first boot, and later rotations do not update it.
Leave unattended security upgrades enabled. The image is patched at build time and ships with automatic security updates armed.
The service runs as the unprivileged broadcastbox user with a strict read-only filesystem, no new privileges, and only the single capability it needs to bind port 80.
Support and Licensing
Broadcast Box is distributed under the MIT license. This is a repackaged open source software product with additional charges for SecureAnyCloud support services. SecureAnyCloud is not affiliated with or endorsed by Glimesh or the Broadcast Box project.
The vendored license text ships on the image at /usr/local/share/doc/broadcast-box/LICENSE.
For help with this image, contact SecureAnyCloud support at sales@secureanycloud.com. Support is available 24/7.
Deploy on Azure
Launch Broadcast Box on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Broadcast Box is an open source WebRTC live streaming server. It implements WHIP for ingest and WHEP for playback, the two standards that carry video over the same real-time transport a video call uses. The delay between something happening in front of the camera and a viewer seeing it is a fraction of a second, rather than the ten to thirty seconds that a traditional segmented streaming pipeline imposes.
You broadcast from OBS Studio or any encoder that speaks WHIP, or directly from a browser tab. Viewers watch in any modern browser with no plugin, no app and no third-party streaming service in the video path. This guide covers deploying and configuring Broadcast Box on AWS from the SecureAnyCloud AWS Marketplace AMI.
What you get:
- Compiled from the pinned upstream release. The image is compiled at build time, and the compilers and source tree are then removed. What ships is a single static Go binary at
/usr/local/bin/broadcast-boxplus the built web interface. It runs under systemd as the non-rootbroadcastboxuser. - Publishing is closed by default. This is a deliberate departure from the upstream default, and it is the most important thing to understand about this image. Broadcast Box normally runs with
STREAM_PROFILE_POLICY=ANYONE_WITH_RESERVED, under which any anonymous caller may publish to any stream key that has not been reserved. On an instance with a public address, that is an open media relay: a stranger who finds your instance can push video through your bandwidth. This image shipsSTREAM_PROFILE_POLICY=RESERVEDinstead. - Every publish requires a bearer token that belongs to a reserved stream profile. Exactly one such profile exists, and it is created on this instance's first boot. An anonymous publish attempt, or one with a wrong credential, is refused.
- The admin portal requires a separate token, also generated on first boot. The portal and the whole
/api/admin/*surface return HTTP 401 without it. - No credential of any kind is baked into the image. Two instances launched from the same AMI get different tokens.
- Playback is open to anyone holding the stream key, which is what makes a player link shareable. The stream key is random per instance, so it is not guessable, but treat it as a capability: anyone you give it to can watch. Mint additional reserved profiles from the admin portal if you need to revoke access for one audience without disturbing another.
- Broadcast Box, compiled from the pinned upstream release and run under systemd as the unprivileged
broadcastboxuser (broadcast-box.service). - The web interface on port 80: stream discovery, browser publishing, a player with cinema mode, a statistics page and an admin portal.
- All WebRTC media muxed onto a single UDP port (3478), so you open one UDP port rather than an ephemeral range.
- A per-instance admin token and a per-instance reserved stream profile, generated on first boot and written to a root-only credentials file.
- A shipped round-trip self-test that proves the auth model end to end, including that an anonymous publish is refused.
- Ubuntu 24.04 LTS, fully patched, with unattended security upgrades enabled.
Prerequisites
- An AWS account.
- An EC2 key pair in the target region.
- A subscription to the Broadcast Box listing on AWS Marketplace.
- A security group that allows TCP 22 (administration), TCP 80 (web interface and WHIP/WHEP signaling) and UDP 3478 (all WebRTC media).
- The recommended instance type is
m5.large(2 vCPU, 8 GB RAM), which is ample for a handful of concurrent viewers. Broadcast Box forwards media without transcoding, so its cost is bandwidth rather than CPU. Increase the size for large viewer counts.
Connecting to your instance
Connect over SSH as the default login user for your AMI, using the private key of the EC2 key pair you launched with. On Ubuntu 24.04, the SSH login user is ubuntu. For example: ssh -i your-key.pem ubuntu@<public-ip>
Launch from the AWS Console
In AWS Marketplace, subscribe to Broadcast Box, choose the SecureAnyCloud listing, and launch the Ubuntu 24.04 AMI with your key pair.
Attach a security group that allows TCP 80 and UDP 3478 from the networks your broadcasters and viewers will connect from, and TCP 22 for administration. For internet exposure, front port 80 with TLS (see Step 10).
Launch from the AWS CLI
aws ec2 run-instances \
--image-id ami-xxxxxxxxxxxxxxxxx \
--instance-type m5.large \
--key-name your-key \
--security-group-ids sg-xxxxxxxx \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=broadcast-box}]'Then authorize the required ingress on the security group:
aws ec2 authorize-security-group-ingress --group-id sg-xxxxxxxx --protocol tcp --port 22 --cidr <your-cidr>
aws ec2 authorize-security-group-ingress --group-id sg-xxxxxxxx --protocol tcp --port 80 --cidr <your-cidr>
aws ec2 authorize-security-group-ingress --group-id sg-xxxxxxxx --protocol udp --port 3478 --cidr <your-cidr>Both the TCP 80 and UDP 3478 rules matter. Opening TCP 80 alone produces the classic WebRTC failure. The page loads and the player appears to connect, but no video ever arrives, because signaling succeeds over HTTP while the media plane is silently blocked. If a stream never starts, check the UDP rule first.
Scope both rules to the CIDRs your broadcasters and viewers actually use, rather than the whole internet.
First boot
On first boot, the image generates a unique admin token, stream key and publish bearer token for this instance. It writes the single reserved stream profile, records the instance's public address (through EC2 IMDSv2) so that WebRTC advertises a reachable path, and arms the service. Nothing is shared between instances.
Read your credentials over SSH:
sudo cat /root/broadcast-box-credentials.txt# Broadcast Box - Per-VM Instance Info
#
# There are NO default credentials. Every value below was generated uniquely on
# THIS instance's first boot and was never baked into the image. Keep this file # secret (root only). # broadcastbox.url=http://<public-ip>/ broadcastbox.admin_url=http://<public-ip>/admin broadcastbox.admin_token=**** broadcastbox.stream_key=cimg-xxxxxxxxxxxxxxxx broadcastbox.stream_token=**** broadcastbox.whip_endpoint=http://<public-ip>/api/whip broadcastbox.player_url=http://<public-ip>/cimg-xxxxxxxxxxxxxxxxThe file also records the OBS settings and the network rules you need. Keep it secret: the stream token is your publishing credential.
Confirm the server is running
systemctl is-active broadcast-box ss -tln | grep -E ':80 |:22 ' ss -uln | grep ':3478 'active LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* LISTEN 0 4096 *:80 *:* LISTEN 0 4096 [::]:22 [::]:* UNCONN 0 0 172.31.91.225:3478 0.0.0.0:*The listener set is deliberately small. The Broadcast Box HTTP server on port 80 and sshd on port 22 are the only externally bound TCP services, and UDP 3478 carries all WebRTC media for both publishing and playback.
No database is installed, because Broadcast Box is stateless. Streams are live sessions held in memory, and nothing is recorded to disk.
The server binds port 80 as a non-root user through a single Linux capability, rather than running as root:
systemctl show -p User -p AmbientCapabilities -p ProtectSystem -p NoNewPrivileges --value broadcast-box.servicecap_net_bind_service broadcastbox strict yesRun the round-trip self-test
The image ships a self-test that proves the access control actually works, rather than merely that a port is open. A liveness check would pass on an image that lets the whole internet publish.
The self-test authenticates with the per-instance admin token and confirms that the per-instance stream token is accepted for publishing. It then runs the negative controls that matter.
sudo bash /usr/local/lib/sac/broadcast-box-roundtrip.shROUNDTRIP OK: the frontend (200) and public status API (200) serve; the per-VM admin token authenticated against /api/admin/login (200) while a missing header and a wrong token were both rejected (401); an ANONYMOUS WHIP publish was refused, an EMPTY bearer was refused 401, and a WRONG bearer was refused 401 by STREAM_PROFILE_POLICY=RESERVED, proving the ingest endpoint is not an open relay; and the per-VM reserved stream token passed WHIP authorisation (HTTP 400, not 401), proving your own publish credential works.Verify the auth model yourself
You do not have to take the self-test's word for it. These five requests are the whole security model, and you can run them directly.
echo "admin login, correct token: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Authorization: Bearer <BB_ADMIN_TOKEN>' http://127.0.0.1/api/admin/login)"
echo "admin login, wrong token: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Authorization: Bearer wrong' http://127.0.0.1/api/admin/login)"
echo "publish, anonymous: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/sdp' --data-binary 'v=0' http://127.0.0.1/api/whip)"
echo "publish, wrong bearer: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/sdp' -H 'Authorization: Bearer not-a-reserved-token' --data-binary 'v=0' http://127.0.0.1/api/whip)"
echo "publish, your stream token: $(curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/sdp' -H 'Authorization: Bearer <BB_STREAM_TOKEN>' --data-binary 'v=0' http://127.0.0.1/api/whip)"admin login, correct token: 200 admin login, wrong token: 401 publish, anonymous: 400 publish, wrong bearer: 401 publish, your stream token: 400Reading those results:
The admin portal is closed. The correct token authenticates, and anything else returns 401.
Publishing is closed. An anonymous attempt is refused (400, Authorization was not set). A wrong bearer token is refused with 401 by the reserved stream policy. On a stock Broadcast Box deployment, that wrong bearer token would have been accepted and would have started a stream.
Your own token gets through authorization. It returns 400 rather than 401, because v=0 is not a negotiable WebRTC offer, so the request fails later, during media negotiation. That is exactly as it should be. The distinction between 400 and 401 is the whole point: 401 means the request was rejected at the door, and 400 means it was admitted and then given nonsense. A real encoder sends a real offer and streams.
Inspect your reserved stream profile
The admin API lists the reserved profiles that the server has loaded. This is the authoritative check that your publish credential is live.
curl -s -o /dev/null -w 'admin status, with token: %{http_code}\n' -H 'Authorization: Bearer <BB_ADMIN_TOKEN>' http://127.0.0.1/api/admin/status
curl -s -o /dev/null -w 'admin status, no token: %{http_code}\n' http://127.0.0.1/api/admin/statusadmin status, with token: 200 admin status, no token: 401Use the web interface
The home page is the entry point for both viewers and broadcasters. A viewer pastes a stream key to watch, and a broadcaster switches the toggle to publish.
Switching the toggle to I want to stream turns the same panel into the publishing form. Enter your stream key and start broadcasting directly from a browser tab, capturing a screen, a window or a webcam with nothing installed. This requires HTTPS (see Step 10).
The admin portal at /admin asks for the per-instance admin token before it shows anything. Without the token, the portal is closed.
Once you enter the admin token, the portal opens on the Stream Status Overview, which lists active stream keys with their session and packet counts. Tabs let you manage reserved stream profiles, inspect the API and rotate tokens.
Broadcast with OBS Studio
OBS Studio 30 and later speaks WHIP natively. In Settings > Stream, set:
- Service: WHIP
- Server:
http://<public-ip>/api/whip - Bearer Token: the
broadcastbox.stream_tokenvalue from your credentials file
Choose OK, then Start Streaming. WebRTC is latency-sensitive rather than bitrate-hungry, so a moderate bitrate and a short keyframe interval give the best experience. Viewers then watch at http://<public-ip>/<your-stream-key>.
Any WHIP-capable encoder works the same way, such as ffmpeg with WHIP support, GStreamer with the appropriate plugins, or a browser tab through the publish page.
Front the server with TLS for internet exposure
Browsers restrict camera and screen capture to secure contexts, so publishing from a browser tab requires HTTPS on anything other than localhost. Playback and OBS/WHIP publishing work over plain HTTP, but you should terminate TLS for any internet-facing deployment regardless.
Point a DNS record at the instance, then place a TLS-terminating proxy in front of port 80.
Alternatively, Broadcast Box accepts SSL_CERT and SSL_KEY directly, so it can terminate TLS itself. Set them in /etc/broadcast-box/broadcast-box.env and restart the service.
Whichever route you take, UDP 3478 must remain open, because media never travels over the TLS connection.
Security recommendations
Keep the stream token secret. It is the publishing credential. Anyone who holds it can broadcast on your instance.
Treat the stream key as a viewing capability. Playback is deliberately open to whoever holds the key, so that links are shareable. If different audiences must not share access, create a separate reserved profile for each audience in the admin portal and revoke them individually.
Scope your security group. Restrict TCP 80 and UDP 3478 to the networks that genuinely need them, rather than the whole internet, especially while testing.
Rotate tokens from the admin portal if a credential is ever exposed. The credentials file records the values generated at first boot, and later rotations do not update it.
Leave unattended security upgrades enabled. The image ships fully patched with automatic security updates armed.
The service runs as the unprivileged broadcastbox user with a strict read-only filesystem, no new privileges, and only the single capability it needs to bind port 80.
Support and Licensing
Broadcast Box is distributed under the MIT license. This is a repackaged open source software product with additional charges for SecureAnyCloud support services. SecureAnyCloud is not affiliated with or endorsed by Glimesh or the Broadcast Box project.
The vendored license text ships on the image at /usr/local/share/doc/broadcast-box/LICENSE.
For help with this image, contact SecureAnyCloud support at sales@secureanycloud.com. Support is available 24/7.
Deploy on AWS
Launch Broadcast Box with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com