Skip to main content
Zyra Zyra
Features Pricing Security FAQ Documentation
Sign In Sign up for free

Documentation › User Guides › Organizations › Stage 3 › Invite your team

Invite your team

Chapter 5 · about 10 minutes to read

You can run the platform solo, but you don't want to. This chapter covers the four moving pieces of multi-user Zyra: invitations, roles, removal, and the audit log that proves who did what.

Time: about 10 minutes. Prerequisites: you are an Org Admin or Super Admin.

The three roles

Zyra ships with three built-in invitation types (from backend/app/models/user_invitation.py, InvitationType enum):

  • super_admin — platform-wide administrator. Owns the global account, can manage every organisation, sees every invoice. Hand out sparingly.
  • org_admin — full read/write inside one organisation. Can invite, remove, and reconfigure billing, devices, Virtual Servers, and SLA agreements.
  • org_member — day-to-day operator inside one organisation. Can deploy and manage Virtual Servers, read metrics and logs, submit jobs. Cannot change billing, invite or remove users, or edit org-level settings.

Custom roles on top of these three are supported via the RBAC service (backend/app/services/rbac/).

Permission matrix (built-in roles)

Capabilitysuper_adminorg_adminorg_member
Sign inyesyesyes
Deploy / start / stop Virtual Serversyesyesyes
View VS metrics + logsyesyesyes
Enroll / remove Compute Nodesyesyesno
Invite usersyesyesno
Remove usersyesyesno
Edit org profile + billingyesyesno
View invoicesyesyesno
Configure SLA agreementsyesyesno
View audit logyesyesno
Manage other organisationsyesnono

[VERIFY: confirm org_member can view invoices vs strictly admin-only — RBAC permission_engine has fine-grained checks not all front-end-exposed at launch]

Step 1 — Send an invitation

Open Settings → Team → Invite user. Fields: Email (becomes login ID), Name, Role (org_admin or org_member; super_admin is invited from the platform admin console), Organisation (pre-filled).

Submit. Zyra generates a 256-bit token (secrets.token_urlsafe(32)), records a user_invitations row with status = pending, sends the magic-link email, and sets expires_at = now + 72 hours per UserInvitation.default_expiry.

[SCREENSHOT: Invite-user form with role dropdown showing org_admin and org_member]

The 72-hour expiry

This is hard-wired in the model. Invitations expire 72 hours after creation — not 7 days, not a week. The 72-hour window is a SOC 2 / ISO 27001 control: short-lived credentials reduce blast radius if an invite email is intercepted.

If a teammate misses the window, resend from Settings → Team → Pending → Resend. That generates a fresh token and resets the clock; the old token is revoked.

Step 2 — The invitee accepts

The recipient clicks the link, lands on the acceptance page, sets their own password (Zyra never stores it before they type it), and is redirected to sign in. On the database side, the invitation flips status: pending → accepted, accepted_at is timestamped, and user_id is set to the new users.id.

Step 3 — Remove a user

  • Revoke an invitation that hasn't been accepted: Settings → Team → Pending → Revoke. The row's status flips to revoked; the token stops working immediately.
  • Deactivate a user who already signed up: Settings → Team → Active → Remove. The user's is_active flag flips to false; their session is invalidated on next request; their Virtual Servers are NOT auto-terminated — reassign or terminate them explicitly.

[VERIFY: confirm UI exposes a single "Remove" button or splits revoke-pending from deactivate-active]

Custom roles

If the three built-in roles don't fit your structure, org_admin users can build custom roles inside their org: Settings → Roles → New role, name it (billing_only, read_only_auditor, etc.), attach individual permissions from the permissions table, assign users via Team → Edit user → Role. Custom roles live in custom_roles per organisation; permissions attach via role_permissions with allow/deny effects evaluated by permission_engine.py.

Step 4 — The audit log

Every state-changing action writes to the audit log. Open Settings → Audit Log. Filters: Actor, Action (user.invited, user.removed, vs.created, vs.terminated, invoice.generated...), Time window, Resource type / ID. Audit retention is 365 days. [VERIFY: confirm export-to-CSV button is exposed in audit log UI at launch]

What just happened

You know the three built-in roles, the 72-hour invitation expiry, the difference between revoking and deactivating, and where the paper trail lives.

Troubleshooting

  • Invitee never received the email. Check spam first. If clean, Pending → Resend. If still nothing, the SMTP relay may be paused.
  • Invitee says "this link has expired" within 72 hours. The token was already used or revoked. Resend.
  • org_member can see something they shouldn't. Open Settings → Roles → org_member → Permissions; the RBAC engine is the source of truth. Check custom roles too.
  • Audit log is empty for an action I know happened. Service-account actions log with the service principal; filter by Actor type = service.

← Previous: Optimize your costs

Next: Understand billing and invoices →

Last reviewed: 2026-05-21

© 2026 Zyra. All rights reserved. | Privacy Policy | Terms of Service | Careers