This document covers the internal technical decisions behind Bedrud’s single-binary architecture.
1. The Fiber-to-Standard Bridge
Bedrud uses Fiber for its speed, but some dependencies like Goth (OAuth) and LiveKit SDK (Twirp) expect standard Go http.ResponseWriter and http.Request.
To bridge these two worlds, Bedrud implements an Adapter Pattern in internal/handlers/auth.go:
responseWriter Adapter
type responseWriter struct {
ctx *fiber.Ctx
headers http.Header
status int
}This struct implements the http.ResponseWriter interface. When a standard library function (like Goth) calls Header().Add(), the adapter stores it in a local headers map. When WriteHeader() is called, it manually copies all headers back into the Fiber Context.
Purpose
It allows Bedrud to remain extremely fast (using Fiber) while maintaining full compatibility with the vast ecosystem of standard Go web libraries.
2. LiveKit Reverse Proxying
Bedrud avoids port management issues by routing all media signaling through its main port.
How it works:
- Detection: If
LIVEKIT_INTERNAL_HOSTpoints to127.0.0.1, Bedrud starts the internal media engine. - Mounting: It mounts a
httputil.NewSingleHostReverseProxyon the/livekitroute. - Path Stripping: A custom Director function is used to strip the
/livekitprefix so that the media server receives the request as if it were at root. - WebSocket Support: Since the proxy operates on the underlying TCP stream via
adaptor.HTTPHandler, it natively supports the WebSockets used by LiveKit for real-time signaling.
3. Storage Efficiency: Embedded Structs
Bedrud makes heavy use of GORM’s embedded tag to keep the database schema flat and optimized.
Example from models/room.go:
type Room struct {
ID string `gorm:"primaryKey"`
Settings RoomSettings `gorm:"embedded;embeddedPrefix:settings_"`
}This causes GORM to create columns like settings_allow_chat directly in the rooms table. This is faster than a JOIN and more searchable than a JSON blob.
4. Testing Infrastructure
Bedrud follows a “DB-First” testing strategy using the internal/testutil package.
SetupTestDB logic:
- Creates a unique SQLite in-memory database for every test.
- Automatically runs all migrations.
- Provides a clean slate, ensuring tests are deterministic and can run in parallel.
To run backend tests:
go test ./internal/...5. Security: Token Rotation & Revocation
Unlike simple JWT implementations, Bedrud rotates both tokens on every refresh.
- Refresh Token Reuse Detection: Once a refresh token is used to get a new pair, it is blocked.
- Cleanup: The
BlockedRefreshTokentable ensures that even if a refresh token is stolen, it cannot be used after the user has cleanly logged out or refreshed their session.