Invitations
The invitation system in Waldur provides a mechanism for inviting users to join organizations (customers), projects, or other scoped resources with specific roles. The system supports two main invitation types: individual invitations and group invitations, with different workflows and approval mechanisms.
Architecture Overview
The invitation system is built around three core models in waldur_core.users.models
:
- BaseInvitation: Abstract base class providing common fields and functionality
- Invitation: Individual invitations for specific users with email-based delivery
- GroupInvitation: Template-based invitations that can be used by multiple users matching specific criteria
- PermissionRequest: Approval workflow for group invitation requests
Invitation Types
Individual Invitations
Individual invitations are sent to specific email addresses and provide a direct mechanism to grant users access to resources.
Key Features
- Email-based delivery: Invitations are sent to specific email addresses
- Civil number validation: Optional civil number matching for enhanced security
- State management: Full lifecycle tracking with states like pending, accepted, canceled, expired
- Execution tracking: Background processing with error handling and retry capabilities
- Expiration handling: Automatic expiration based on configurable timeouts
- Webhook support: External system integration for invitation delivery
State Flow
stateDiagram-v2
[*] --> PENDING: Create invitation
[*] --> REQUESTED: Staff approval required
[*] --> PENDING_PROJECT: Project not active yet
REQUESTED --> PENDING: Staff approves
REQUESTED --> REJECTED: Staff rejects
PENDING_PROJECT --> PENDING: Project becomes active
PENDING --> ACCEPTED: User accepts
PENDING --> CANCELED: Creator cancels
PENDING --> EXPIRED: Timeout reached
CANCELED --> PENDING: Resend invitation
EXPIRED --> PENDING: Resend invitation
ACCEPTED --> [*]
REJECTED --> [*]
Group Invitations
Group invitations provide template-based access that multiple users can request to join, with an approval workflow. They support both private invitations (visible only to authenticated users with appropriate permissions) and public invitations (visible to all users including unauthenticated ones).
Key Features
- Pattern-based matching: Users can request access if they match email patterns or affiliations
- Approval workflow: Requests go through a review process before granting access
- Project creation option: Can automatically create projects instead of granting customer-level access
- Role mapping: Support for different roles at customer and project levels
- Template-based naming: Configurable project name templates for auto-created projects
- Public visibility: Public invitations can be viewed and requested by unauthenticated users
Workflow
sequenceDiagram
participant U as User
participant GI as GroupInvitation
participant PR as PermissionRequest
participant A as Approver
participant S as System
U->>GI: Submit request
GI->>PR: Create PermissionRequest
PR->>A: Notify approvers
A->>PR: Approve/Reject
alt Approved & auto_create_project
PR->>S: Create project
S->>U: Grant project permission
else Approved & normal
PR->>S: Grant scope permission
end
PR->>U: Notify result
Public Group Invitations
Public group invitations are a special type of group invitation that can be viewed and requested by unauthenticated users. They are designed for open enrollment scenarios where organizations want to allow external users to request access to projects.
Key Characteristics
- Unauthenticated visibility: Listed in public API endpoints without authentication
- Staff-only creation: Only staff users can create and manage public invitations
- Project-level access only: Public invitations can only grant project-level roles, not customer-level roles
- Automatic project creation: All public invitations must use the auto-create project feature
- Enhanced security: Authentication is still required for submitting actual access requests
Constraints and Validation
- Staff authorization: Only
is_staff=True
users can create public group invitations - Auto-creation required: Public invitations must have
auto_create_project=True
- Project roles only: Public invitations can only use roles starting with "PROJECT." (e.g.,
PROJECT.MANAGER
,PROJECT.ADMIN
) - No customer-level access: Cannot grant customer-level roles like
CUSTOMER.OWNER
orCUSTOMER.SUPPORT
Use Cases
- Open research projects: Universities allowing external researchers to request project access
- Community initiatives: Organizations providing project spaces for community members
- Partner collaborations: Companies offering project access to external partners
- Educational platforms: Schools providing project environments for students
API Endpoints
Individual Invitations (/api/user-invitations/
)
POST /api/user-invitations/
- Create invitationGET /api/user-invitations/
- List invitationsGET /api/user-invitations/{uuid}/
- Retrieve invitation detailsPOST /api/user-invitations/{uuid}/send/
- Resend invitationPOST /api/user-invitations/{uuid}/cancel/
- Cancel invitationPOST /api/user-invitations/{uuid}/accept/
- Accept invitation (authenticated)POST /api/user-invitations/{uuid}/delete/
- Delete invitation (staff only)POST /api/user-invitations/approve/
- Approve invitation (token-based)POST /api/user-invitations/reject/
- Reject invitation (token-based)POST /api/user-invitations/{uuid}/check/
- Check invitation validity (unauthenticated)GET /api/user-invitations/{uuid}/details/
- Get invitation details for display
Group Invitations (/api/user-group-invitations/
)
POST /api/user-group-invitations/
- Create group invitation (authentication required)GET /api/user-group-invitations/
- List group invitations (public invitations visible without authentication)GET /api/user-group-invitations/{uuid}/
- Retrieve group invitation (public invitations accessible without authentication)POST /api/user-group-invitations/{uuid}/cancel/
- Cancel group invitation (authentication required)POST /api/user-group-invitations/{uuid}/submit_request/
- Submit access request (authentication required)GET /api/user-group-invitations/{uuid}/projects/
- List available projects (authentication required)
Permission Requests (/api/user-permission-requests/
)
GET /api/user-permission-requests/
- List permission requestsGET /api/user-permission-requests/{uuid}/
- Retrieve permission requestPOST /api/user-permission-requests/{uuid}/approve/
- Approve requestPOST /api/user-permission-requests/{uuid}/reject/
- Reject request
Model Fields and Relationships
BaseInvitation (Abstract)
1 2 3 4 5 6 7 |
|
Invitation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
GroupInvitation
1 2 3 4 5 6 7 8 9 10 11 12 |
|
PermissionRequest
1 2 3 4 5 6 7 8 9 |
|
Permission System Integration
Access Control
Invitation management permissions are controlled through:
- Staff privileges: Staff users can manage all invitations
- Scope-based permissions: Users with CREATE permissions on scopes can manage invitations
- Customer-level access: Customer owners can manage invitations for their resources
- Hierarchical permissions: Customer permissions apply to contained projects
Permission Checks
The system uses can_manage_invitation_with()
utility (src/waldur_core/users/utils.py:179
) for authorization:
1 2 3 4 5 6 7 8 9 10 11 |
|
Filtering and Visibility
- InvitationFilterBackend: Filters invitations based on user permissions
- GroupInvitationFilterBackend: Controls group invitation visibility, allows public invitations for unauthenticated users
- PendingInvitationFilter: Filters invitations user can accept
- VisibleInvitationFilter: Controls invitation detail visibility
Background Processing
Celery Tasks
The invitation system uses several background tasks (src/waldur_core/users/tasks.py
):
Core Processing Tasks
process_invitation
: Main processing entry pointsend_invitation_created
: Send invitation emails/webhooksget_or_create_user
: Create user accounts for invitationssend_invitation_requested
: Notify staff of invitation requests
Maintenance Tasks
cancel_expired_invitations
: Clean up expired invitationscancel_expired_group_invitations
: Clean up expired group invitationsprocess_pending_project_invitations
: Activate invitations for started projectssend_reminder_for_pending_invitations
: Send reminder emails
Notification Tasks
send_invitation_rejected
: Notify creators of rejectionssend_mail_notification_about_permission_request_has_been_submitted
: Notify approvers
Execution States
Individual invitations track background processing with FSM states:
SCHEDULED
: Initial state, queued for processingPROCESSING
: Currently being processedOK
: Successfully processedERRED
: Processing failed with error details
Error Handling
The system provides robust error tracking:
- Error messages: Human-readable error descriptions
- Error tracebacks: Full stack traces for debugging
- Retry mechanisms: Failed invitations can be resent
- Webhook failover: Falls back to email if webhooks fail
Configuration Options
Core Settings (WALDUR_CORE
)
1 2 3 4 5 6 7 8 9 10 11 |
|
Constance Settings
1 2 3 |
|
Webhook Integration
1 2 3 4 5 6 |
|
Email Templates
The system uses several email templates (waldur_core/users/templates/
):
invitation_created
- New invitation notificationinvitation_requested
- Staff approval requestinvitation_rejected
- Rejection notificationinvitation_expired
- Expiration notificationinvitation_approved
- Auto-created user credentialspermission_request_submitted
- Permission request notification
Advanced Features
Project Auto-Creation
Group invitations can automatically create projects instead of granting customer-level access:
1 2 3 4 5 6 7 8 9 |
|
Pattern Matching
Group invitations support sophisticated user matching:
1 2 3 4 5 6 7 |
|
Token-Based Security
Staff approval uses cryptographically signed tokens:
1 2 3 4 5 6 |
|
Security Considerations
Civil Number Validation
When civil_number
is provided:
- Only users with matching civil numbers can accept invitations
- Provides additional security layer for sensitive resources
- Empty civil numbers allow any user to accept
Email Validation
Multiple levels of email validation:
- Loose matching (default): Case-insensitive email comparison
- Strict validation: Exact email matching when
ENABLE_STRICT_CHECK_ACCEPTING_INVITATION=True
- Pattern matching: Group invitations validate against email patterns
Token Security
- Cryptographic signing: Uses Django's TimestampSigner
- Time-based expiration: Tokens expire after configurable period
- Payload validation: Validates UUID formats and user/invitation existence
- State verification: Ensures invitations are in correct state for operation
Permission Isolation
- Scope-based filtering: Users only see invitations they can manage
- Role validation: Ensures roles match scope content types, with additional constraints for public invitations
- Customer isolation: Prevents cross-customer invitation access
- Public invitation constraints: Public invitations restricted to project-level roles only
Best Practices
Creating Invitations
- Validate scope-role compatibility before creating invitations
- Set appropriate expiration times based on use case sensitivity
- Use civil numbers for high-security invitations
- Include helpful extra_invitation_text for user context
Group Invitation Setup
- Design clear email patterns that match intended user base
- Choose appropriate role mappings for auto-created projects
- Set meaningful project name templates for clarity
- Configure proper approval workflows with designated approvers
Public Invitation Management
- Restrict to staff users only - Only allow trusted staff to create public invitations
- Use project-level roles exclusively - Never grant customer-level access through public invitations
- Design clear project naming - Use descriptive templates since multiple projects may be created
- Monitor request volume - Public invitations may generate high volumes of access requests
- Set up proper approval processes - Ensure adequate staffing to handle public invitation approvals
Error Handling
- Monitor execution states for processing failures
- Set up alerts for invitation processing errors
- Provide clear error messages to users and administrators
- Implement retry strategies for transient failures
Performance Optimization
- Use bulk operations for large invitation batches
- Index frequently queried fields (email, state, customer)
- Archive old invitations to prevent table bloat
- Monitor background task queues for processing bottlenecks
Troubleshooting
Common Issues
- Invitations stuck in PROCESSING state
- Check Celery task processing
- Review error messages in invitation records
-
Verify SMTP/webhook configuration
-
Users can't accept invitations
- Verify email matching settings
- Check civil number requirements
-
Confirm invitation hasn't expired
-
Permission denied errors
- Validate user has CREATE permissions on scope
- Check customer-level permissions for hierarchical access
-
Confirm role is compatible with scope type
-
Group invitation requests not working
- Verify email patterns match user addresses
- Check affiliation matching logic
- Confirm invitation is still active
Debugging Tools
- Admin interface: View invitation details and states
- Celery monitoring: Track background task execution
- Logging: Enable debug logging for invitation processing
- API introspection: Use
/api/user-invitations/{uuid}/details/
for status checking
Integration Examples
Basic Individual Invitation
1 2 3 4 5 6 7 8 9 10 11 |
|
Group Invitation with Auto-Project
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Public Group Invitation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Webhook Integration
1 2 3 4 5 6 7 8 9 10 |
|
This invitation system provides flexible, secure, and scalable user onboarding capabilities that integrate seamlessly with Waldur's permission and organizational structure.