Skip to content

Admin — Humans

The Humans page is the tenant’s user directory. It lists every person (and every service account) who has access to the tenant, their role, and their current status. From here operators invite new members, see who’s pending acceptance, and manage the access that underpins every other admin feature.

Route: /humans
File: apps/admin/src/routes/_authed/_tenant/humans/index.tsx

A searchable DataTable with columns:

ColumnNotes
NameAvatar with initials + display name
EmailPrimary identifier
RoleBadge — Owner / Editor / Viewer
StatusBadge — Active / Pending
JoinedRelative timestamp (for active members) or “Invited” (for pending)

A Invite Member button in the header opens the InviteMemberDialog.

Three roles cover the common cases:

  • Owner — full access to every admin surface. Can invite and remove other members, change roles, delete the tenant configuration, and touch billing
  • Editor — can create and edit agents, templates, skills, connectors, scheduled jobs, routines, and webhooks. Cannot manage members or tenant settings
  • Viewer — read-only access to all admin surfaces. Useful for auditors or stakeholders who need visibility but not authority

Role checks are enforced server-side. Even if the UI shows a button, the underlying mutation is rejected if the caller’s role doesn’t allow it.

The InviteMemberDialog captures:

  • Email — Cognito is the identity provider, so this is the email the user will authenticate with
  • Role — Owner / Editor / Viewer
  • Optional message — a short note included in the invitation email

Submitting the dialog fires a CreateTenantMemberInvitationMutation (likely routed through GraphQL). The backend:

  1. Creates a pending row in tenant_members with status: pending
  2. Issues a Cognito invitation or sends a SES email with a signup / acceptance link
  3. Returns the new row to the UI

The UI refetches TenantMembersListQuery after the mutation resolves and the new pending member appears in the list.

From the invitee’s side:

  1. They receive the invitation email
  2. They click the link, land at the admin app’s /sign-in page
  3. They authenticate with the temporary password or via Google SSO
  4. The tenant pre-signup Lambda links them to the tenant and marks their tenant_members row as active
  5. They land in the authenticated layout as a member of the tenant

The admin app’s user list flips the row from pending to active on the next refetch.

The tenant_members table also carries a principal_type column that distinguishes:

  • user — a human member
  • service_account — a programmatic account used by BYOB agents and internal services

The Humans page only shows user rows. Service accounts are managed through Agent Invites and the credential vault, not through Humans.

Query / MutationPurpose
TenantMembersListQuery($tenantId)List members
CreateTenantMemberInvitationMutationInvite a new member

Role changes and member removal likely flow through additional mutations not directly visible in the Humans route — they may be exposed through a detail page not yet shipped or through a dialog on row click.

tenant_members — Aurora table with:

  • id, tenant_id, principal_type (user / service_account)
  • email, name
  • role (owner / editor / viewer)
  • status (active / pending)
  • created_at, updated_at

The row is the source of truth for access control. Postgres row-level security policies on every other tenant table reference the current user’s tenant membership to enforce isolation.

  1. Click Invite Member
  2. Enter their email
  3. Choose Editor (most common for day-to-day operators) or Viewer (for read-only audit access)
  4. Submit
  5. The new member appears with status: pending
  6. They receive the Cognito invitation email
  7. After they sign in, their status flips to active
  1. Find the member in the list
  2. (Supported through the admin API; UI surface in the current release is limited)
  • No role editing UI in the current list. Row-level role changes need a detail page or API call.
  • No bulk invite. Members are invited one at a time.
  • No custom roles. The three built-in roles are the only options; there’s no per-capability permission grid.
  • No delegated administration. Owners have full authority; there’s no “can invite but can’t edit” middle ground.