Voice Communications¶
MAGK integrates with Mumble to provide event-based voice communications. When enabled, the platform deploys a Mumble server alongside an Ice Admin Sidecar that manages channels, ACLs, and LDAP-based authentication — all orchestrated through the MAGK admin interface.
Architecture Overview¶
graph TB
subgraph Docker Network
Web[MAGK Web Service] -->|HTTP API| Sidecar[Ice Admin Sidecar<br/>magk-mumble-admin]
Sidecar -->|ZeroC Ice RPC| Mumble[Mumble Server<br/>magk-mumble]
Sidecar -->|LDAP Bind| LDAP[OpenLDAP<br/>magk-openldap]
Monitor[Monitoring Bot] -->|node-grumble| Mumble
end
TAK[ATAK Vx Plugin] -->|Mumble Protocol| Mumble
Desktop[Mumble Desktop/Mumla] -->|Mumble Protocol| Mumble
Browser[Admin Browser] -->|WebSocket| Monitor The architecture uses a hybrid Ice + node-grumble approach:
- Ice Admin Sidecar — A Python service that connects to Mumble's ZeroC Ice RPC interface for all server administration (channel CRUD, ACL management, user registration, LDAP authentication delegation).
- Monitoring Bot (optional) — A TypeScript client using
node-grumblethat observes real-time channel/user state for the admin dashboard.
Enabling Mumble¶
Voice communications require two environment variables to be set in your .env file:
MUMBLE_ENABLED=true
MUMBLE_LDAP_ENABLED=true
| Variable | Purpose |
|---|---|
MUMBLE_ENABLED | Adds the Mumble server and Ice Admin Sidecar to the Docker Compose stack |
MUMBLE_LDAP_ENABLED | Enables LDAP-based authentication so players can log in with roster credentials |
MUMBLE_MONITORING_ENABLED | Enables the optional real-time monitoring bot for the admin dashboard |
SuperUser Password Required
You must also generate a MUMBLE_SUPERUSER_PASSWORD before starting the stack:
MUMBLE_SUPERUSER_PASSWORD=$(openssl rand -base64 24)
After setting these variables, restart the Docker Compose stack. The magk-mumble and magk-mumble-admin services will start automatically.
Tip
Run bash config/scaling/generate-config.sh to auto-generate all required secrets including the Mumble SuperUser password.
Voice Admin Page¶
The Voice admin page is accessible at /admin/mumble and provides a centralized interface for managing the Mumble server.
Channel Tree¶
The channel tree displays the full Mumble channel hierarchy in a collapsible tree view:
- Root — The server root channel
- Event channels — One per event with Mumble enabled
- Platoon channels — Grouped by platoon
- Squad channels — One per squad in the roster
- Admin channel — Restricted to organizers and administrators
- Platoon channels — Grouped by platoon
- Event channels — One per event with Mumble enabled
Each channel node shows:
| Indicator | Meaning |
|---|---|
| User count badge | Number of currently connected users |
| Speaking indicator | Pulsing icon when a user is transmitting |
| Lock icon | Channel has ACL restrictions |
Connected Users¶
The connected users panel shows all users currently on the Mumble server:
| Column | Description |
|---|---|
| Username | Mumble username (matches roster mumbleUsername) |
| Channel | Current channel location |
| Status | Online, Muted, Deafened, or Speaking |
| Duration | Time connected |
Channel CRUD¶
From the Voice admin page you can:
- Create Channel — Add a new channel under any parent. Specify a name and optional team-based ACL.
- Rename Channel — Edit an existing channel's display name.
- Delete Channel — Remove a channel and all its subchannels. Connected users are moved to the parent channel.
- Move Channel — Drag a channel to a new position in the tree hierarchy.
Note
Channels created during roster finalization are managed by the provisioning system. Manual edits to provisioned channels will be overwritten if the roster is re-finalized.
Channel Access Management¶
Each channel can have access restrictions configured through ACLs (Access Control Lists).
Adding Teams to Channels¶
- Select a channel in the tree view
- Click Manage Access in the channel detail panel
- Use the Add Team dropdown to select a team affiliation
- The system sets an ACL rule using the format
team:<team_name>that restricts the channel to members of that team
When a team is added, the ACL denies enter, speak, and listen to @all and grants those permissions to the team:<team_name> group.
ACL Display¶
The access panel shows current ACL assignments with human-readable labels:
| Display | ACL Group Name | Meaning |
|---|---|---|
| Squad: Alpha | squad:alpha | Only Alpha squad members can access |
| Team: BLUFOR | team:blufor | Only BLUFOR team members can access |
| Event: Operation Sunrise | event:operation_sunrise | All participants in this event can access |
| Platoon: 1st Platoon | platoon:1st_platoon | All members of 1st Platoon can access |
Group Name Format
Mumble group names follow the format <type>:<normalized_name> where the name is lowercased with spaces replaced by underscores. The authenticator returns these same group names during login, allowing Mumble's built-in ACL engine to enforce access.
Removing Access¶
To remove a team from a channel's ACL:
- Select the channel
- In the Manage Access panel, click the × next to the team entry
- The corresponding ACL rule is removed from the channel
Event-Based Voice Provisioning¶
Voice channels are automatically provisioned during roster finalization. This is the recommended workflow for event-based voice communications.
sequenceDiagram
participant Admin
participant Web as MAGK Web
participant Sidecar as Ice Admin Sidecar
participant Mumble as Mumble Server
Admin->>Web: Finalize Roster
Web->>Sidecar: Create root event channel
Sidecar->>Mumble: Ice addChannel()
Mumble-->>Sidecar: Channel ID
Web->>Sidecar: Create platoon channels
Web->>Sidecar: Create squad channels
Web->>Sidecar: Create admin channel
Web->>Sidecar: Set ACLs per channel
Sidecar->>Mumble: Ice setACL()
Web->>Web: Update event (mumbleChannelsCreated=true)
Web-->>Admin: Provisioning complete Channel Hierarchy¶
The provisioning service creates channels mirroring the roster structure:
Event: Operation Sunrise
├── Platoon: 1st Platoon
│ ├── Squad: Alpha
│ └── Squad: Bravo
├── Platoon: 2nd Platoon
│ ├── Squad: Charlie
│ └── Squad: Delta
└── Admin (organizers/admins only)
Channel Modes¶
When enabling Mumble for an event, you choose a channel mode:
| Mode | Behavior |
|---|---|
| Roster-Based | Full hierarchy (Root → Platoons → Squads + Admin channel) created during finalization |
| Admin Channel Only | Single root channel with an Admin sub-channel — no squad hierarchy |
Deprovisioning¶
To remove provisioned channels:
- Navigate to the event's Communications section
- Click Deprovision Channels
- Confirm the action
This removes all Mumble channels for the event (including the admin channel) and resets mumbleChannelsCreated to false.
Manual Channel Creation¶
For scenarios outside the roster workflow (e.g., persistent team channels, training rooms), create channels manually:
- Go to
/admin/mumble - Click Create Channel
- Enter a channel name and select a parent channel
- Optionally assign a team via the Add Team dropdown to restrict access
- Click Create
Tip
Manual channels are useful for persistent team voice rooms that span multiple events. Assign a team affiliation to automatically restrict access to team members.
ATAK Vx Plugin Integration¶
TAK users connect to Mumble through the ATAK Vx (Voice) plugin. MAGK distributes Mumble connection configuration automatically through two mechanisms:
Data Packages¶
When Mumble is enabled for an event, the TAK data package generator includes Vx plugin configuration:
- ATAK packages — The
preference.preffile includes acom.atakmap.app.vxpreference section with Mumble host, port, username, and channel settings. - iTAK packages — The
config.preffile includes equivalent Vx configuration entries.
Players who import their data package get Mumble auto-configured alongside their TAK server connection.
QR Code Enrollment¶
QR code payloads are resolved dynamically at scan time. When Mumble is provisioned for an event, the QR payload includes:
{
"serverHost": "magktech.com",
"serverPort": 8089,
"mumbleHost": "magktech.com",
"mumblePort": 64738,
"mumbleUsername": "player_alpha_01",
"mumbleChannel": "Operation Sunrise/1st Platoon/Alpha"
}
Dynamic Resolution
QR payloads are resolved at scan time (not stored statically), so they always reflect the latest Mumble configuration — including channel assignments set after initial registration.
TLS Certificate¶
The Mumble server uses a TLS certificate for encrypted connections. The certificate must include the extendedKeyUsage=1.3.6.1.5.5.7.3.1 (TLS Web Server Authentication) extension for the Vx plugin to trust the connection.
Certificate mode is controlled by MUMBLE_CERT_MODE:
| Mode | Behavior |
|---|---|
self-signed | Mumble generates its own self-signed certificate (default) |
ca | Certificate is generated from the MAGK CA for trust chain consistency |
Auto-Placement¶
When a player connects to Mumble with LDAP credentials, the authenticator resolves their group memberships and returns them to the Mumble server. Combined with channel ACLs, this means:
- Player authenticates with their roster username/password
- The Ice authenticator queries MAGK for the player's squad, platoon, team, and event memberships
- Mumble receives the group list (e.g.,
["event:operation_sunrise", "platoon:1st_platoon", "squad:alpha", "team:blufor"]) - The player can only enter channels where their groups match the ACL rules
- The Vx plugin's channel configuration (from the data package) places them directly into their assigned squad channel
Note
Auto-placement relies on the Vx plugin's channel preference being set correctly in the data package. Players using standalone Mumble clients will need to navigate to their channel manually.
Troubleshooting¶
Certificate Errors¶
| Symptom | Cause | Solution |
|---|---|---|
| "Certificate not trusted" in Vx plugin | Self-signed certificate not accepted | Switch to MUMBLE_CERT_MODE=ca or manually trust the certificate in ATAK settings |
| TLS handshake failure | Missing extendedKeyUsage extension | Regenerate the Mumble TLS certificate with the server auth extension |
| Certificate mismatch | Hostname doesn't match certificate CN/SAN | Ensure MUMBLE_HOST matches the certificate's subject |
Connection Timeouts¶
| Symptom | Cause | Solution |
|---|---|---|
| Client cannot connect | Port 64738 not exposed | Verify Docker port mapping and firewall rules for UDP/TCP 64738 |
| Ice Admin Sidecar unreachable | Sidecar not started or unhealthy | Check docker logs magk-mumble-admin and verify the health check |
| "Server connection failed" | Mumble server not ready | Wait for the magk-mumble health check to pass before connecting |
Authentication Issues¶
| Symptom | Cause | Solution |
|---|---|---|
| "Invalid username or password" | LDAP credentials not provisioned | Ensure roster finalization completed successfully |
| Login works but no channel access | Authenticator returning empty groups | Check the membership lookup API at /api/internal/mumble-groups |
| Intermittent auth failures | LDAP server overloaded | Check OpenLDAP container health and resource limits |
Connection Test¶
Use the admin UI connection test to verify the voice infrastructure:
- Go to
/admin/mumble - Click Test Connection
- The system verifies:
- Ice Admin Sidecar is reachable
- Ice connection to Mumble server is active
- Mumble server version is reported
If the test fails, check the Docker container logs:
docker logs magk-mumble
docker logs magk-mumble-admin
Related Pages¶
- Configuration Reference — Mumble environment variables
- Data Packages — TAK data package generation including Vx config
- Teams — Team management for ACL assignments
- Events — Event creation and Mumble configuration
- Workflow — Automated workflows triggered by roster finalization