Skip to content

Workspaces

Copy page

A Workspace is the middle tier of Plan Desk’s tenancy model: it sits between an organization and its projects. A workspace is implemented as a native better-auth team (team / teamMember) — there is no parallel custom table.

Org asyncdot better-auth organization (tenant)
└ Workspace Fiji TV better-auth TEAM (members + the agent/repo boundary)
└ Project OTT Mobile, QA & Bug Fixes domain board (canvas, tasks, docs) — projects.workspace_id

One concept solves four real shapes at once:

  • Agent isolation. Bind a repo to one workspace and its agent gets a key scoped to that workspace’s projects and nothing else in the org. A stray key on a client engagement can never read your other clients’ boards.
  • Multi-project folders. A single client or product often carries several projects (one repo per service, or a portfolio of initiatives). A workspace groups them so connect --workspace binds the whole set at once.
  • Client engagements. A workspace is the natural unit of a client engagement: invite the client’s people into it, and (optionally) share the entire workspace with the client over the portal.
  • Member scoping. Membership and invitations are workspace-scoped. A teammate belongs to the workspaces they need, not the whole org.
  • Every project belongs to exactly one workspace (projects.workspace_id, NOT NULL).
  • Each organization has a default workspace named General. Projects created without an explicit workspace land there, so nothing ever lives “outside” a workspace.
  • A workspace has members (better-auth teamMember). A user can belong to multiple workspaces in the same org.
  • Org roles (owner / admin / member) still govern who can create workspaces and invite. Custom per-workspace role ladders are future.

An agent key carries one of three scopes (see Architecture → Auth and tenancy):

TierMetadataReach
Owner{ orgId, kind: 'owner' }Every workspace and project in the org
Workspace{ orgId, teamId }All projects in one workspace, nothing else in the org
Project{ orgId, projectId }That one project

The owner key (from plandesk login) mints workspace- and project-scoped keys. Agents never receive the owner key.

A workspace-scoped key can reach only its workspace’s projects. A request for a project outside the scoped workspace returns the same 404 as a non-existent project — there is no existence leak, no distinguishable “forbidden vs. missing.” Owner keys skip the guard.

This is enforced in the service layer (assertProjectInWorkspace), extending the existing projectId → 404 project guard. It applies to every read path: REST, MCP, and the client portal.

EntityLives underNotes
Organization(root tenant)better-auth organization; billing/identity boundary
WorkspaceOrganizationbetter-auth team; the agent/repo boundary
ProjectWorkspaceprojects.workspace_id; one workspace each
MemberWorkspacebetter-auth teamMember; a user may join many workspaces in an org
InvitationWorkspaceinvite email + role to a workspace; accepting joins the team
Client shareWorkspaceshare an entire workspace → portal shows all its projects
Agent keyWorkspace/orgworkspace- or project-scoped; owner keys span the org
CommandPurpose
plandesk workspace create <name> [--to <org>]Create a workspace in an org (local by default; --to hosted)
plandesk workspace list [--to <org>]List workspaces in an org
plandesk connect [--workspace <name>] [--to <org>]Bind a repo to a workspace; mint a workspace-scoped key (hosted)
plandesk go-online [--to <org>] [--all | --workspace <name>...]Push local workspaces + projects up to a hosted org
plandesk legacy-upgrade [--into-workspace <name>]Import an old board into a workspace

See CLI reference for flags. Connecting a repo to a workspace writes a plandesk-connect-v2 config — see plandesk connect.

The web UI is workspace-aware: a nav switcher (Org ▸ Workspace ▸ Projects, backed by better-auth’s active team) filters the projects home to the active workspace. From there you can:

  • create / rename / delete workspaces,
  • move a project between workspaces,
  • manage workspace members (add / remove / list),
  • invite a person to a workspace (link-only, owner/admin-gated), and
  • share a whole workspace with a client over the portal.

For the collaboration model — invitations, client shares, submissions — see Collaboration & sharing.