Roles & permissions
WatchTower15 uses role-based access control (RBAC) scoped to each organisation. Permissions are granular and per-module; roles bundle permissions; users hold one or more roles. Everything is enforced server-side on every request, so the UI and the API share exactly one source of truth.
The model
Section titled “The model”- Organisation-scoped. Roles and assignments belong to an organisation. A role in one organisation has no effect in another — a user can be an admin in one org and read-only in another with no bleed-through.
- Permissions are the atoms. Each permission is a
module.tierstring. Tiers areview,edit(create + update), anddelete. - Roles bundle permissions. A role is a named set of permissions.
- Users can hold multiple roles. Effective access is the union of their roles’ permissions.
Built-in roles
Section titled “Built-in roles”Every organisation is seeded with two system roles that cannot be renamed or deleted:
| Role | Access |
|---|---|
| Admin | Full access. Enforcement grants admins everything via a fast super-user bypass, so admins are never blocked by a missing individual permission. |
| Regular Users | Read-only starter role: servers.view, server_profiles.view, domains.view, database.view, logs.view, services.view. New members default to this role on invitation. |
You can create any number of custom roles — e.g. a “Domain manager” with the domain and DNS permissions, or an “On-call” role with incident and policy access — and assign several to a user as needed.
The permission catalogue
Section titled “The permission catalogue”WatchTower15 ships a catalogue of granular permissions across every functional module:
| Module | Permissions |
|---|---|
| Servers | servers.view · servers.edit · servers.delete |
| Server profiles | server_profiles.view · server_profiles.edit · server_profiles.delete |
| Domains | domains.view · domains.edit · domains.delete |
| Services | services.view · services.edit · services.delete |
| Logs | logs.view |
| Database | database.view |
| Incidents | incidents.view · incidents.edit · incidents.delete |
| Alarm policies | policies.view · policies.edit · policies.delete |
| Notification channels | channels.view · channels.edit · channels.delete |
| Contact groups | contact_groups.view · contact_groups.edit · contact_groups.delete |
| Tags | tags.view · tags.edit · tags.delete |
| Users | users.view · users.edit · users.delete |
| Settings | settings.view · settings.edit |
| Billing | billing.view · billing.edit |
| Audit | audit.view |
edit covers both creating and updating; delete is separated so you can grant
change-without-destroy access — a common requirement for junior operators.
How enforcement works
Section titled “How enforcement works”On every authenticated request, WatchTower15:
- Resolves the caller’s organisation context (the team the request targets).
- Grants immediately if the caller holds the Admin role.
- Otherwise checks whether any of the caller’s roles include the specific
permission the endpoint requires (e.g.
domains.editto update a domain). - Returns 403 Forbidden if not.
Because the check is per-endpoint and server-side, there’s no way to reach a protected action by calling the API directly — the browser and the API are held to the same permission.
Working with roles
Section titled “Working with roles”- Invite a member — they start as Regular Users (read-only).
- Assign roles — give them one or more roles; access is the union.
- Create custom roles — scope a role to exactly the modules a job needs.
- Delete guardrails — system roles can’t be removed, and a role still assigned to members can’t be deleted until it’s unassigned.
Related
Section titled “Related”- Audit trail — who did what, gated by
audit.view. - Single sign-on — how members authenticate.