User and admin roles

How Cascadia Marquee models access: platform account types, Cascadia staff roles, client organization roles, and brand-scoped access.

User and admin roles

Access in Cascadia Marquee comes from a few separate systems that stack together. This document explains each one, who gets what, and how they interact, so anyone deciding "what should this person be able to do?" has a single reference.

There are three layers:

  1. Account type (platform-wide): are you Cascadia staff, a client, or a free-scan lead?
  2. Staff role (Cascadia staff only): which parts of the admin workspace a staff member can open.
  3. Organization role and brand access (clients): what a person can do inside their own company's dashboard, and which brands they can see.

A single person has one account type, may have staff roles (if they are staff), and has one organization role per company they belong to.

For the technically curious: account types live in src/lib/app-role.ts, staff roles in src/lib/staff-tags.ts and src/lib/staff-permissions.ts, and client organization access in src/lib/client-brand-scope.ts and src/lib/client-team-api.ts.

Layer 1: Account types

The account type is the top-level identity for a user across the whole platform. It is stored on the user (not per organization) and decides which workspace they land in after signing in.

Account typeStored slugWho it is forPrimary workspace
Super Adminsuper_adminCascadia platform operators/admin
EmployeeteamCascadia staff/admin (gated by staff role)
ContractorcontractorExternal contractors working with Cascadia/admin (gated by staff role)
ClientclientCustomers managing their own company/dashboard
Scan leadscan_leadFree-scan funnel sign-upsLimited dashboard

Notes:

  • Super Admin always has full platform access and bypasses every permission check. A user is Super Admin if their account type is super_admin or their email is listed in ADMIN_EMAILS.
  • Employee and Contractor are both "staff," but they see nothing in the admin workspace until they are given one or more staff roles (see Layer 2). The two account types are treated the same for permission purposes; the label just records employment relationship.
  • Client users get the full client dashboard for the organizations they belong to. What they can do there depends on Layer 3.
  • Scan lead is a lightweight account created through the free accessibility scan funnel. It has limited dashboard access and is meant to convert into a full client later.

Historic rows may store admin as the account type; that value is normalized to super_admin on read. Never write new rows with admin.

Layer 2: Cascadia staff roles

Employees and Contractors do not automatically see the admin workspace. Access is granted by assigning staff roles (also called staff tags). Each role maps to a set of admin permissions, and a staff member's effective permissions are the union of all their roles.

Super Admins skip this entirely: they receive every permission regardless of roles.

Staff roles

RoleSlugGrants access to
SalessalesClients (read), Users (read), Team (read)
DeveloperdeveloperProjects (read/manage), Accessibility (read/manage), Documents (read)
DesigndesignProjects (read), Clients (read), Documents (read)
UX/UIux_uiProjects (read), Accessibility (read), Documents (read)
Account Manageraccount_managerClients (read), Users (read), Documents (read/manage), Projects (read)
Project Managerproject_managerProjects (read/manage), Documents (read/manage), Clients (read)
AccountingaccountingBilling (read/manage), Documents (read)
ITitSettings (read), Users (read), Team (read)
MarketingmarketingAnalytics (read), Accessibility (read), Clients (read), Documents (read)

Every role includes admin.access (the ability to open the admin workspace at all). A staff member with no roles cannot enter /admin.

How permissions gate the admin workspace

Admin navigation and routes are gated by permission keys. For example, opening /admin/billing requires admin.billing.read, and /admin/projects requires admin.projects.read. A staff member only sees the nav items their roles unlock.

Permission keys follow a admin.<area>.<action> shape, where action is usually read or manage (manage implies write). The full list lives in src/lib/staff-permissions.ts (STAFF_PERMISSIONS), and the nav mapping is ADMIN_NAV_ITEM_PERMISSIONS.

Layer 3: Client organization roles

Inside a client company (an "organization"), each member has an organization role. This is separate from their account type: a person is a client account type, and within their company they might be an owner, admin, member, or brand manager.

Organization roleWhat it means
OwnerFull control of the company, including deleting the organization.
AdminSame day-to-day powers as Owner in this app (manage people, settings, all brands).
MemberParticipates in the company. Can be company-wide or limited to specific brands.
Brand ManagerA brand-limited member who can also invite and remove members for the brands they manage.

