OfferingUser States and Management
OfferingUser represents a user account created for a specific marketplace offering. It tracks two independent state dimensions:
- Lifecycle state (
state): A finite state machine (FSM) tracking where the account is in the provisioning/deletion workflow. - Runtime state (
runtime_state): An operational flag the service provider can set freely to signal whether the user currently has access to the service (e.g. TOU accepted, account linked). This is independent of lifecycle and can be updated at any time except when the account isDELETED.
Lifecycle States
OfferingUser has the following lifecycle states:
| State | Description |
|---|---|
CREATION_REQUESTED |
Initial state when user account creation is requested |
CREATING |
Account is being created by the service provider |
PENDING_ACCOUNT_LINKING |
Waiting for user to link their existing account |
PENDING_ADDITIONAL_VALIDATION |
Requires additional validation from service provider |
OK |
Account is active and ready to use |
DELETION_REQUESTED |
Account deletion has been requested |
DELETING |
Account is being deleted |
DELETED |
Account has been successfully deleted |
ERROR_CREATING |
An error occurred during account creation |
ERROR_DELETING |
An error occurred during account deletion |
State Transitions
stateDiagram-v2
[*] --> CREATION_REQUESTED : Account requested
CREATION_REQUESTED --> CREATING : begin_creating()
CREATION_REQUESTED --> OK : set_ok()
CREATING --> PENDING_ACCOUNT_LINKING : set_pending_account_linking()
CREATING --> PENDING_ADDITIONAL_VALIDATION : set_pending_additional_validation()
CREATING --> OK : set_ok()
PENDING_ACCOUNT_LINKING --> OK : set_validation_complete()
PENDING_ACCOUNT_LINKING --> PENDING_ADDITIONAL_VALIDATION : set_pending_additional_validation()
PENDING_ADDITIONAL_VALIDATION --> OK : set_validation_complete()
PENDING_ADDITIONAL_VALIDATION --> PENDING_ACCOUNT_LINKING : set_pending_account_linking()
OK --> DELETION_REQUESTED : request_deletion()
DELETION_REQUESTED --> DELETING : set_deleting()
DELETING --> DELETED : set_deleted()
%% Error state transitions during creation flow
CREATION_REQUESTED --> ERROR_CREATING : set_error_creating()
CREATING --> ERROR_CREATING : set_error_creating()
PENDING_ACCOUNT_LINKING --> ERROR_CREATING : set_error_creating()
PENDING_ADDITIONAL_VALIDATION --> ERROR_CREATING : set_error_creating()
%% Error state transitions during deletion flow
DELETION_REQUESTED --> ERROR_DELETING : set_error_deleting()
DELETING --> ERROR_DELETING : set_error_deleting()
%% Recovery from error states
ERROR_CREATING --> CREATING : begin_creating()
ERROR_CREATING --> OK : set_ok()
ERROR_CREATING --> PENDING_ACCOUNT_LINKING : set_pending_account_linking()
ERROR_CREATING --> PENDING_ADDITIONAL_VALIDATION : set_pending_additional_validation()
ERROR_DELETING --> DELETING : set_deleting()
ERROR_DELETING --> OK : set_ok()
%% Legacy error transitions (backward compatibility)
CREATION_REQUESTED --> ERROR_CREATING : set_error() [legacy]
CREATING --> ERROR_CREATING : set_error() [legacy]
PENDING_ACCOUNT_LINKING --> ERROR_CREATING : set_error() [legacy]
PENDING_ADDITIONAL_VALIDATION --> ERROR_CREATING : set_error() [legacy]
OK --> ERROR_CREATING : set_error() [legacy]
DELETION_REQUESTED --> ERROR_CREATING : set_error() [legacy]
DELETING --> ERROR_CREATING : set_error() [legacy]
REST API Endpoints
State Transition Actions
All state transition endpoints require UPDATE_OFFERING_USER permission and are accessed via POST to the offering user detail endpoint with the action suffix.
Base URL: /api/marketplace-offering-users/{uuid}/
Set Pending Additional Validation
1 2 3 4 5 6 7 | |
Valid transitions from: CREATING, ERROR_CREATING, PENDING_ACCOUNT_LINKING
Set Pending Account Linking
1 2 3 4 5 6 7 | |
Valid transitions from: CREATING, ERROR_CREATING, PENDING_ADDITIONAL_VALIDATION
Set Validation Complete
1 | |
Valid transitions from: PENDING_ADDITIONAL_VALIDATION, PENDING_ACCOUNT_LINKING
Note: This action clears both the service_provider_comment and service_provider_comment_url fields.
Set Error Creating
1 | |
Valid transitions from: CREATION_REQUESTED, CREATING, PENDING_ACCOUNT_LINKING, PENDING_ADDITIONAL_VALIDATION
Sets the user account to error state during the creation process. Used when creation operations fail.
Set Error Deleting
1 | |
Valid transitions from: DELETION_REQUESTED, DELETING
Sets the user account to error state during the deletion process. Used when deletion operations fail.
Begin Creating
1 | |
Valid transitions from: CREATION_REQUESTED, ERROR_CREATING
Initiates the account creation process. Can be used to retry creation after an error.
Request Deletion
1 | |
Valid transitions from: OK
Initiates the account deletion process. Moves the user from active status to deletion requested.
Set Deleting
1 | |
Valid transitions from: DELETION_REQUESTED, ERROR_DELETING
Begins the account deletion process. Can be used to retry deletion after an error.
Set Deleted
1 | |
Valid transitions from: DELETING
Marks the user account as successfully deleted. This is the final state for successful account deletion.
Service Provider Comment Management
Update Comments
Service providers can directly update comment fields without changing the user's state:
1 2 3 4 5 6 7 | |
Permissions: Requires UPDATE_OFFERING_USER permission on the offering's customer.
Valid states: All states except DELETED
Both fields are optional - you can update just the comment, just the URL, or both.
Update Runtime State
1 2 3 4 5 6 7 8 | |
service_provider_comment and service_provider_comment_url are optional. Omit them to leave existing comments unchanged, or pass empty strings to clear them.
Where runtime_state is one of:
| Value | Meaning |
|---|---|
Active |
User can access the service normally |
Pending account linking |
User must link an external account (e.g. MyAccessID) before access is granted |
Pending additional validation |
User must complete additional validation (e.g. accept new Terms of Use) |
Valid transitions: Any → Any (no FSM). Can be set regardless of lifecycle state, except when lifecycle is DELETED.
Permissions: Requires UPDATE_OFFERING_USER permission on the offering's customer.
Key use case — backfill sync: When a service provider syncs an external system (e.g. Puhuri), they can update runtime_state on users already in lifecycle OK without touching the provisioning FSM.
OfferingUser Fields
When retrieving or updating OfferingUser objects, the following state-related fields are available:
state(string, read-only): Current lifecycle state of the user account (provisioning/deletion)runtime_state(string, read-only): Current operational/access state of the user accountservice_provider_comment(string, read-only): Comment from service provider for pending statesservice_provider_comment_url(string, read-only): Optional URL link for additional information or actions related to the service provider comment
Runtime States
| State | Description |
|---|---|
Active |
User has full access to the service |
Pending account linking |
Access blocked; user must link an external account |
Pending additional validation |
Access blocked; user must complete additional validation (e.g. TOU) |
Lifecycle vs Runtime State
These two fields are independent:
state (lifecycle) |
runtime_state |
Meaning |
|---|---|---|
OK |
Active |
Account provisioned and fully accessible |
OK |
Pending account linking |
Provisioned in Waldur, but blocked in backend (e.g. MyAccessID not linked yet) |
OK |
Pending additional validation |
Provisioned in Waldur, but blocked pending TOU acceptance |
Creating |
Active |
Account being created; default runtime state |
The lifecycle FSM (state) tracks Waldur-side provisioning. The runtime_state tracks operational access status as reported by the service provider. Service providers should update runtime_state via update_runtime_state, and upstream consumers should read both fields from STOMP messages.
Backward Compatibility
The system maintains backward compatibility with existing integrations:
Automatic State Transitions
- Username Assignment: When a username is assigned to an OfferingUser (via API or
set_offerings_username), the state automatically transitions toOK - Creation with Username: Creating an OfferingUser with a username immediately sets the state to
OK
Legacy Endpoints
POST /api/marketplace-service-providers/{uuid}/set_offerings_username/- Bulk username assignment that automatically transitions users toOKstate
Legacy Error State Support
For backward compatibility with existing integrations:
set_error()method: The legacyset_error()method still exists and defaults toERROR_CREATINGstate
New integrations should use the specific error states (ERROR_CREATING, ERROR_DELETING) for better error context.
Usage Examples
Service Provider Workflow
Standard Creation Flow
- Initial Creation: OfferingUser is created with state
CREATION_REQUESTED - Begin Processing: Transition to
CREATINGstate - Require Validation: If additional validation needed, transition to
PENDING_ADDITIONAL_VALIDATIONwith explanatory comment and optional URL - Complete Validation: Once validated, transition to
OKstate - Account Ready: User can now access the service
Enhanced Workflow with Comment URLs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Error Handling and Recovery
1 2 3 4 5 6 7 8 9 10 11 | |
Account Deletion Workflow
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Permissions
State transition endpoints use the permission_factory pattern with:
- Permission:
UPDATE_OFFERING_USER - Scope:
["offering.customer"]- User must have permission on the offering's customer
This means users need the UPDATE_OFFERING_USER permission on the customer that owns the offering associated with the OfferingUser.
Filtering OfferingUsers
The OfferingUser list endpoint supports filtering by state to help manage users across different lifecycle stages.
State Filtering
Filter OfferingUsers by their current state using the state query parameter:
1 2 | |
Available State Filter Values
| Filter Value | State Constant | Description |
|---|---|---|
Requested |
CREATION_REQUESTED |
Users with account creation requested |
Creating |
CREATING |
Users whose accounts are being created |
Pending account linking |
PENDING_ACCOUNT_LINKING |
Users waiting to link existing accounts |
Pending additional validation |
PENDING_ADDITIONAL_VALIDATION |
Users requiring additional validation |
OK |
OK |
Users with active, ready-to-use accounts |
Requested deletion |
DELETION_REQUESTED |
Users with deletion requested |
Deleting |
DELETING |
Users whose accounts are being deleted |
Deleted |
DELETED |
Users with successfully deleted accounts |
Error creating |
ERROR_CREATING |
Users with errors during account creation |
Error deleting |
ERROR_DELETING |
Users with errors during account deletion |
Multiple State Filtering
Filter by multiple states simultaneously:
1 2 | |
Combining with Other Filters
State filtering can be combined with other available filters:
1 2 3 4 5 6 7 8 | |
Error Handling
Invalid state values return HTTP 400 Bad Request:
1 2 | |
Other Available Filters
The OfferingUser list endpoint also supports these filters:
offering_uuid- Filter by offering UUIDuser_uuid- Filter by user UUIDuser_username- Filter by user's username (case-insensitive)provider_uuid- Filter by service provider UUIDis_restricted- Filter by restriction status (boolean)created_before/created_after- Filter by creation datemodified_before/modified_after- Filter by modification datequery- General search across offering name, username, and user names
Practical Filtering Examples
Here are common filtering scenarios for managing OfferingUsers:
Find Users Requiring Attention
1 2 3 4 5 6 7 8 9 10 11 | |
Monitor Service Provider Operations
1 2 3 4 5 | |
Audit and Reporting
1 2 3 4 5 | |
Events and Logging
State transitions generate:
- Event logs: Recorded in the system event log for audit purposes
- Application logs: Logged with user attribution for debugging and monitoring
- STOMP messages: Published to the
offering_userqueue for external systems (see Event-Based Order Processing).OfferingUserAttributeConfigalso gates which user profile attributes are included in STOMP event payloads.
User Attribute Exposure Configuration
Waldur supports GDPR-compliant per-offering configuration of which user attributes are exposed to service providers. This allows organizations to declare and control what personal data is shared with each offering.
Overview
The OfferingUserAttributeConfig model allows service provider administrators to configure exactly which user profile attributes are exposed when retrieving OfferingUser data via the API.
flowchart LR
subgraph User Profile
UP[User]
UP --> |has| A1[username]
UP --> |has| A2[full_name]
UP --> |has| A3[email]
UP --> |has| A4[phone_number]
UP --> |has| A5[organization]
UP --> |has| A6[nationality]
UP --> |has| A7[...]
end
subgraph Offering Config
OC[OfferingUserAttributeConfig]
OC --> |expose_username| E1[true]
OC --> |expose_full_name| E2[true]
OC --> |expose_email| E3[true]
OC --> |expose_phone_number| E4[false]
OC --> |expose_nationality| E5[true]
end
subgraph API Response
AR[OfferingUser API]
AR --> |returns| R1[username ✓]
AR --> |returns| R2[full_name ✓]
AR --> |returns| R3[email ✓]
AR --> |filters| R4[phone_number ✗]
AR --> |returns| R5[nationality ✓]
end
UP --> OC
OC --> AR
API Endpoints
Get/Update Attribute Configuration
Endpoint: /api/marketplace-offering-user-attribute-configs/
1 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Update Existing Configuration
1 2 3 4 5 6 7 | |
Available Attributes
| Attribute | Default | Description |
|---|---|---|
expose_username |
true |
User's username |
expose_full_name |
true |
User's full name |
expose_email |
true |
User's email address |
expose_phone_number |
false |
User's phone number |
expose_organization |
false |
User's organization |
expose_job_title |
false |
User's job title |
expose_affiliations |
false |
User's affiliations |
expose_gender |
false |
User's gender (ISO 5218) |
expose_personal_title |
false |
Honorific title |
expose_place_of_birth |
false |
Place of birth |
expose_country_of_residence |
false |
Country of residence |
expose_nationality |
false |
Primary nationality |
expose_nationalities |
false |
All citizenships |
expose_organization_country |
false |
Organization's country |
expose_organization_type |
false |
Organization type (SCHAC URN) |
expose_eduperson_assurance |
false |
REFEDS assurance level |
expose_civil_number |
false |
Civil/national ID number |
expose_birth_date |
false |
Date of birth |
expose_identity_source |
false |
Identity provider source |
Default Behavior
When no OfferingUserAttributeConfig exists for an offering, the system uses the DEFAULT_OFFERING_USER_ATTRIBUTES Constance setting, which defaults to:
1 | |
Staff can configure system-wide defaults via /api-auth/override-db-settings/:
1 2 3 4 5 6 | |
Permissions
- View: Users with
VIEW_OFFERINGpermission on the offering - Create/Update: Offering owner or customer owner
GDPR Compliance
This feature supports GDPR Article 13/14 compliance by:
- Data minimization: Only expose attributes necessary for the service
- Transparency: Configuration is accessible via API for audit
- Purpose limitation: Each offering declares its data processing needs
- Consent integration: Can be linked to
OfferingTermsOfServiceto show users what data is collected