Authorization

This guide describes the username/password authorization system with per-queue ACL in VibeMQ.

Overview

VibeMQ supports two authentication modes:

When authorization is enabled via UseAuthorization(), the broker requires username/password credentials for authentication. Without any auth configured, the broker accepts all connections anonymously.

Quick Start

var broker = BrokerBuilder.Create()
    .UsePort(2925)
    .UseAuthorization(o => {
        o.SuperuserUsername = "admin";
        o.SuperuserPassword = Environment.GetEnvironmentVariable("VIBEMQ_ADMIN_PASS");
        o.DatabasePath = "/var/lib/vibemq/auth.db";
    })
    .Build();

Connect the client:

await using var client = await VibeMQClient.ConnectAsync(
    "localhost",
    2925,
    new ClientOptions {
        Username = "alice",
        Password = "alice-secret"
    }
);

Configuration

AuthorizationOptions

public sealed class AuthorizationOptions {
    public string SuperuserUsername { get; set; } = "vibemq";
    public string SuperuserPassword { get; set; } = "";
    public string DatabasePath { get; set; } = "auth.db";
}

Property

Default

Description

SuperuserUsername

"vibemq"

Username for the built-in superuser account.

SuperuserPassword

""

Password for the superuser. Must be set before the first run. If empty and the account does not exist yet, the broker throws on startup.

DatabasePath

"auth.db"

Path to the SQLite file that stores users and ACL entries. Separate from the message storage database.

Warning

The superuser account is seeded automatically on the first broker start when the database is empty. If SuperuserPassword is empty at that point, the broker will throw and refuse to start. Store the password securely (e.g. environment variable, secrets manager).

Superuser

The superuser account is a special account that bypasses all permission checks. It is the only account that can execute admin commands (create/delete users, grant/revoke permissions).

Properties of the superuser:

  • Always authorized for every queue and every operation.

  • Cannot be deleted via the AdminDeleteUser command (lockout protection).

  • Password can be changed by any authenticated superuser via AdminChangePassword.

Users and Passwords

Passwords are hashed using BCrypt with a work factor of 12. The hash is stored in the auth.db SQLite database.

Creating users (admin protocol command):

Command: AdminCreateUser
Headers:
  username  — new user's username
  password  — plaintext password (hashed server-side)

Changing passwords:

Command: AdminChangePassword
Headers:
  username    — target user (superuser can change any; regular user can only change own)
  newPassword — new plaintext password

Deleting users:

Command: AdminDeleteUser
Headers:
  username — user to delete (cannot delete superuser accounts)

Per-Queue ACL

Every user has a list of permission entries. Each entry associates a queue pattern (glob) with a set of allowed operations.

QueueOperation

public enum QueueOperation {
    Publish,
    Subscribe,
    CreateQueue,
    DeleteQueue,
    PurgeQueue,
    GetQueueInfo,
    ListQueues,
}

Glob Patterns

Queue patterns use * as a wildcard that matches any sequence of characters, including dots. Matching is case-insensitive.

Pattern

Matches

*

Any queue name.

orders.*

orders.new, orders.shipped, orders.test.deep, …

*.events

orders.events, payments.events, …

tenant.alice.*

Any queue under the tenant.alice. namespace.

invoices

Exactly invoices (case-insensitive).

Union semantics: when a user has multiple matching entries, the effective permission is the union of all matched operations.

Granting permissions (admin protocol command):

Command: AdminGrantPermission
Headers:
  username      — target user
  queuePattern  — glob pattern (e.g. "orders.*")
  operations    — comma-separated operations (e.g. "Publish,Subscribe")

Revoking permissions:

Command: AdminRevokePermission
Headers:
  username      — target user
  queuePattern  — pattern to revoke (must match an existing entry exactly)

Permission Caching

When a client connects and authenticates successfully, the server loads all permission entries for that user and stores them in the session. All subsequent authorization checks use this in-memory cache — no database I/O per request.

Implication: if you grant or revoke permissions for a connected user, the change takes effect only after the user reconnects.

Admin Protocol Commands

Admin commands are available only to superuser sessions.

Command

Description

AdminCreateUser

Create a new user with a BCrypt-hashed password.

AdminDeleteUser

Delete a user (superusers cannot be deleted).

AdminChangePassword

Change a user’s password (superuser: any user; regular: own only).

AdminGrantPermission

Add a permission entry (queue pattern + operations) for a user.

AdminRevokePermission

Remove a specific permission entry for a user.

AdminListUsers

List all users (returns username, isSuperuser, createdAt).

AdminGetUserPermissions

List all ACL entries for a specific user.

ListQueues Filtering

When authorization is enabled, ListQueues returns only the queues that match at least one of the user’s permission patterns with the ListQueues operation. Superusers always see all queues.

Security Recommendations

Warning

Follow these guidelines for production deployments:

  • Store SuperuserPassword in an environment variable or secrets manager; never hard-code it.

  • Use a dedicated DatabasePath outside the application directory with appropriate file system permissions (readable only by the broker process).

  • Combine authorization with TLS (Server Setup) so credentials are never transmitted in cleartext.

  • Apply the principle of least privilege: grant each user only the operations and queue patterns they actually need.

  • Rotate passwords regularly using AdminChangePassword.

Examples

Multi-tenant Setup

// Server
var broker = BrokerBuilder.Create()
    .UsePort(2925)
    .UseAuthorization(o => {
        o.SuperuserPassword = Environment.GetEnvironmentVariable("VIBEMQ_ADMIN_PASS");
        o.DatabasePath = "/var/lib/vibemq/auth.db";
    })
    .Build();

After startup, create tenants via admin commands (pseudocode — replace with a management tool or admin client that sends raw protocol messages):

AdminCreateUser: username=alice, password=<secret>
AdminGrantPermission: username=alice, queuePattern=tenant.alice.*, operations=Publish,Subscribe,CreateQueue,GetQueueInfo,ListQueues

AdminCreateUser: username=bob, password=<secret>
AdminGrantPermission: username=bob, queuePattern=tenant.bob.*, operations=Publish,Subscribe,CreateQueue,GetQueueInfo,ListQueues

Connect as tenant:

await using var client = await VibeMQClient.ConnectAsync(
    "localhost", 2925,
    new ClientOptions { Username = "alice", Password = "alice-secret" }
);

// alice can only access tenant.alice.* queues
await client.PublishAsync("tenant.alice.orders", new { OrderId = 1 });

Worker Pool (Publish-only)

AdminCreateUser: username=worker-1, password=<secret>
AdminGrantPermission: username=worker-1, queuePattern=jobs.*, operations=Publish
await using var worker = await VibeMQClient.ConnectAsync(
    "localhost", 2925,
    new ClientOptions { Username = "worker-1", Password = "..." }
);

await worker.PublishAsync("jobs.process", new { TaskId = "abc" });

Next Steps

  • Server Setup — TLS encryption for secure credential transmission

  • Configuration — full BrokerOptions and ClientOptions reference

  • Features — all broker features overview