Invitation Token
This token represents an invitation for a user to join a subscribable action, such as a conversation (CONV). Invitations enable controlled access to closed groups.
The invitation token must contain a subject (sub) field referencing the subscribable action and an audience (aud) field specifying the invited user. For other constraints see the Action Tokens.
Content-Addressing
This token is content-addressed using SHA-256:
- The entire JWT token (header + payload + signature) is hashed
- Action ID format:
a1~{base64_hash} - Changing any field invalidates the action_id
- See Content-Addressing & Merkle Trees for details
Immutability: Once created, an INVT token cannot be modified without changing its action ID.
Purpose
INVT tokens serve several important purposes:
- Access Control: Enable users to join closed/private groups
- Role Assignment: Pre-assign roles for invited users
- Discoverability: Notify users about groups they can join
- Subject Delivery: Include the subject action (CONV) with the invitation
Required Fields
| Field | Required | Description |
|---|---|---|
| iss | Yes | The inviter’s identity (must have moderator+ role) |
| aud | Yes | The invited user’s identity |
| sub | Yes | The action_id being invited to (a1~...) |
| t | Yes | “INVT” or “INVT:DEL” |
| c | Optional | Invitation metadata (role, message) |
Subtypes
| Subtype | Description |
|---|---|
| INVT | Create a new invitation |
| INVT:DEL | Revoke an invitation |
Content Structure
The optional content (c) field contains invitation metadata:
{
"role": "member",
"message": "Welcome to our project discussion!"
}| Property | Type | Required | Description |
|---|---|---|---|
| role | string | No | Role to assign when accepting: “observer”, “member”, “moderator”, “admin” |
| message | string | No | Optional invitation message |
Database Key
The database key for an invitation token is {type}:{sub}:{aud}
Purpose: This key ensures that only one active invitation exists per user per subject. The key components are:
{type}: “INVT” (base type){sub}: Subject ID (what they’re invited to){aud}: Audience identity (who is invited)
Example:
- Alice invites Bob to a CONV β Stored with key
INVT:a1~conv123:bob.example.com - A new invitation to the same user replaces the previous one
Permission Requirements
To create an invitation, the inviter must have appropriate permissions:
| Inviter Role | Can Invite |
|---|---|
| observer | No |
| member | No |
| moderator | Yes |
| admin | Yes |
The system validates that the inviter has at least moderator-level access to the subject action.
Subject Delivery
INVT has deliver_subject=true behavior, meaning:
- When an invitation is delivered, the subject action (e.g., CONV) is included
- The invitee receives both the INVT and the CONV token
- This allows the invitee to see conversation details before accepting
{
"token": "eyJhbGciOi...INVT_TOKEN",
"related": ["eyJhbGciOi...CONV_TOKEN"]
}Federation Flow
Sending an Invitation
Moderator creates INVT token
β
βΌ
βββββββββββββββββββββββββββββββ
β Validate permissions β
β - Check inviter has mod+ β
β - Validate subject exists β
βββββββββββββ¬ββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββ
β schedule_delivery() β
β - Deliver to invitee (aud) β
β - Include subject action β
βββββββββββββ¬ββββββββββββββββββ
β
βΌ
Invitee receives INVT + CONVAccepting an Invitation
Invitee receives INVT + CONV
β
βΌ
βββββββββββββββββββββββββββββββ
β Invitee creates SUBS token β
β - sub = CONV action_id β
β - aud = CONV owner β
β - role from INVT (optional) β
βββββββββββββ¬ββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββ
β SUBS sent to CONV owner β
βββββββββββββ¬ββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββ
β Auto-accept logic β
β - INVT exists? β Accept! β
βββββββββββββ¬ββββββββββββββββββ
β
βΌ
Invitee is now a subscriber
and receives messagesRevoking an Invitation
Moderator creates INVT:DEL token
β
βΌ
βββββββββββββββββββββββββββββββ
β Delivered to invitee β
βββββββββββββ¬ββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββ
β Original INVT marked deletedβ
βββββββββββββββββββββββββββββββ
β
βΌ
User can no longer use
invitation to subscribeInvitation Lifecycle
ββββββββββββ Create ββββββββββββ
β None ββββββββββββββββββΆβ Active β
ββββββββββββ ββββββββββββ
β
ββββββββββββββββΌβββββββββββββββ
βΌ βΌ βΌ
SUBS created INVT:DEL Expires
β β β
βΌ βΌ βΌ
ββββββββββββ ββββββββββββ ββββββββββββ
β Used β β Revoked β β Expired β
ββββββββββββ ββββββββββββ ββββββββββββExample
User @alice.cloudillo.net invites @bob.cloudillo.net to a conversation:
| Field | Value |
|---|---|
| iss | alice.cloudillo.net |
| aud | bob.cloudillo.net |
| iat | 2024-04-13T00:01:10.000Z |
| k | 20240301 |
| t | INVT |
| sub | a1~NAado5PS4j5+abYtRpBELU0e5OQ+zGf/tuuWvUwQ6PA= |
| c | {“role”: “member”, “message”: “Join our project discussion!”} |
Delivery includes:
- INVT token (the invitation)
- CONV token (the conversation being invited to)
Flow:
- Alice (moderator or admin) creates INVT for Bob
- Bob receives INVT + CONV details
- Bob creates SUBS to accept
- SUBS auto-accepted because INVT exists
- Bob now receives messages in the conversation
See Also
- Conversation Token - Subscribable group conversations
- Subscription Token - Accepting invitations by subscribing
- Message Token - Messages in the conversation
- Federation Architecture - How invitations are delivered