Owner vs Admin

Owner and Admin are intentionally equivalent for everyday work: both can update the organization, manage members and invitations, manage brands, and approve join requests. Both are always company-wide (they see every brand).

The differences are safeguards, not capabilities:

  • The UI labels them "Company owner" and "Company admin."
  • The organization must keep at least one Owner or Admin; the last Owner cannot be demoted to member or removed unless another admin exists.
  • New organizations default the first member to Owner.

Member

A Member participates in the company but cannot manage the team, brands, or company settings. A Member's reach depends on brand access (below): they are either company-wide (see everything) or brand-limited (see only assigned brands).

Billing and revenue remain company-wide only, so brand-limited members never see them.

Brand Manager

A Brand Manager is a Member who has been marked as brand admin on at least one of their assigned brands. It is not a separate stored role; it is a Member with brand-admin rights on one or more brands. This lets a company delegate team management for a brand without granting company-wide control.

A Brand Manager can:

  • View only the brands they are assigned to (like any brand-limited member).
  • Invite new members to the brands they manage.
  • Remove members who belong to the brands they manage.
  • Cancel pending member invitations scoped to their brands.

A Brand Manager cannot:

  • See or manage brands they are not assigned to.
  • Invite or create Owners or Admins.
  • Remove or edit Owners or Admins.
  • Change organization roles or edit another member's brand scope.
  • Access company-wide settings, brands administration, or billing.

Brand access scope

Independent of the organization role, every member has a brand access scope that controls which brand data they can see. This is what enforces "you can only view brands you are assigned to."

ScopeWho has itWhat they see
Company-wideOwners and Admins, or any Member with no brand assignmentsAll brands and org-level data
Brand-limitedMembers assigned to one or more specific brandsOnly their assigned brands' data

Key rules:

  • Owners and Admins are always company-wide and cannot be limited to specific brands.
  • A Member with zero brand assignments is treated as company-wide; a Member with one or more brand assignments is brand-limited.
  • Brand-limited members are filtered on projects, tasks, documents, websites, contacts, and brand lists to only their assigned brands.
  • The brand admin flag on a brand assignment is what turns a brand-limited member into a Brand Manager for that brand.

How brand access is assigned

Brand access is set when inviting a member or editing an existing member:

  • Access scope: "Full company" (company-wide) or "Specific brands" (brand-limited).
  • Brand picker: which brands the member can access.
  • Brand admin: an optional per-brand checkbox that promotes the member to Brand Manager for that brand.

When someone is invited with brand scope, the selection is stored on the invitation and copied to their membership when they accept, so the role activates automatically.

Admins inviting from the admin workspace can also set brand scope: for an existing organization with brands, a member invite can be limited to specific brands rather than the whole company.

Putting it together

A few worked examples:

  • A Cascadia developer: account type Employee, staff role Developer. Sees Projects and Accessibility in the admin workspace, but not Billing or Settings.
  • A client company owner: account type Client, organization role Owner. Full control of their company and all its brands; can manage team and billing.
  • A brand lead at a multi-brand client: account type Client, organization role Member, brand-limited to "Brand A," with brand admin on "Brand A." This is a Brand Manager: they see only Brand A, and can invite or remove Brand A members, but cannot touch owners, admins, or other brands.
  • A single-brand client contributor: account type Client, organization role Member, brand-limited with no brand admin. They see their brand's data but cannot manage the team.

Quick reference

CapabilitySuper AdminStaff (by role)Owner / AdminBrand ManagerMember
Admin workspace (/admin)FullPer staff roleNoNoNo
Manage own company teamn/an/aYesTheir brands onlyNo
Invite Owners / Adminsn/an/aYesNoNo
Remove Owners / Adminsn/an/aYes (with guards)NoNo
Edit member roles / brand scopen/an/aYesNoNo
View all brandsYesPer staff roleYesNoNo
View assigned brands onlyn/an/an/aYesYes (if brand-limited)
Company settings and billingYesPer staff roleYesNoNo