Platform & Partners

Platform & Tenant Admin

How the three-tier Teamcast hierarchy works — from Teamcast itself down to partner platforms and their customer workspaces.

Teamcast is a multi-tenant platform. Every organisation that uses it lives in one of three tiers, each with its own role, dashboard, and permission set. There are no hardcoded role checks in the UI — every feature gate reads the permissions[] array returned by GET /auth/me.

Three-tier hierarchy

Teamcast Platform (Super Admin — wildcard *) │ ├── Partner Platform A (Platform Admin — e.g. LinkedIn) │ ├── Customer Workspace 1 (Tenant Admin — e.g. Liha) │ └── Customer Workspace 2 (Tenant Admin — e.g. Parent WorkSpace) │ └── Partner Platform B (Platform Admin) └── Customer Workspace 3
TierRole discriminatorDefault dashboardPermission model
Teamcast (Super Admin)super_admin/adminWildcard — passes every permission check
Partner Platform (Platform Admin)platform_admin/adminCurated platform:* + apikey:* / webhook:*
Customer Workspace (Tenant Admin)tenant_user/recruiterStandard workspace permissions scoped to their tenant

How permissions resolve

After login, GET /auth/me returns the authenticated user's full permissions[] array. The frontend evaluates every feature gate against this array — never against a role string. Super admins receive a single * entry that passes all checks. Platform admins receive a curated set of platform:* keys and selected workspace-level keys.

The roleDiscriminator field on the user object is used only for the initial dashboard redirect (platform_admin /admin, tenant_user /recruiter). All subsequent feature gates use permissions[] directly.
HelperWhere usedWhat it checks
hasPlatformPermission(permissions, key)Platform Console gatesReturns true if permissions contains * or the exact key
hasPermission(me, key)Workspace-level gatesHandles * wildcard; checks the key in me.data.permissions

Backend security model

Every platform-admin endpoint on tc-core is protected by two guards applied at the controller class level:

GuardWhat it enforces
PermissionsGuardReads the @RequirePermissions(key) decorator on the handler and rejects if the caller lacks it
PlatformGuardRejects if the caller's tenant does not have isPlatform = true in Postgres

For cross-tenant operations (e.g. a platform admin writing an API key for a customer tenant), controllers additionally call an assertAccess(actor, tenantId) helper that allows the call only when the target tenant's parentPlatformId matches the actor's own tenantId. Super admins (wildcard) bypass this check.

Was this page helpful?