6.2.2.14 OrganizationInvitation
6.2.2.14.1 Purpose¶
How a person joins an Organization, the way Google Workspace or GitHub do it: a member invites an e-mail address with a role and, if they like, groups; the person accepts, signs in or signs up, and only then do their Person and their direct membership exist. Nobody becomes a member without accepting, an invitation that is never accepted leaves no personal record behind, and every Person stays complete. The link carries a secret whose hash alone is stored; it expires after seven days.
6.2.2.14.2 Questions it answers¶
- Who was invited to this Organization, by whom, with which role?
- Which invitations are still pending, and when do they expire?
- When did a person accept, and as which user?
6.2.2.14.3 Fields¶
| Field | Type | Cardinality | Description |
|---|---|---|---|
id |
string (uuid) |
1..1 |
Key. |
organization |
Organization | 1..1 |
|
email |
string (regex) |
1..1 |
Compared without case. Accepting requires a signed-in Person whose verified e-mail is this one. |
role |
OrganizationRoleAccessControl | 1..1 |
The inviter must be allowed to give it (OrganizationRoleAccessControl.priority), checked again when the invitation is accepted. Never Owner or Sync Client (OrganizationPredefinedRoleEnum). |
groups |
UserGroup | 0..* |
Groups of the same Organization the person joins on acceptance, within the same priority rule. |
invited_by |
User | 1..1 |
|
token_hash |
string |
1..1 |
Unique. SHA-256 of the secret in the invitation link; the secret itself is never stored. |
expires_at |
datetime |
1..1 |
Seven days after it was sent; a resent invitation gets a new link and a new expiry. |
status |
enum | 1..1 |
Values: pending, accepted, revoked, expired. Default: pending. |
accepted_by |
Person | 0..1 |
|
accepted_at |
datetime |
0..1 |
|
revoked_by |
User | 0..1 |
|
revoked_at |
datetime |
0..1 |
|
created_at |
datetime |
1..1 |
|
updated_at |
datetime |
1..1 |
6.2.2.14.4 Relationships¶
References
OrganizationInvitation.organization→ Organization (1..1)OrganizationInvitation.role→ OrganizationRoleAccessControl (1..1)OrganizationInvitation.groups→ UserGroup (0..*)OrganizationInvitation.invited_by→ User (1..1)OrganizationInvitation.accepted_by→ Person (0..1)OrganizationInvitation.revoked_by→ User (0..1)
6.2.2.14.5 Rules & constraints¶
- How a person joins an Organization, as in Google Workspace or GitHub: a member with
access.members.manageinvites an e-mail address; the person accepts, signs in or signs up, and only then do their. - Person and their DirectMembership exist. Nobody becomes a member without accepting, an invitation that is never accepted leaves no Person behind, and every Person stays complete (Person).
(organization, email)is unique among pending invitations. An invitation cannot be accepted while the Organization is not active; it is revoked when the inviter's role no longer allows it, and when the Organization closes (OrganizationClosure).- The check runs again at acceptance, for the role and for every group's roles; a group archived since the invitation is skipped, and the person joins the others.
- A person who is already a member gets no invitation; their role is changed through their membership.
- ServiceAccounts are never invited: they are created by their Organization (ServiceAccount).
- Rows whose status is not pending are deleted 90 days after they ended; the audit keeps who invited whom.