Roles & Permissions in TuneCamp β
This document describes the different roles within a TuneCamp instance, their capabilities, and their associated security constraints.
TuneCamp uses a Role-Based Access Control (RBAC) system to ensure that each user can only operate within the scope of their assigned role.
1. Instance Owner (Root Admin) β
The Instance Owner (or Root Admin) is the primary system administrator. This typically corresponds to the first user created (ID 1). It has the highest level of authority.
Exclusive Capabilities: β
- Global Site Management: Modify the site name, description, public URL, logos, and background images.
- Web3 Configuration: Set wallet addresses for USDC/USDT payments and NFT contracts.
- Full User Management:
- Create and manage all roles.
- Reset passwords for any user.
- Delete accounts (except their own).
- System Identity: Access to cryptographic keys and server-level maintenance tasks.
2. Manager (Full Admin) β
The Manager has broad administrative powers to oversee the community and content without full server control.
Capabilities: β
- User Monitoring: Can view the list of registered users.
- Federated Network: Manage ActivityPub follows and synchronization.
- Content Moderation: Manage posts and releases across the instance. Can review, resolve, or dismiss copyright and content reports from the Reports dashboard (Admin β Reports).
- Artist Support: Can operate as any artist they are assigned to.
Release Reports (copyright & content) β
Any logged-in user can report a release via POST /api/releases/:id/report. The payload should include a reason string (e.g. "copyright", "inappropriate").
Managers and Root Admins see pending reports at Admin β Reports (GET /api/admin/reports). Each report shows the release, the reporting user, and the reason. To resolve or dismiss a report: DELETE /api/admin/reports/:id.
Reports are also surfaced in the admin panel UI β a badge on the Reports menu item counts unresolved items.
3. Curator (Super User / Library Management) β
The Curator is a specialized role focused on library quality and content organization.
Capabilities: β
- Global Visibility: Can view all content (including private/drafts) to assist in curation.
- Library Management: Can edit metadata, cover art, and organization for their own tracks and albums. Editing content owned by other users requires Manager/Root Admin (
MANAGE_ALL_CONTENT); a Curator has onlyMANAGE_PRIVATE_LIBRARY, which grants global visibility but not cross-owner write. - Maintenance: Help maintain the library structure and correct errors.
Note: the Curator's edit rights are owner-scoped, enforced per-item by
VisibilityGuardian.canManageItem. The global-visibility capability lets them see everything to triage and report, but modifying another owner's content is reserved for Managers and above.
4. Listener (Standard User) β
The Listener is the base role for users who consume music and interact with the platform.
Capabilities: β
- Listening & Collection: Stream music via the web player or Subsonic-compatible apps, purchase content, and manage favorites.
- Social Interaction: Create playlists, comment, follow artists, and manage their own profile.
5. Listener-Artist (Listener with an artist profile) β
A Listener-Artist is a standard user-role account that has been linked to an artist profile by an admin. The role stays user β no promotion to Curator happens β but the artist-profile link grants publishing rights via canPublishContent. This is the state a listener enters after their artist request is approved.
Additional capabilities over plain Listener: β
- Upload tracks and create albums/releases under their own artist profile.
- ActivityPub posts (release announcements) under their artist identity.
- Storage quota assigned at approval time (configurable via Admin β Settings β
listenerSelfPublishQuota).
What they still cannot do: β
- Edit or manage other users' content (no library-wide write access).
- Access the admin panel.
- Sell content (blocked at checkout server-side) β see
can_sellbelow.
Paths to become a Listener-Artist: β
- Admin-initiated: Admin links an artist profile to an existing user manually (Admin β Users β Edit β Artist Profile).
- Self-request: The listener requests one from Profile β Settings β Become an Artist. The admin approves from the Users panel (
POST /api/admin/system/users/:id/approve-artist): an artist profile is created under their username,can_sellis set tofalse, and the storage quota is applied. The role staysuser.
6. The can_sell flag (per-artist sales gate) β
can_sell is a flag on the artist profile (not on the user account). It controls whether buyers can complete a purchase for that artist's content. It is independent of the user's role.
can_sell | Effect |
|---|---|
0 (default after approval) | Stripe checkout, crypto on-ramp, and NFT mint are refused server-side for this artist's items. The Buy button may be hidden client-side, but the server enforces the block regardless. |
1 | Full sales enabled β Stripe (direct charge to artist's connected account if stripe_account_id is set, otherwise instance account), crypto, and NFT mint all work. |
How can_sell gets enabled:
- Artist with a linked user account: toggle "Sales enabled" in Admin β Users β Edit User (the artist section of that dialog). The control in Admin β Library β Artists β Edit is read-only for linked artists ("Managed from the linked user's Edit User dialog").
- Artist without a linked user account (library-only): toggle "Sales enabled" in Admin β Library β Artists β Edit.
- Automatic via Stripe Connect: When an artist completes Stripe Connect onboarding and
charges_enabledbecomestrueon their connected account, theaccount.updatedwebhook automatically setscan_sell = 1. If Stripe later disables charges, it reverts to0.
Permission Matrix (Summary) β
| Capability | Root Admin | Manager | Curator | Listener-Artist | Listener |
|---|---|---|---|---|---|
| Modify Site Settings | β | β | β | β | β |
| Manage Users | β | β (view) | β | β | β |
| Edit Others' Content | β | β | β (own only) | β | β |
| Upload Music / Create Releases | β | β | β (with artist link) | β (own profile only) | β |
| Sell Music / Store Assets | β | β
(with can_sell) | β
(with artist link + can_sell) | β
(with can_sell) | β |
| Social Posts (ActivityPub) | β | β | β (with artist link) | β (own profile only) | β |
| Access Server Keys | β | β | β | β | β |
| Manage Federation | β | β | β | β | β |
Internal role names (for debugging / DB queries) β
| UI name | DB role value | UserRole enum |
|---|---|---|
| Root Admin / Instance Owner | root_admin | ROOT_ADMIN |
| Manager | admin | ADMIN |
| Curator | super_user | SUPER_USER |
| Listener-Artist | user + artist_id IS NOT NULL | NORMAL_USER |
| Listener | user | NORMAL_USER |
| Unauthenticated | β | GUEST |
First Login: Setup Wizard β
When a user logs in and their account password is the temporary sentinel tunecamp, the web app blocks access behind a setup wizard until the password is changed. The backend signals this via the mustChangePassword flag returned by POST /api/auth/login (computed by isDefaultPassword in auth.service.ts, which checks for the tunecamp sentinel).
Note: the bootstrap admin created on first run uses
admin/admin(orTUNECAMP_ADMIN_USER/TUNECAMP_ADMIN_PASS), nottunecampβ so that account is not forced through the wizard automatically; change its password manually after the first login. The wizard fires for accounts an admin has reset totunecamp(see below).
What the wizard shows depends on the role:
- Instance Owner (Root Admin) β two steps:
- Security β replace the default password.
- Identity β set the instance's site name and description. This step can be skipped and configured later under Admin Settings.
- All other roles (Manager, Curator, Listener) β a single Security step to replace the temporary password. The Identity step is not shown because site settings are exclusive to the Instance Owner (see Permission Matrix above).
A Root Admin can force any user through the password step at their next login by resetting that user's password to tunecamp (PUT /api/admin/system/users/:id/password).
Security Verification β
TuneCamp implements these controls at the API level:
- JWT Middleware: Every authenticated request verifies the role (
isAdmin) and identity (userId). - Content Ownership: Modification APIs (
PUT,DELETE) verify thatowner_id(referencingadmin.id) matches the requester'suserId, unless the requester is an administrator. The system includes self-healing maintenance to ensure all content is correctly owned by a valid administrator. - SSRF Protection: Network operations (ActivityPub follow) are protected against SSRF attacks via URL validation.
- Sanitization: File names and metadata are sanitized to prevent Path Traversal and XSS attacks.
- Quota Check: During upload, the user's available disk space is dynamically verified before accepting files.