A privacy-focused voice communication server and client, inspired by TeamSpeak, built entirely in Go.
GoSpeak uses a Selective Forwarding Unit (SFU) architecture — the server relays encrypted voice packets between clients without ever decoding the audio. All voice data is end-to-end encrypted with AES-128-GCM.
- Real-time voice chat — Opus codec at 48 kHz, 20ms frames via PortAudio
- Encrypted voice — AES-128-GCM with authenticated headers; server relays without decoding (see Security for key model caveats)
- TLS 1.3 control plane — auto-generated self-signed certificates or bring your own
- Channel system — hierarchical channels with sub-channels, temporary channels, max-user limits
- Role-based access control — Admin, Moderator, User roles with granular permissions
- Token-based authentication — 256-bit random tokens, SHA-256 hashed storage
- Text chat — per-channel messaging
- Desktop GUI — native cross-platform UI built with Fyne
- Server bookmarks — save and manage server connections
- YAML configuration — server channels, client settings, bookmarks
- Admin tools — create/delete channels, manage tokens, kick/ban, import/export config
- Global hotkeys — configurable push-to-mute/deafen (Windows; F11/F12 default)
- Voice Activity Detection — energy-based VAD with configurable threshold
- Containerized builds — reproducible multi-stage Podman/Docker builds for Linux and Windows
Note: Voice packets are encrypted with a shared AES-128 key generated by the server and distributed to clients over TLS. The server chooses not to decrypt audio, but a compromised or modified server could. See Security — Threat Model for details. But at least you only need to trust yourself or your friends if you self-host the Server, I'll take that any day over trusting Discord with my data...
docker compose up --buildThe server listens on:
- TCP :9600 — TLS control plane
- UDP :9601 — Encrypted voice
- TCP :9602 — Prometheus metrics HTTP
On first run, an admin token is printed to stdout — save it to create more tokens and manage the server.
# Extract binaries from container build
docker compose --profile build run builder
# Run server
./bin/gospeak-server -open # -open allows token-less connectionsDownload the appropriate binary for your platform from Releases, or build from source:
./bin/gospeak-client-win.exe # Windows
./bin/gospeak-client-lin # LinuxEnter the server address, your username, and (optionally) an invite token to connect. On first login the server issues a personal token; keep it to reconnect with the same username.
┌─────────────────────────────────────────────────────┐
│ GoSpeak Server │
│ │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────┐ │
│ │ Control Plane │ │ Voice SFU │ │ SQLite │ │
│ │ TCP/TLS 1.3 │ │ UDP Relay │ │ Store │ │
│ │ :9600 │ │ :9601 │ │ │ │
│ └──────────────┘ └───────────────┘ └──────────┘ │
└─────────────────────────────────────────────────────┘
│ │
JSON/TLS AES-128-GCM
│ │
┌─────────────────────────────────────────────────────┐
│ GoSpeak Client │
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────┐ ┌────────┐ │
│ │ Fyne GUI │ │ Engine │ │ Audio │ │ Crypto │ │
│ │ │ │ Control │ │ Opus │ │ AES │ │
│ │ │ │ + Voice │ │ + VAD │ │ GCM │ │
│ └──────────┘ └──────────┘ └────────┘ └────────┘ │
└─────────────────────────────────────────────────────┘
| Document | Description |
|---|---|
| Architecture | Package structure, data models, server/client lifecycle |
| Protocol | Control plane messages, voice packet format, wire protocol |
| Security | Encryption details, key distribution, RBAC, threat model |
| Audio Pipeline | Capture/playback, Opus codec, VAD, jitter buffer |
| Building | Container builds, local dev setup, build targets |
| Deployment | Rocky Linux 10 cloud-init example |
| Flag | Default | Description |
|---|---|---|
-control |
:9600 |
TCP/TLS bind address |
-voice |
:9601 |
UDP voice bind address |
-db |
gospeak.db |
SQLite database path |
-data |
. |
Data directory (TLS certs, etc.) |
-open |
false |
Allow connections without a token |
-channels-file |
YAML file for initial channel setup | |
-cert / -key |
(auto-generated) | Custom TLS certificate |
-metrics |
:9602 |
Prometheus /metrics HTTP endpoint (empty to disable) |
-export-users |
false |
Export all users as YAML and exit |
-export-channels |
false |
Export all channels as YAML and exit |
-log-level |
info |
Log level |
-log-format |
text |
Log format: text or json |
channels:
- name: General
description: Main voice channel
max_users: 50
- name: Gaming
description: Gaming channels
allow_sub_channels: true
children:
- name: FPS
- name: MMO| Component | Technology |
|---|---|
| Language | Go 1.24 |
| GUI | Fyne v2 |
| Audio I/O | PortAudio via gordonklaus/portaudio |
| Voice Codec | Opus via hraban/opus |
| Encryption | AES-128-GCM (stdlib crypto/aes), Argon2id (golang.org/x/crypto) |
| Database | SQLite via modernc.org/sqlite (pure Go) |
| TLS | Go stdlib crypto/tls (TLS 1.3) |
| Config | gopkg.in/yaml.v3 |
| Containers | Podman / Docker with multi-stage builds |
See CONTRIBUTING.md for development guidelines.
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
This means you can use, modify, and distribute GoSpeak freely, but:
- Any modified version must also be open-sourced under AGPL-3.0
- If you run a modified version as a network service, you must provide the source code to users
- Commercial use requires a separate license — contact the author for licensing
See LICENSE for the full license text.
Copyright (c) 2026 Nicolas Haas