# Music Assistant API Security Model and User Roles: A Complete Technical Guide

> Explore the Music Assistant API security model and user roles. Learn about ADMIN, USER, and GUEST roles that control access to API endpoints via RBAC and runtime validation.

- Repository: [Music Assistant/server](https://github.com/music-assistant/server)
- Tags: deep-dive
- Published: 2026-06-21

---

**The Music Assistant server implements a strict role-based access control (RBAC) system with three distinct user roles—ADMIN, USER, and GUEST—that govern every API endpoint through the `@api_command` decorator and runtime validation.**

The **Music Assistant API security model user roles** architecture ensures that every authenticated request is explicitly authorized before execution. This design, implemented in the `music-assistant/server` repository, separates privileges across administrative, standard, and temporary access levels, preventing unauthorized configuration changes while enabling flexible household and guest access.

## Understanding the Role-Based Access Control (RBAC) System

The security model centers on the `UserRole` enum defined in the external `music_assistant_models` package. These roles are enforced at the API layer, not merely stored as metadata, ensuring consistent security boundaries across all transport protocols.

### The Three User Roles

The system recognizes three logical roles with distinct privilege levels:

- **ADMIN** – Full system access. Can manage users, generate tokens, modify configuration, and access all resources. Typically assigned to Home Assistant administrators and system maintainers.
- **USER** – Standard authenticated access. Can control playback, view personal data, and create short-lived tokens for regular household members.
- **GUEST** – Limited-privilege temporary access. Intended for visitors connecting via join codes (party mode), with restricted API visibility.

## How Role Enforcement Works in the API Layer

Role validation occurs at two stages: declaration via decorators and runtime verification by the request dispatcher.

### Declaring Required Roles with @api_command

API endpoints declare their security requirements using the `@api_command` decorator in [`music_assistant/helpers/api.py`](https://github.com/music-assistant/server/blob/main/music_assistant/helpers/api.py). The decorator accepts a `required_role` parameter that stores the requirement on the function object as `api_required_role`.

```python
@api_command("auth/users", required_role="admin")
async def list_users(self) -> list[User]:
    ...

```

If `required_role` is omitted, the endpoint defaults to any authenticated user. If set to `"admin"`, the request is rejected unless the caller’s `User.role` equals `UserRole.ADMIN`.

### Runtime Role Validation

During request handling, the webserver controller inspects the target handler before execution. In [`music_assistant/controllers/webserver/controller.py`](https://github.com/music-assistant/server/blob/main/music_assistant/controllers/webserver/controller.py) (line 552), the dispatcher performs the check:

```python
if handler.required_role == "admin" and user.role != UserRole.ADMIN:
    raise InsufficientPermissions(...)

```

Both WebSocket and HTTP request paths execute this identical validation, guaranteeing consistent enforcement regardless of transport method.

## Managing User Roles Programmatically

User roles are managed through the `AuthenticationManager` class in [`music_assistant/controllers/webserver/auth.py`](https://github.com/music-assistant/server/blob/main/music_assistant/controllers/webserver/auth.py).

### Creating Users with Specific Roles

The `create_user` method accepts a `role` parameter defaulting to `UserRole.USER`. Only ADMIN users can create other ADMIN users.

```python
user = await auth_manager.create_user(username="bob", role=UserRole.ADMIN)

```

*Reference:* `AuthenticationManager.create_user` – lines 300-320.

### Updating User Roles

Admins can promote or demote users via `update_user_role`. This method first verifies the caller holds the ADMIN role before applying changes.

```python
await auth_manager.update_user_role(user_id, UserRole.ADMIN, admin_user)

```

*Reference:* `AuthenticationManager.update_user_role` – lines 443-470. If the caller lacks privileges, the operation silently returns `False`.

### Guest Accounts and Join Codes

Guest accounts (`UserRole.GUEST`) obtain JWT access exclusively through join codes generated by the `generate_join_code` endpoint. The `/auth/join_codes` endpoint itself requires admin privileges, preventing arbitrary guest creation.

## Token Lifetimes and Role Implications

Token generation respects role boundaries:

- **Short-lived tokens** – Created on login (`AuthenticationManager.login`), auto-renew on use, and limited to USER or ADMIN roles. Available to all authenticated users.
- **Long-lived tokens** – Created via `create_long_lived_token` for persistent integrations (e.g., Home Assistant). Restricted to ADMIN users generating tokens for other accounts.

Both token types store the user’s role immutable; the role is checked on every request, preventing privilege escalation through token manipulation.

## Implementing Role-Based Security in Practice

### Listing Users (Admin Only)

To retrieve all system users, the client must present an admin JWT:

```python

# HTTP request

GET /api/auth/users
Authorization: Bearer <admin-jwt>

```

Server-side implementation:

```python
@api_command("auth/users", required_role="admin")
async def list_users(self) -> list[User]:
    ...

```

*Reference:* [`music_assistant/controllers/webserver/auth.py`](https://github.com/music-assistant/server/blob/main/music_assistant/controllers/webserver/auth.py) – lines 712-724.

### Creating a New Admin User

Programmatically create privileged accounts:

```python
from music_assistant_models import UserRole

# Current user must be admin

new_admin = await auth_manager.create_user(
    username="alice", 
    role=UserRole.ADMIN
)

```

*Reference:* `AuthenticationManager.create_user` – lines 300-306.

### Securing Custom Configuration Endpoints

Protect management endpoints using the decorator:

```python
@api_command("config/providers/save", required_role="admin")
async def save_provider(self, provider_id: str, config: dict) -> None:
    ...

```

*Reference:* [`music_assistant/controllers/config.py`](https://github.com/music-assistant/server/blob/main/music_assistant/controllers/config.py) – line 531.

## Summary

The Music Assistant API security model implements defense-in-depth through explicit role declarations:

- **Three distinct roles** (ADMIN, USER, GUEST) defined in the external models package govern access levels.
- **Decorator-based enforcement** via `@api_command(required_role="admin")` in [`music_assistant/helpers/api.py`](https://github.com/music-assistant/server/blob/main/music_assistant/helpers/api.py) makes security requirements declarative and auditable.
- **Runtime validation** in [`music_assistant/controllers/webserver/controller.py`](https://github.com/music-assistant/server/blob/main/music_assistant/controllers/webserver/controller.py) (line 552) ensures consistent enforcement across HTTP and WebSocket transports.
- **Privileged operations** such as user creation, role updates, and long-lived token generation are restricted to ADMIN users through explicit checks in `AuthenticationManager`.
- **Guest isolation** prevents temporary users from accessing administrative functions or creating persistent credentials.

## Frequently Asked Questions

### What are the three user roles in Music Assistant?

Music Assistant defines three roles in its RBAC system: **ADMIN** for full system control, **USER** for standard household access, and **GUEST** for temporary party-mode access. These roles are defined in the `music_assistant_models` package and enforced at the API layer through the `@api_command` decorator and runtime validation logic.

### How do I restrict an API endpoint to admin users only?

Apply the `required_role` parameter to the `@api_command` decorator in your handler method: `@api_command("endpoint/path", required_role="admin")`. The webserver controller automatically rejects requests from non-admin users by checking `user.role != UserRole.ADMIN` before executing the handler.

### Can guest users create long-lived tokens?

No. Guest accounts (`UserRole.GUEST`) cannot create long-lived tokens. Only ADMIN users can generate long-lived tokens, and they can only create them for other accounts. This restriction prevents temporary guests from maintaining persistent access to the system beyond their join code session.

### Where are role checks enforced in the codebase?

Role checks are enforced in two primary locations: the `@api_command` decorator in [`music_assistant/helpers/api.py`](https://github.com/music-assistant/server/blob/main/music_assistant/helpers/api.py) stores the requirement, and the runtime validation occurs in [`music_assistant/controllers/webserver/controller.py`](https://github.com/music-assistant/server/blob/main/music_assistant/controllers/webserver/controller.py) (line 552) where the dispatcher compares the handler's `required_role` against the authenticated user's role before execution.