Bedrud supports multiple authentication methods.

JWT (JSON Web Tokens)

Bedrud uses JWT for session management. On login, the server returns two tokens:

  1. Access Token: Short-lived (e.g., 1 hour). Used to access protected API endpoints.
  2. Refresh Token: Long-lived (e.g., 30 days). Used to get a new Access Token without logging in again.

The backend validates these tokens in the internal/middleware/auth.go file.

Token Management & Security

1. Token Pair Strategy (Rotation)

Bedrud uses a secure token rotation strategy. When a user authenticates, they receive:

  • Access Token: Signed with HS256, contains user ID, name, and permissions. Valid for a short duration (configured via tokenDuration).
  • Refresh Token: A separate long-lived token.

Rotation: When the Access Token expires, the client sends the Refresh Token to /api/auth/refresh. The server then issues a brand new pair of tokens and updates the stored refresh token in the database. This limits the window of opportunity even if a token is stolen.

2. Token Revocation (Blacklisting)

To support secure logout, Bedrud implements a Token Blacklist.

  • When a user logs out, their current Refresh Token is added to the blocked_refresh_tokens table.
  • Before refreshing any session, the server checks this table. If a token is blocked, the request is rejected immediately.
  • A background task (Scheduler) is designed to clean up these blocked tokens once they naturally expire.

3. JWT Claims Structure

The tokens carry metadata that allows the backend and frontend to make quick decisions without database hits:

{
  "userId": "uuid-string",
  "email": "user@example.com",
  "name": "Display Name",
  "accesses": ["user", "admin"],
  "exp": 123456789,
  "iat": 123456780
}

Authentication Methods

1. Local Email & Password

  • Passwords are hashed using bcrypt - never stored as plain text.
  • When you register, a new User record is created in the database.

2. Social Login (OAuth2)

Bedrud uses the Goth library to support:

  • Google
  • GitHub
  • Twitter

You can enable these by filling in the auth: section in your config.yaml with your Client ID and API Secret.

3. Passkeys (WebAuthn/FIDO2)

Bedrud supports passwordless authentication via the FIDO2 standard (WebAuthn).

  • Registration Ceremony:
    1. Begin: The server generates a cryptographically secure Challenge and stores it in the user’s session.
    2. Finish: The client’s authenticator (e.g., TouchID, YubiKey) signs the challenge. The server verifies the attestation, extracts the Public Key, and saves it in the passkeys table.
  • Authentication Ceremony:
    1. Begin: The server issues a new challenge.
    2. Finish: The client signs the challenge with their private key. The server retrieves the Public Key from the database, verifies the signature, and checks the Sign Counter.
  • Security: The matching of the Counter field prevents Replay Attacks. If the authenticator’s counter is not higher than the stored counter, the login is rejected.

4. Guest Login

Allows users to join a meeting instantly with just a name. The server creates a temporary user record with the role guest.

Email Verification

When requireEmailVerification: true in config, local (non-OAuth) registration and login require email confirmation:

  • Registration creates the user but sets EmailVerifiedAt to nil. User cannot log in until verified.
  • Login returns 403 with {"requiresVerification": true} for unverified accounts.
  • Resend via POST /api/auth/verify/resend — rate-limited by verificationEmailCooldownMins and a separate rate limit bucket (authResendMaxRequests).
  • Auto-cleanup deletes unverified accounts after unverifiedAccountTTLHours (default 48h, 0 to disable).
  • Email change triggers a new verification flow. User stays logged in; new token issued.

Guest users are exempt — they have no email.

Password Reset

Password reset flow (requires SMTP):

  1. POST /api/auth/forgot-password with {"email": "..."} — server sends reset link to email
  2. POST /api/auth/reset-password with {"token": "...", "newPassword": "..."} — sets new password

The reset token TTL is controlled by resetTokenTTLHours (default 1 hour). The forgot-password endpoint shares the auth rate limit bucket.

Cooldown & Rate Limiting

Bedrud uses four separate rate limit buckets:

BucketEndpointsDefaultWindow
Authlogin, register, refresh, passkey, forgot-password1060s
Guestguest-login560s
APIgeneral API3060s
Resendverify/resend360s

Bucket set to 0 = disabled. All limits per remote IP. Exceeded requests return 429 Too Many Requests with Retry-After header.

Interoperability & CORS

Bedrud is designed to be accessible from multiple origins, which is crucial for development (React dev server) and production (different subdomains).

  • CORS Policy: Defined in config.yaml. It supports AllowCredentials: true, which is required for the session cookies used during OAuth and Passkey ceremonies.
  • Allowed Origins: By default, it allows the server’s own domain and localhost:3000 (the React dev server port).

User Roles (Access Control)

Each user has an accesses array that can contain multiple access levels simultaneously. The JWT claims include the full accesses array, allowing middleware to check granular permissions.

Access Levels

Access LevelScopeGrants
superadminSystem-wideFull access to the admin dashboard (/dashboard/admin), all admin API endpoints (/api/admin/*), user management, room management, system settings, invite tokens. Acts as a global bypass for all room moderation actions. Protected by RequireAccess("superadmin") middleware.
adminDefined, not enforcedAvailable in the accesses array but currently not used by any middleware. Informational only. Reserved for future role-based access control features.
moderatorRoom-scopedCan moderate a specific room: block chat, deafen/undeafen participants, spotlight, stop screen share, disable video. Promoted by the room creator or a superadmin during a call via PromoteParticipant. Checked via isRoomModerator() helper.
userStandardDefault for all registrations. Can create rooms, join rooms, manage profile, and manage own passkeys. Protected by Protected() middleware.
guestLimitedTemporary user for joining public rooms via guest login. Cannot create rooms or access protected features.

Role Hierarchy

superadmin > admin > moderator > user > guest

A superadmin can perform any moderation action in any room without being promoted as a room moderator. Room creators are automatically room admins and can promote participants to moderator.

Assigning Roles

Roles are managed through multiple channels:

  • CLI: bedrud user create (creates as user), bedrud user promote (adds superadmin), bedrud user demote (removes superadmin)
  • Admin Dashboard: User detail page has promote/demote buttons
  • Admin API: PUT /api/admin/users/:id/accesses with desired accesses array
  • In-Meeting: Room creator can promote participants to room-level moderator

Note: There is no API endpoint or web UI to create the first superadmin. After installation, you must use the CLI (bedrud user create + bedrud user promote) to bootstrap initial admin access. This is a deliberate security measure.