All Docs
FeaturesPosibl Life & Gym AppUpdated March 13, 2026

User Roles & Permissions

User Roles & Permissions

The platform uses a five-tier role model to control what each user can see and do. Roles are tenant-scoped, meaning a user's permissions are always evaluated within the context of a specific gym — not globally.


The Five Roles

platform_owner

The highest privilege level. A platform owner has unrestricted access to all tenants, system configuration, and administrative tooling. This role is reserved for the SaaS operator.

gym_owner

Full administrative control within a single gym tenant. A gym owner can manage coaches, personal trainers, and members, configure the gym's settings, access business intelligence dashboards, and manage the storefront.

coach

Operational access within their assigned gym. A coach can author and deliver programming, manage class schedules, view and annotate member sessions, and access the movement library. A coach cannot access data from any other gym.

personal_trainer

Focused access scoped to their assigned clients within a gym. A personal trainer can create individual programmes, monitor client progress and recovery, and manage one-to-one sessions. They do not have access to gym-wide configuration or other trainers' clients.

member

Self-service access to personal data only. A member can view their daily training schedule, log sessions, track progress, and interact with community features. They cannot read or modify data belonging to other members.


Tenant Scoping

Roles are always evaluated within a tenant boundary.

  • A user may hold different roles at different gyms (e.g. coach at Gym A and member at Gym B).
  • The permission system resolves the correct role for every request based on the active tenant context.
  • Cross-tenant data access is blocked at the tRPC procedure level — there is no way for a request authenticated against Gym A to read Gym B data, regardless of role.

How Permissions Are Enforced

Permission guards are applied per tRPC procedure. This means:

  1. Every API call carries the caller's session, which includes their resolved role for the active tenant.
  2. Before any procedure logic runs, a guard checks that the caller's role satisfies the minimum required role for that procedure.
  3. If the check fails, the procedure returns an UNAUTHORIZED or FORBIDDEN error immediately — no data is touched.

This approach ensures that permission enforcement is co-located with the business logic it protects, rather than relying solely on upstream middleware or route guards.


Role Hierarchy Summary

platform_owner
  └── gym_owner
        └── coach
              └── personal_trainer
                    └── member

Higher-tier roles generally inherit the capabilities of roles below them within their scope, but procedures can also be gated to a specific role only (e.g. a procedure that only a gym_owner should call, not a coach).


Error Responses

When a permission check fails, the tRPC procedure returns a structured error:

{
  "error": {
    "code": "FORBIDDEN",
    "message": "You do not have permission to perform this action."
  }
}

Callers should handle UNAUTHORIZED (no valid session) and FORBIDDEN (valid session, insufficient role) as distinct cases.


Related