Skip to content

Invite User to Tenant

Implement OAM::IAM::0006::0004.UC from Identity and Access Management Behaviors.

  1. Any user of a tenant can send an invitation.
  2. The system sends the invitation email automatically when an invitation is created, refreshed, or reopened.
  3. An invitation inbox is out of scope. Invitees manage invitations in their email inbox.
  4. Batch operations (creation, management) of invitations is out-of-scope.
  5. Email can be disabled per deployment. In that mode, a no-op sender reports success so invitation workflows can run without contacting the mail server.
  1. Invite a user (identified by email) that does not have an invitation yet or only has archived invitations to join the tenant. The caller may supply custom message parameters for the configured template.
  2. View all invitations sorted by creation date (descending), filterable by status (PENDING, ACCEPTED, EXPIRED, REJECTED, CANCELLED, ARCHIVED, PENDING_FAILED) with pagination.
  3. Cancel an invitation in PENDING status.
  4. Reopen an invitation in CANCELLED, EXPIRED, or REJECTED status, returning it to PENDING.
  5. Archive an invitation in PENDING, ACCEPTED, CANCELLED, EXPIRED, or REJECTED, moving it to ARCHIVED.
  6. Refresh an invitation in PENDING status, updating its invitationDate to the current date and time and its expirationDate to the current date and time plus the configured expiration interval.
  7. Retry a failed delivery by moving a PENDING_FAILED invitation to PENDING.
  1. Accept the invitation (joining the tenant).
  2. Reject the invitation.
  1. Provide the invitation as a link encoding the invitation identifier and (for convenience) the invitee’s email.
  2. Render and send an email whenever an invitation enters PENDING, including creation, refresh, reopen, and retry.
  3. Protect the system-owned invitation_ template parameters from caller overrides.
  4. If rendering, message construction, or sending fails, transition the invitation to PENDING_FAILED; persist the sender outcome in messageStatus when one is available.
  5. Collect metrics for template renders and successful and failed email sends.
  6. Validate the invitation:
    • Exists
    • Is in PENDING status
    • Is addressed to the logged-in user

Accounts selects its sender at startup. It constructs the configured System Email sender only when features.email=true and an email {} configuration is present; otherwise it uses NoOpEmail.

With NoOpEmail, the service follows the same render-and-send control flow but receives a synthetic successful outcome with message ID noop. This keeps the invitation in PENDING without contacting Postmark.

PlantUML diagram

All entities will include the following information:

Field NameTypeDescriptionNotes
idUUIDA unique identifier for the entity in the systemGenerated by the system. Not editable
rIdUUIDA unique identifier for a particular version of the entityNot editable
createdByTextThe identification of the user that created the entityNot Editable
createdAtTimeCoordinatesThe time when the entity was created, specifying when it was created in the real world and when it was recorded by the system.
authorTextThe identification of the users that made the latest change (version) of the entity.
asOfTimeCoordinatesThe time when the latest change was made (effective and recorded).

In addition, Invitations belong to a tenant, so they will also have:

Field NameTypeDescriptionNotes
tenantIdUUIDThe identification of the tenant that owns this entity.
FieldTypeDefaultEditableDescription
invitationDateDateCreated atNoDate invitation was created
expirationDateDateinvitationDate + configurable intervalNoExpiry date
statusEnumPENDINGNoCurrent lifecycle status
inviteeStringBlankYesEmail of invited user
inviterIdUUIDCurrent user idNoID of inviting user
tenantIdUUIDCurrent tenant idNoTenant being invited to
messageParametersMap<String, String>Empty mapNoCaller-supplied values used when rendering the invitation email. Keys beginning with invitation_ are removed on creation.
messageStatusStringEmpty stringNoDiagnostic sender outcome for a failed delivery, when available. Cleared before a new transition attempt.

The state diagram annotates those states and transitions that are triggered by the invitee or the system events. All other transitions (e.g. cancel, archive) are triggered by a user in the inviting tenant.

These operations (refresh, cancel, …) are implemented as update of the status field on the invitation entity, as described by the transition diagram below.

PlantUML diagram

  1. Inviter creates an invitation via Company Settings > Users, optionally supplying template parameters.
  2. The system registers the invitation as PENDING, generates its URL and protected template parameters, renders the configured system template, and sends the email.
  3. If delivery fails, the system records a new PENDING_FAILED version. A tenant user can retry it by requesting PENDING; the retry refreshes the invitation and expiration timestamps and sends again.
  4. Invitee opens the link from the email, then signs in or creates an account if needed.
  5. System validates the invitation.
  6. On accept:
    • invitation transitions to ACCEPTED.
    • a new AgentFor is created linking the invitee’s UserAccount to the tenant;
    • the invitee’s role in the tenant is set to USER;
    • invitee’s active tenant is set to the new tenant.
  7. On reject:
    • invitation transitions to REJECTED.

Every transition to PENDING attempts to send an email. This includes a refresh (PENDINGPENDING), a reopen from CANCELLED, EXPIRED, or REJECTED, and a retry from PENDING_FAILED. The existing no-op interval still suppresses a refresh requested too soon; because no state transition occurs, no email is sent.

PlantUML diagram