diff --git a/content/en/docs/deployment/general/licensing-apps/contract-management.md b/content/en/docs/deployment/general/contract-management/_index.md similarity index 97% rename from content/en/docs/deployment/general/licensing-apps/contract-management.md rename to content/en/docs/deployment/general/contract-management/_index.md index 35634ad851d..e3ce221f699 100644 --- a/content/en/docs/deployment/general/licensing-apps/contract-management.md +++ b/content/en/docs/deployment/general/contract-management/_index.md @@ -1,7 +1,7 @@ --- title: "Contract Management" url: /developerportal/deploy/contract-management/ -weight: 20 +weight: 10 description: "Understand your Mendix subscription lifecycle, contract statuses, renewal timelines, and critical actions to ensure continuous service and prevent data loss." --- @@ -16,7 +16,7 @@ This document provides detailed information about the status of your Mendix appl Your Mendix subscription is categorized into three main statuses: Active, Expiring, and Expired, based on your contract's expiry date. | Account Status | Timeline | Impact | -|---------------|----------|--------------------| +| --------------- | ---------- | -------------------- | | **Active (Green)** | Until 30 days before contract expiry | Your account is fully active, with all services available and application runtimes functioning normally. This is the optimal state for uninterrupted Mendix usage. | | **Expiring (Orange)** | From 30 days before contract expiry until contract end date | All services continue to function normally. You receive email reminders, notifications, and banner alerts on Mendix Platform about your upcoming renewal. | | **Expired (Red)** | From the day after contract expiry up to 60 days | Your account and applications are downgraded to **Unlicensed** mode. You can manually restart apps, but they will automatically shut down after 2-4 hours and are limited to 6 concurrent users. Platform features are not disabled.| @@ -68,7 +68,7 @@ This is your final opportunity to renew your contract and avoid service disrupti #### Pre-Expiry Timeline Summary{#pre-expiry-timeline-summary} | **Days Before Expiry** | **Key Actions** | **Status** | -|------------------------|-----------------|------------| +| ------------------------ | ----------------- | ------------ | | **90 days** | Contact Account Team for renewal | Active | | **30 days** | Finalize renewal discussions | Expiring | | **15 days** | Download data if not renewing | Expiring | @@ -95,7 +95,7 @@ Application data deletion is irreversible. Make sure to download all necessary a #### Post-Expiry Timeline Summary{#post-expiry-timeline-summary} | **Days After Expiry** | **Key Actions** | **Status** | -|------------------------|-----------------|------------| +| ------------------------ | ----------------- | ------------ | | **0 days (Expired)** | Contract expires | Expired | | **+1 day** | Limited access | Expired | | **+60 days** | Data permanently deleted | Expired | diff --git a/content/en/docs/deployment/general/licensing-apps/_index.md b/content/en/docs/deployment/general/contract-management/licensing-apps.md similarity index 81% rename from content/en/docs/deployment/general/licensing-apps/_index.md rename to content/en/docs/deployment/general/contract-management/licensing-apps.md index 50dfd5c5bf9..6f65ca87359 100644 --- a/content/en/docs/deployment/general/licensing-apps/_index.md +++ b/content/en/docs/deployment/general/contract-management/licensing-apps.md @@ -23,7 +23,7 @@ Unlicensed apps, running outside Mendix Cloud, have some restrictions. These res ¹ More information on the capabilities of different license options is available on [Mendix Platform Pricing](https://www.mendix.com/pricing). -² End-users of your app are classified as either internal or external. You will need to report this for licensing purposes using either the [`USAGE_METRICS_EMAIL_FIELDS` custom variable](/developerportal/deploy/environments-details/#custom-environment-variables) (if you are using email domain to distinguish between them) or by [populating the user type](/developerportal/deploy/populate-user-type/) for each end-user of your app. Only end-users whose Mendix accounts are marked as **Active** are counted towards the number of end-users of the app. +² End-users of your app are classified as either internal or external. You will need to report this for licensing purposes using either the [`USAGE_METRICS_EMAIL_FIELDS` custom variable](/developerportal/deploy/environments-details/#custom-environment-variables) (if you are using the email domain to distinguish between them) or by [Implementing User Metering](/developerportal/deploy/implementing-user-metering/) for each end-user of your app. Only end-users whose Mendix accounts are marked as **Active** are counted towards the number of end-users of the app. ³ Depending on the configuration of your chosen cloud, a container and runtime may be restarted if it appears unhealthy because the runtime has stopped. @@ -31,6 +31,25 @@ For each environment for which you want to remove the restrictions placed on an The app checks for a license each time it is started. If the license expires while the app is running, it will continue to run until the next time it is started, when the license will be checked again. +## User Types and Definitions + +Mendix licenses follow user-based pricing plans. This means customers pay based on how many users need access and what type of access they require for their Mendix applications. +Customers can purchase user licenses in the following categories: + +### Multi-App Internal User + +These are internal users (employee or contractor of the customer or affiliated company or group) who can access any number of applications and are licensed under the Multi-App Internal User Pack. Each internal user is counted as one unique user, regardless of how many apps they access. + +### Single-App Internal User + +An internal user (employee or contractor) licensed for only one specific application and counted as one user limited to a single designated app. They are licensed under the Single-App Internal User Pack. + +### External User + +A user who is not an employee or contractor of the customer or its affiliates, and is explicitly marked “External” within your Mendix application data. This is one unique user across all apps designated for external use and licensed under the External User Pack. + +For more information on legal definitions, refer to [Order Form Definitions](https://www.mendix.com/legal/platform-usage/order-form-definitions/). + ## Obtaining a Mendix License{#get-license} {{% alert color="info" %}} @@ -78,7 +97,7 @@ To license an Insights Hub app, you need to provide your **License ID** and **Li To license a Mendix app on Mendix on Kubernetes, you need to supply a **Subscription Secret** or license credentials for your app. See below for how it can be added to either a Connected or Standalone cluster. -In addition to the licenses for your apps, you will also need to license the Mendix Operator which helps deploy your app to a Mendix on Kubernetes environment. For details on the Mendix Operator license, see [Licensing Mendix on Kubernetes](/developerportal/deploy/private-cloud/#licensing). +In addition to the licenses for your apps, you will also need to license the Mendix Operator, which helps deploy your app to a Mendix on Kubernetes environment. For details on the Mendix Operator license, see [Licensing Mendix on Kubernetes](/developerportal/deploy/private-cloud/#licensing). #### Mendix on Kubernetes Connected @@ -99,7 +118,7 @@ cf set-env LICENSE_ID cf set-env LICENSE_KEY ``` -Then restart the app so that the environment variables are read and the license goes into effect. +Then restart the app so that the environment variables, are read and the license goes into effect. ### Docker diff --git a/content/en/docs/deployment/general/contract-management/user-metering/_index.md b/content/en/docs/deployment/general/contract-management/user-metering/_index.md new file mode 100644 index 00000000000..194c4dc242f --- /dev/null +++ b/content/en/docs/deployment/general/contract-management/user-metering/_index.md @@ -0,0 +1,99 @@ +--- +title: "User Metering" +url: /developerportal/deploy/user-metering/ +weight: 20 +description: "This document describes how user metering works." +--- + +## Introduction + +Mendix uses end user metering process to determine the number and type of users accessing applications in accordance with license agreements. Proper user classification ensures accurate reporting and optimal licensing costs for customers. + +{{% alert color="info" %}} +End user metering is currently applied to applications deployed to Mendix Cloud and Mendix Cloud Dedicated environments. +{{% /alert %}} + +Mendix licenses include user-based pricing plans. With user-based pricing, customers purchase licenses based on the number of users who need access to their Mendix applications. Customers can purchase user licenses in the following categories: + +* Multi-App Internal User +* Single-App Internal User +* External User + +For more information, refer to the [User Types and Definitions](/developerportal/deploy/licensing-apps-outside-mxcloud/#user-types-and-definitions) section of *Licensing apps*. + +### Key Features + +* Automatic tracking – User consumption is automatically tracked from the moment your app is deployed to production and becomes functional, ensuring real-time tracking. +* Prompt data processing – Usage data is collected, processed, and deduplicated regularly. +* License type classification – Users are classified by license type as External, Multi-App Internal, or Single-App Internal. This classification yields accurate license tracking and helps optimize licensing costs. + +## How User Metering Works + +User metering in the Mendix cloud operates through a four-stage automated process, and it is enabled by default for apps deployed in Mendix Cloud environments. + +### In-App User Classification + +Your application logic plays an important role in creating and maintaining accurate user records. A key component of in-app user classification is maintaining a consistent user identifier. This becomes especially important when customers are using multi-app licenses. In the Mendix Multi-App License Pack, the same individual may access multiple apps under a single license agreement. A unique, persistent user identifier ensures accurate tracking and prevents duplication. The application logic is responsible for classifying users as `Internal` or `External`. For more detailed information, refer to the [User Classification](/developerportal/deploy/implementing-user-metering/#user-classification). + +### Data Collection + +All applications on the Mendix Cloud and Mendix Cloud Dedicated automatically send user data back to the Mendix platform. Data is collected from all environments throughout the month. However, only data from the production environment is considered for consumption numbers and billing purposes. PII information (username and other user identifiers) is hashed at source before transmission to ensure data privacy. + +### Data Aggregation and Deduplication + +At the end of each month, the Mendix Platform aggregates the collected data. Users are counted and rolled up to the app portfolio level. This process is detailed in the [User Classification and Deduplication](#classification-deduplication) section below. + +### User Classification and Reporting + +Users are thereafter automatically classified in the following user licensing buckets based on your user licenses: + +1. External Users +2. Single-App Internal Users +3. Multi-App Internal Users (default) + + + +## How User Classification and Deduplication Work {#classification-deduplication} + +The user classification and deduplication process determines which user pack is consumed when a user accesses one or more of your applications. The process evaluates users in a sequence so that each user is counted according to the correct license pack without duplication. The classification follows the steps below: + +### User Identification (Deduplication) + +Users are deduplicated based on common identifier values. A customer who has different identifier values in the aggregated data cannot be recognized as the same user, and will be counted as multiple users. The deduplication mechanism evaluates two user attributes. When different values persist, Mendix treats them as different users. For more information, refer to [Guidelines for Unique User Identification (Deduplication)](/developerportal/deploy/implementing-user-metering/#guidelines-for-unique-user-identification-deduplication). + +### Classifying External Users + +The next step is to determine whether a user is an external user: + +* If the customer has a valid External User Pack subscription, and +* The user is explicitly marked as `External` within the application. + +Then the user is classified as an external user. + +Once classified, the user is licensed under the External User Pack and excluded from further classification steps. For more information, see the [User classification](/developerportal/deploy/implementing-user-metering/#user-classification) section of *Implementing User Metering*. + +All remaining users are classified as `Internal` Users and further classified as described in the sections below. + +{{% alert color="info" %}} +A multi-app user who is marked as `Internal` in one app and `External` in another will be counted as an internal user. +{{% /alert %}} + +### Classifying Single-App Internal Users + +After `External` users are classified, the classification process further classifies the single-app internal users. + +If the application is associated with a Single-App Internal User Pack, the user of the app will be classified as a single-app internal user. This user will be counted against the Single-App Internal User Pack for that application. + + +{{% alert color="info" %}} +An internal user accessing multiple apps, one of which is covered under a Single-App Internal User Pack, will be counted as a single-app internal user for that app and will also be counted separately for any other apps they use. +{{% /alert %}} + +### Classifying Multi-App Internal Users + +After external users and single-app internal users have been identified, any remaining internal users are classified as multi-app internal users. +These users are licensed under the Multi-App Internal User Pack, and no further action is required from your side. + +## Read More + +* [Licensing Apps](/developerportal/deploy/licensing-apps-outside-mxcloud/) diff --git a/content/en/docs/deployment/general/contract-management/user-metering/faq.md b/content/en/docs/deployment/general/contract-management/user-metering/faq.md new file mode 100644 index 00000000000..5fc5a545bf3 --- /dev/null +++ b/content/en/docs/deployment/general/contract-management/user-metering/faq.md @@ -0,0 +1,113 @@ +--- +title: "Frequently Asked Questions on User Metering" +linktitle: FAQs on User Metering +url: /developerportal/deploy/faq/ +weight: 40 +description: "This document contains a list of frequently asked questions on user metering." +--- + +## Introduction + +This document answers common questions about user metering, outlining user classification and users. + +## General Questions + +### Is User Metering Automatically Enabled? + +User metering is automatically enabled for all Mendix Cloud and Mendix Cloud Dedicated applications without requiring any configuration or setup for usage data collection. All running app environments transmit usage data to the Mendix Platform at regular intervals. Data collection begins as soon as your application is deployed to a production environment. + + +### What Happens if I Exceed My Entitlement? + +If you exceed your licensed entitlements: + +* No immediate service disruption: Your applications continue to run normally. + +* Compliance discussion: Your Customer Success Manager (CSM) will contact you to discuss: + + * Purchasing additional user packs + * Optimizing user classification + * Adjusting your license agreement + + + +## Questions on User Classification + +### How Are Users Classified If I Do Not Assign Single-App Internal User Pack to an app? + +If no action is taken, all users are classified as Multi-App Internal Users by default. +This means all users in your apps are aggregated together and classified as Multi-App Internal Users. + +### I Have External Users in My Applications. How Do I Ensure They Are Counted Correctly? + +Explicitly mark users as `External` in your application to ensure they are counted correctly under your External User Pack. If you do not have an External User Pack, these users will be classified as `Internal`, even if they are marked as `External` users. Also, a multi-app user who is marked as `Internal` in one app, but as `External` in another app, will be counted as an Internal Multi-App User. + +For more information, refer to [User Classification](/developerportal/deploy/implementing-user-metering/#user-classification). + + +### How Do I Assign Single-App User Packs to Multiple Applications With Unique User Bases? + +You must purchase a separate Single-App User Pack for each application and assign them individually. Contact your CSM or account team to purchase additional packs. + +## User-Specific Questions + +### How Are Users Counted If They Log In Only Once Per Year? + +Users are counted based on their active status, not login frequency. If they are marked as `Active` in your application, they are counted every month, regardless of whether they log in. + +Note that if the user has an active status during any moment in a month, they are counted as an active user for that calendar month. + +### What Is the Best Practice for Deactivating Users Who Left the Organization? + +Deactivate users as soon as they no longer need access. This ensures that they are not counted in future usage reports and helps maintain security. Deactivate leavers before month-end to optimize license consumption. + +### Should I Delete or Deactivate Users To Save on License Costs? + +Technically, you can deactivate or remove users to optimize license costs. + +To optimise license cost, you may choose to delete records in the `system.user` object, while maintaining data in custom user objects. + +You may also choose to deactivate users by using SCIM integration between your app and your IdP. This requires you to include the [SCIM](/appstore/modules/scim/) module in your application. + +{{% alert color="info" %}} +Check your organization's data retention policies before purging any user data. Deactivation usually satisfies both license optimization and compliance requirements. +{{% /alert %}} + +### Are Anonymous Users Counted in User Metering? + +Anonymous Users are users who access your application without logging in or authenticating. Anonymous users are not reported and hence not even counted in user metering. Only Named Users (users with unique login credentials) are counted. + +### Are API Users and Service Accounts Counted in User Metering? + +API Users (also called Service Accounts or System Users) are non-human accounts used for: + +* System-to-system integrations +* Automated processes +* Background jobs +* External system access via web services + +API users with authentication count as Named Users and are included in the user metering. + +### I Have Users Who Log in Very Infrequently. Does Mendix Allow Reassigning a ‘Seat’ to Different Users? + +Yes. A seat can be reassigned at most once per month, meaning that within a single calendar month, a seat can only be used by one user. If a user is active on any day within a calendar month, they will occupy that seat for the entire month, regardless of how often they log in during that period. Over the course of a year, a single seat can therefore be assigned to a maximum of 12 different users. + +## Read More + +* [User Metering](/developerportal/deploy/user-metering/) +* [Implementing User Metering](/developerportal/deploy/implementing-user-metering/) diff --git a/content/en/docs/deployment/general/contract-management/user-metering/implementing-user-metering.md b/content/en/docs/deployment/general/contract-management/user-metering/implementing-user-metering.md new file mode 100644 index 00000000000..8989e1696e9 --- /dev/null +++ b/content/en/docs/deployment/general/contract-management/user-metering/implementing-user-metering.md @@ -0,0 +1,145 @@ +--- +title: "Implementing User Metering" +url: /developerportal/deploy/implementing-user-metering/ +weight: 30 +description: "This document describes how to implement user metering." +--- + +## Introduction + +This document provides you with an overview of the user metering implimentation, including guidelines for unique user identification, how users are classified, and the process for deactivation of users. +For accurate user metering, in-app user classification is a crucial first step. For more information, refer to [How User Metering Works](/developerportal/deploy/user-metering/#how-user-metering-works). To do this, the logic in your app models needs to cater to the following aspects, if applicable: + +* [Unique user identification](/developerportal/deploy/implementing-user-metering/#guidelines-for-unique-user-identification-deduplication) +* [User classification](/developerportal/deploy/implementing-user-metering/#user-classification) +* [User deactivation](/developerportal/deploy/implementing-user-metering/#deactivation-of-users) + +## Guidelines for Unique User Identification (Deduplication) + +Mendix offers two variants of multi-app user licenses, namely internal multi-app and external multi-app user licenses. These licenses allow a single user to access multiple applications while being counted only once for metering purposes. This applies to both internal and external users. Accurate user metering and correct multi-app user deduplication depend critically on consistent user identification across all your applications. + +To ensure unique multi-app users are correctly identified and metered, you must maintain a consistent user identifier across all relevant applications. + +The Mendix metering mechanism uses the `UserCommons.namedUserIdentifier.value` attribute as the primary user identifier. If this attribute is not available or populated, it falls back to `system.user.name`. For a detailed overview of relevant entities and attributes, refer to the [Domain Model Entities](#domain-model-entities) section below. + +### Key Requirements for Multi-App User Identification: + +Consistent Identifier Value: The same value for a given multi-app user must be stored in the chosen identifier attribute (`UserCommons.namedUserIdentifier.value` or `system.user.name`) across all applications that the user accesses. Inconsistent values will result in the user being counted as multiple distinct users. + +### Best Practices for Choosing and Implementing a Cross-App User Identifier: + +User identification strategies can vary across application portfolios, particularly when applications were developed independently or use different provisioning methods. Consider the following guidelines to establish a robust and consistent identification strategy: + +1. Prioritize `UserCommons.namedUserIdentifier.value`: Always aim to use and populate `UserCommons.namedUserIdentifier.value` for user identification. This provides a dedicated field for metering purposes and offers flexibility regardless of the `system.user.name` value. + +2. Use a stable, globally unique identifier: Select an identifier that is stable and consistently unique across your entire user base and application portfolio. + + * Recommended Identifier: User's Email Address – Mendix strongly recommends storing the user's email address in `UserCommons.namedUserIdentifier.value`. This is typically a stable and globally unique identifier that users are familiar with. An email address is personal information. The Mendix platform, therefore, collects hashed values of the user identifier to enhance privacy. If you have specific privacy concerns, consult the [data processing agreement](https://www.siemens.com/en-us/company/compliance/data-privacy/data-privacy-terms/) you have with Siemens. + + * Alternative Identifiers: If using email addresses is not feasible or desired for your organization, you must establish a clear guideline on what user identifier your company will consistently use for cross-app user identification. + + * Handling Case Sensitivity: When using email addresses or other text-based identifiers, always store these values in lowercase to prevent metering issues caused by case sensitivity. The `system.user.name` attribute is case-sensitive by design. Mendix's standard SAML, OIDC SSO, and SCIM modules already apply this for email claims received from Identity Providers (IdPs). + +3. Address pairwise identifiers (for example, OIDC `sub` claim): Some identity providers, such as Microsoft Entra ID, generate "pairwise" identifiers (for example, Entra ID's `sub` claim). These identifiers are unique for each application for the same user. This is designed to prevent correlation across different service providers. However, you are using this technical identifier as the global unique identifier for user metering, it can lead to incorrect multi-app metering within your portfolio. When using the OIDC SSO module with Microsoft Entra ID, you can use the `oid` claim instead of the `sub` claim as the global unique identifier. The `oid` claim contains the Entra ID user object ID and remains consistent for the same user across all applications. Alternatively, if you follow the recommended approach of using the user’s email address as the global unique identifier for user metering, pairwise identifiers will not impact your metering accuracy. + +4. Integrating with existing application logic: If your current applications use varying `system.user.name` values or different provisioning methods, you can implement `UserCommons.namedUserIdentifier.value` without altering existing logic. Continue using your existing application logic for `system.user.name` if necessary, but additionally implement logic to populate `UserCommons.namedUserIdentifier.value` with your chosen consistent cross-app identifier (for example, email address or `oid` claim). This ensures the metering mechanism has a reliable, consistent identifier to use. If your applications are already consistently storing the same identifier for a multi-app user in `system.user.name`, you do not have to use the `UserCommons.namedUserIdentifier.value`. + +For more information on user types and definitions, refer to the [User Types and Definitions](/developerportal/deploy/licensing-apps-outside-mxcloud/#user-types-and-definitions) section of *Licensing Apps*. + +## User Classification + +In the Mendix pricing plan, a distinction is made between internal and external named users of a Mendix app. As a customer, you purchase a license for a specific number of internal users and, optionally, for external users (which are typically cheaper). For accurate user metering, external users must be correctly classified. If they are not, your company may exceed the licensed capacity for internal users, and Mendix may require you to acquire additional internal user licenses. + +To ensure accurate user metering, external users must be explicitly marked as `External`. If they are not marked accordingly, they will be counted as `Internal` users. + +There are several approaches to classify users as `Internal` or `External`, ranging from configuration-only to custom development. These options are: + +### IdP-Based User Classification + +This method requires one of the following identity modules to be enabled: OIDC SSO, SCIM, or SAML. A key advantage of this approach is that it does not require any modifications to your existing app. Classification can begin immediately by setting a constant. However, because users are only classified when they log in, it may take some time before all end users are classified. + +### Userrole-Based User Classification + +The user-role-based User Classification module classifies users by using the roles already defined in your app. It can update all existing users in one run and works well if you already have separate roles for internal and external users. However, using this module requires upgrading your app to include the User Classification module. Userrole-based user classification is the recommended approach. It encourages and leverages application design with distinct userrole definitions for external and internal users. + +### Custom User Classification + +This method can be implemented either by using the [User Classification](/appstore/modules/user-classification/) module or by creating fully custom microflows. The main advantage of this approach is the flexibility it provides. You can apply any classification logic you choose while still relying on the User Classification module as the base. However, this method requires developing custom logic and involves upgrading your app to a new version of your app to include the [User Classification](https://marketplace.mendix.com/link/component/245015) module. + +{{% alert color="info" %}} +In situations where there is ambiguity about the user classification, Mendix considers users as internal users. Ambiguity may happen in the following situations: + +* A multi-app user is marked as `External` in one app and `Internal` in another app. +* When applying userrole-based classification, and a user has both an `Internal` and an `External` userrole. +{{% /alert %}} + +Classification by the platform is not supported by using your email domains, nor any other logic. Your app logic is responsible for classification. + +#### Custom Classification Using Your Own Microflow + +If you prefer not to use the custom User Classification module, you can instead create the user classification logic entirely from scratch using custom microflows. This approach provides maximum control and flexibility, allowing you to define any classification rules and processes according to your specific requirements. + +{{% alert color="info" %}} +This approach is for end users who are already set up in your app. For new end users onboarding into your app, you can implement a similar logic to set the `UserType` attribute during initial end user creation. +{{% /alert %}} + +To update the `UserType` attribute of the `UserReportInfo` entity, refer to the [Domain Model Entities](#domain-model-entities) section for more details. + +## (De)Activation of Users + +The `system.user.active` attribute controls active or inactive users in your application. Users with an ‘active’ state can log in to your app and are counted for user metering purposes, while non-active users cannot login are not counted for user metering. + +You can provision the user records (for example, created, updated, or deleted) using proprietary logic or via one of the following platforms supported modules: + +* SAML and OIDC SSO modules can create users with active state. By nature of the SSO protocols, these modules do not deactivate or delete any user records in your application. +* The SCIM module allows your app to be integrated with your IdP to create, update, or delete user records. Depending on the (configured) business logic in your IdP, users may be created, deactivated, or deleted + + * as a result of the Joiner, Mover, or Leaver processes. + * as a result of license optimization, users who have not logged in to a certain application for a certain period may be removed from the access group in the IdP, and therefore, the IdP may deactivate or remove users from your SCIM-enabled application. + +* The LDAP module allows you to synchronize users and their status (active=false/true) from your on-premises Active Directory to your application. This is a similar module to SCIM but using a different protocol. + +If you are considering deactivating or removing user records for optimization of user cost, you are advised to consider the following: + +* Users cannot log in when in the deactivated (active=false) state. The primary purpose of the active state is to control which users can log in. When SSO is used, the user may be successfully logged in at the IdP; however, the Mendix application fails to grant access if the active state is not updated. +* Actual logins, frequency of login, or `system.user.lastlogin` is also not relevant for metering. A user is counted as an active user if the state was active on any day of the calendar month. +* If you choose to remove user records, associated data may be deleted depending on your domain model. +* The SAML and OIDC SSO modules are capable of creating or recreating any user that was deleted. This can be described as just-in-time user provisioning, also known as on-the-fly user onboarding or real-time user creation. + +## Versioning Information + +The improved user metering capabilities are introduced in Mendix 11. These capabilities in the platform apply to apps using any Mendix version. Mendix offers the following guidance on versioning. + +| Classification Menthod | Mendix 9 LTS | Mendix 10 LTS, Mendix 11 | +| --- | --- | --- | +| IdP-based user classification | SAML 3.6.21 and above
OIDC 3.0.0 and above | SAML 4.0.0 and above
OIDC SSO v4.0.0 and above | +| Userrole-based or custom user classification | User Classification v1.0.1 and above | User Classification v2.0.0 and above | +| Multi-app user identification | `system.user.name` | `system.user.name` or `NamedUserIdentifier` in User Commons v2.2.0 and above | +| SCIM-based user deactivation | SCIM v3.0.0 and above | SCIM v4.0.0 and above | + +If you have extended support on Mendix 8, contact your CSM for guidance on user metering if needed. + +## Domain Model Entities {#domain-model-entities} + +This section explains the entities and their attributes in your app domain model that are relevant for user metering. + +The following are entities and their attributes: + +1. `User`: Every Mendix app has a system module containing an entity `User`. + + * `system.user.name`: This field is used to identify users, unless a `UserCommons.namedUserIdentifier.value` is available for the same user. + * `system.User.Active`: A Boolean attribute, `Active`, is used to select the active user account for user metering. A user record that has `Active=true` during the metering period is counted as an active user during the billing period and reconciliated against one of the allocated user licenses. + +2. `UserReportInfo`: The system module also features the `UserReportInfo`. + + * `system.UserReportInfo.UserType`: `UserType` is used to classify end-users as `External` or `Internal` Users. Your application must set the attribute for all existing and new (external) end users. If it does not, Mendix will classify those users as `Internal`. + + {{< figure src="/attachments/deployment/general/implementing-user-metering/user-type-enumeration.png" class="no-border" >}} + +3. `namedUserIdentifier`(optional): Recent versions of the [UserCommons](https://marketplace.mendix.com/link/component/223053) module include a `namedUserIdentifier` entity. + + * `UserCommons.namedUserIdentifier.value`: User commons modules in your app model assign the values to the `namedUserIdentifier.value` attribute to identify a user instead of `system.user.name`. The `namedUserIdentifier` overrides `user.name`. + +Note that one application may use `system.user.name` and not `userCommons.namedUserIdentifier.value`, or may exclude the UserCommons module, while another application may use `userCommons.namedUserIdentifier.value` instead. If the values in these different fields are the same for a multi-app user, the Mendix user metering mechanism correctly identifies the user as a single multi-app user (deduplication). + +It is not possible to map multiple values of `system.user.name` to a single value of `UserCommons.namedUserIdentifier.value` within an app. diff --git a/content/en/docs/deployment/general/populate-user-type.md b/content/en/docs/deployment/general/populate-user-type.md deleted file mode 100644 index 220c10e160a..00000000000 --- a/content/en/docs/deployment/general/populate-user-type.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: "Populate User Types" -url: /developerportal/deploy/populate-user-type/ -description: "Describes how to classify existing app end-users as either internal or external." -aliases: - - /howto/monitoring-troubleshooting/populate-user-type/ - - /howto9/monitoring-troubleshooting/populate-user-type/ ---- - -## Introduction - -In the Mendix Pricing Plan, a distinction is made between Internal and External Named Users of a Mendix app. As a customer, you purchase a license for a specific number of Internal users and, optionally, for External users (which are typically cheaper). For accurate user metering, External users must be correctly classified. If they are not, your company may exceed the licensed capacity for Internal users, and Mendix may require you to acquire additional Internal user licenses. - -This document helps you set up your apps to ensure accurate metering for your External users. It describes different sample solutions that can help you in External User classification for existing users of your apps. - -{{% alert color="info" %}} -**Definitions** - -* *Named User* – an individual authorized by you to have access to your apps with unique login credentials, or an authorized external system that accesses or is accessed by your application. -* *Internal User* – a *Named User* who is an employee or contractor of your business. -* *External User* – a *Named User* who is not an employee or contractor of your business, and is designated as an External User in the Mendix Platform. - -{{% /alert %}} - -## Background - -Every Mendix app has a system module containing an entity `UserReportInfo`. This entity has an attribute `UserType` that is used to classify end-users as `External` or `Internal` Users. Your application must set the attribute for all existing and new (external) end users. If it does not, Mendix will classify those users as Internal. - -The metering relies on this attribute to ascertain the end-user type and report it back to us. - -{{< figure src="/attachments/deployment/general/populate-user-type/user-type-enumeration.png" class="no-border" >}} - -## Classification Options - -There are several approaches to classify users as `Internal` or `External`, ranging from configuration-only to custom development. These options are listed below: - -### IdP-Based User Classification - -The simplest method to set the `UserType` is by using the Identity and Access Management (IAM) modules, which require only configuration without the need to develop a microflow. This approach leverages a connection with an Identity Provider (IdP) to classify users. The primary benefit of IdP-based classification is its efficiency, as it typically only requires configuration within the existing IAM modules. Mendix offers you the following IAM modules: - -* [OIDC](https://docs.mendix.com/appstore/modules/oidc/) -* [SCIM](https://docs.mendix.com/appstore/modules/scim/) -* [SAML](https://docs.mendix.com/appstore/modules/saml/) - -Alternatively, you can build a custom microflow as described in the [Populating UserType for Existing Users of an App](#using-microflow) section below. - -When connecting your app with an IdP, set up the `UserType` through the capabilities of the OIDC SSO, SCIM, or SAML module. The `UserType` is now configured in the User Provisioning, which is integrated into the OIDC SSO, SCIM, and SAML modules. This means you can directly configure end-users of your application as `Internal` or `External` in the **UserProvisioning** tab of your app. Based on this configuration, users are updated each time they log in. These modules allow you to set the `UserType` per IdP as the source of your end-users, assuming that separate IdPs are used for `internal` and `external` users. - -For more information, refer to the User Provisioning section of the following modules: - -* [OIDC SSO](/appstore/modules/oidc/#custom-provisioning-rt) -* [SCIM](/appstore/modules/scim/#user-provisioning) -* [SAML](/appstore/modules/saml/#custom-provisioning-rt) - -#### Prerequisites for IdP-Based User Classification - -1. Mendix and module versions: - * Mx9 - * OIDC SSO: v3.0.0 or above - * SCIM: v1.0.0 or above - * Mx10 - * OIDC SSO: v4.0.0 or above - * SAML: v4.0.0 or above - * SCIM: v2.0.0 or above - * Mx11 - * OIDC SSO: v4.0.0 or above - * SAML: v4.0.0 or above - * SCIM: v2.0.0 or above - -2. IdP Setup: Use separate IdPs for `Internal` and `External` users. - - {{% alert color="info" %}}It may be possible to enhance configurations in your IdP by settting-up two separate connections between your app and your IdP. In this scenario, the IdP sees your app as two distinct clients/services. The Mendix app sees them as two distinct IdPs, each with its own provisioning configuration. This allows assigning different `UserType` values per IdP connection. Configurations in your IdP have to ensure that each client only addresses internal or external users. - {{% /alert %}} - -3. Classification on login: Classification of users happens when they log in. If your application has limited user buckets (for example, license restrictions for internal/external users), and timely classification is critical, ensure all (external) users log in before your limit on internal users is reached, as external users have not been classified as `External` users yet. - -### User Role-Based User Classification - -Role-based classification relies on the distinct user roles defined within the application itself. This method is particularly effective for scenarios where an application needs to differentiate between user types, such as internal employees versus external users, by assigning them specific roles. Mendix offers the [User Classification](https://marketplace.mendix.com/link/component/245015) module, which aims to streamline the implementation of user role-based classification, thereby minimizing the development effort required within the application. - -Instead of writing microflows, you can classify users as `Internal` or `External` using roles in the User Classification module. To do this: - -1. Define roles like `ExternalRole` or other custom roles. -2. Use the [User Classification](/appstore/modules/user-classification/) module to map these roles to the `UserType` field in the `UserReportInfo`. -3. When a role is assigned to a user in your Mendix app, the User Classification module automatically updates the `UserType` field in the `UserReportInfo` entity for that user. - -This approach is simpler, more consistent, and easier to maintain than attribute-based logic. - -For more information, see the [Role-based Classification](/appstore/modules/user-classification/#role-based-classification) section of *User Classification*. - -#### Prerequisites for Role-Based Classification - -1. Your app model uses distinct user roles for external and internal users. -2. Include the User Classification module in your app model. To use it, your app must be running on one of the following Mendix versions: - - * Mx9 LTS - * Mx10 LTS - * Mx11 and above - -### Custom Classification - -When the logic of your application does not allow for IdP-based or user role-based user classification, you need to build your own custom user classification logic in your app. It lets you create specific rules tailored to the unique needs of your application. - -#### Custom Classification Using the User Classification Module - -This option lets you build custom logic while still using the framework from the [User Classification](/appstore/modules/user-classification/) module. It reduces development effort by giving you a structured way to add custom classification rules. - -You can classify users as `Internal` or `External` using your own business rules instead of only user roles or IAM settings. With the User Classification module and a microflow, you can evaluate conditions, for example, email domain of end-users. The User Classification module makes it easy for you to implement custom logic to classify existing users as well as new users. This gives maximum flexibility to handle complex or unique scenarios and ensures accurate Mendix user metering. For more information, see the [Custom Classification](/appstore/modules/user-classification/#custom-classification) section of *User Classification*. - -#### Custom Classification Using Your Own Microflow - -For maximum control, developers can create user classification entirely from scratch using custom microflows. This gives full flexibility to define any classification rules and processes, making it the most customized approach. - -{{% alert color="info" %}} -This approach is for end-users who are already set up in your app. For new end-users who onboard into your app, you can implement a similar logic to set the `UserType` attribute during initial end-user creation. -{{% /alert %}} - -Outlined below is an example of a module that can be used to update the `UserType` attribute. You will need to adapt the module logic for classifying your own internal and external end-users. - -##### Domain Model - -In the example below, our aim is to update the `UserType` attribute of the `UserReportInfo` entity. However, the entity `UserReportInfo` is protected in the System module and has no access rules. As a result, it cannot be exposed directly in the UI pages. -Therefore, the approach we take is to create a new non-persistable entity, `UserTypeReport`, which we will populate based on the values of `UserReportInfo` to show in the UI. - -{{< figure src="/attachments/deployment/general/populate-user-type/usertypereport.png" class="no-border" >}} - -{{< figure src="/attachments/deployment/general/populate-user-type/usertypereport-properties.png" class="no-border" >}} - -##### Populating `UserType` for Existing Users of an App {#using-microflow} - -1. Create a microflow `User_RetrieveOrCreateUserReportInfo` which will ensure that a `UserReportInfo` object exists for a given `User`. - - {{< figure src="/attachments/deployment/general/populate-user-type/retrieve-userreportinfo.png" alt="Microflow: User_RetrieveOrCreateUserReportInfo" class="no-border" >}} - -2. Create a microflow `User_EvaluateAndSetUserType` which will populate the `UserType` attribute on the `UserReportInfo` entity for a given `User`. - - In this example, we decide whether a user is `Internal` or `External` based on the email address of the user. To do that, we need to retrieve the email address of each user from the database. Note that the `System.User` entity itself does not have the email address. The email address is stored in the specializations of `System.User`. - - Here, we show how to do it for two specializations of the `System.User` entity, namely `Administration.Account` and `MendixSSO.MendixSSOUser`. In the `Administration.Account` entity, the email is in an attribute named `Email`. And in the `MendixSSO.MendixSSOUser` entity, it’s in an attribute named `EmailAddress`. Hence, we need to use an [Object Type Decision](/refguide/object-type-decision/) activity to split the `System.User` into `Administration.Account` and `MendixSSO.MendixSSOUser` and then fetch the email address according to the name of the attribute. - - {{< figure src="/attachments/deployment/general/populate-user-type/set-user-type.png" alt="Microflow: User_EvaluateAndSetUserType" class="no-border" >}} - - * The logic to determine whether the end-user is internal or external is up to the developer. The example below returns `true`, to indicate that the user is internal, if the user has no email address, or if the domain for their email address is `mendix.com` or `myorg.com`. - - {{< figure src="/attachments/deployment/general/populate-user-type/user-type-split.png" alt="Split: Decide if user is internal" class="no-border" >}} - -3. Create a new microflow `User_Correct_UserType` which will use the microflows `User_RetrieveOrCreateUserReportInfo` and `User_EvaluateAndSetUserType` created above. In this microflow, we create and populate the `UserTypeReport` entity and return a list of these entities at the end of the microflow. - - {{< figure src="/attachments/deployment/general/populate-user-type/correct-user-type.png" alt="Microflow: User_Correct_UserType" class="no-border" >}} - -4. Create a page `UserTypeReport` with a DataGrid which uses the microflow `User_Correct_UserType` as its source. - - {{< figure src="/attachments/deployment/general/populate-user-type/grid-general.png" class="no-border" >}} - - {{< figure src="/attachments/deployment/general/populate-user-type/grid-data-source.png" class="no-border" >}} - -5. Add the page to the **Navigation**. -6. When you go to that page, it will set the `UserType` as per your logic and show you the user type report. - - {{< figure src="/attachments/deployment/general/populate-user-type/user-type-report.png" class="no-border" >}} - -7. The report can be exported into an Excel file. - -## Read More - -* [User Classification Module](/appstore/modules/user-classification/) diff --git a/content/en/docs/deployment/mendix-cloud-deploy/_index.md b/content/en/docs/deployment/mendix-cloud-deploy/_index.md index 3c042ffae87..0f7ce3c9545 100644 --- a/content/en/docs/deployment/mendix-cloud-deploy/_index.md +++ b/content/en/docs/deployment/mendix-cloud-deploy/_index.md @@ -137,7 +137,7 @@ Mendix apps cannot use custom ports. They communicate on the standard HTTP and H ### Number of End-Users for Licensed Apps -The number of end-users supported for your licensed app depends on your [pricing plan](#plans). End-users of your app are classified as either internal or external. You need to report this for licensing purposes, using either the [USAGE_METRICS_EMAIL_FIELDS custom variable](/developerportal/deploy/environments-details/#custom-environment-variables) (if you are using email domains to distinguish between end-users) or by [populating the user type](/developerportal/deploy/populate-user-type/) for each end-user of your app. Only end-users whose Mendix accounts are marked as **Active** are counted towards the number of end-users of the app. +The number of end-users supported for your licensed app depends on your [pricing plan](#plans). End-users of your app are classified as either internal or external. You need to report this for licensing purposes, using either the [USAGE_METRICS_EMAIL_FIELDS custom variable](/developerportal/deploy/environments-details/#custom-environment-variables) (if you are using email domains to distinguish between end-users) or by [Implementing User Metering](/developerportal/deploy/implementing-user-metering/) for each end-user of your app. Only end-users whose Mendix accounts are marked as **Active** are counted towards the number of end-users of the app. ### Supported Mendix Versions {#mendix-cloud-supported-versions} diff --git a/content/en/docs/deployment/mendix-cloud-deploy/environments-details.md b/content/en/docs/deployment/mendix-cloud-deploy/environments-details.md index ea2f3aef610..efd50032890 100644 --- a/content/en/docs/deployment/mendix-cloud-deploy/environments-details.md +++ b/content/en/docs/deployment/mendix-cloud-deploy/environments-details.md @@ -530,12 +530,12 @@ Click **Add** and select **Supported** to choose from the following variables: * **JVM_GARBAGE_COLLECTOR** – This overrides the automatic configuration of the Java garbage collector. Accepted values are `Serial` or `G1`. * **METRICS_AGENT_CONFIG** – This passes a configuration JSON to control the metrics passed to Datadog. * **SAMESITE_COOKIE_PRE_MX812** – This sets `SameSite=None;Secure` for all cookies coming from the Mendix runtime, as described in the [Running Your App in an Iframe](#iframe) section. -* **USAGE_METRICS_EMAIL_FIELDS** (deprecated) – If your app uses specializations of the `System.User` entity to store users, use this variable to point to them. This enables Mendix to identify [internal and external users](/developerportal/deploy/populate-user-type/) of your app. +* **USAGE_METRICS_EMAIL_FIELDS** (deprecated) – If your app uses specializations of the `System.User` entity to store users, use this variable to point to them. This enables Mendix to identify [internal and external users](/developerportal/deploy/implementing-user-metering/#user-classification) of your app. * The value of this variable is in the format `Module.Entity.Attribute`, where `Module` is the module of your app that contains the `Entity` that is a specialization of `System.User` and `Attribute` is the attribute that contains the email address of the user. * If you have multiple specializations of `System.User`, you can specify the values in comma-separated format (that is, `Module1.Entity1.Attribute1,Module2.Entity2.Attribute2,…,ModuleN.EntityN.AttributeN`). In the following example, there are two specializations identified: `Administration.Account.Email,MendixSSO.MendixSSOUser.EmailAddress`. - To ensure accurate user metering, it is important to distinguish external users from internal users. The recommended approach is to implement logic in your app to classify users (see [Populate User Types](/developerportal/deploy/populate-user-type/) and the [User Classification](/appstore/modules/user-classification/) module). A previous method relied on using email domains via the `USAGE_METRICS_EMAIL_FIELDS` constant, as described above. However, this method has now been deprecated. + To ensure accurate user metering, it is important to distinguish external users from internal users. The recommended approach is to implement logic in your app to classify users (see [Implementing User Metering](/developerportal/deploy/implementing-user-metering/) and the [User Classification](/appstore/modules/user-classification/) module). A previous method relied on using email domains via the `USAGE_METRICS_EMAIL_FIELDS` constant, as described above. However, this method has now been deprecated. Unsupported environment variables can only be used to control Mendix beta features. To configure an unsupported variable, click **Add** and select **Unsupported**. If you are using a beta feature, you will be informed what **Name** and **Value** to enter. diff --git a/content/en/docs/marketplace/platform-supported-content/modules/SAML/_index.md b/content/en/docs/marketplace/platform-supported-content/modules/SAML/_index.md index 4f45dc6311d..e66204ab87c 100644 --- a/content/en/docs/marketplace/platform-supported-content/modules/SAML/_index.md +++ b/content/en/docs/marketplace/platform-supported-content/modules/SAML/_index.md @@ -461,7 +461,7 @@ You can set up custom user provisioning by selecting the **IdP Configuration** t * **Allow the module to create users** – This enables the module to create users based on user provisioning and attribute mapping configurations. When disabled, it will still update existing users. However, for new users, it will display an exception message stating that the login action was successful but no user has been configured. * By default, the value is set to *Yes*. * **Default Userrole** – the role assigned to newly created users and remains unchanged even when the user's details are updated. You can select one default user role. To assign additional roles, use the Access Token Parsing Microflow. If the Access Token Processing Microflow is selected, OIDC verifies the updated default role configuration and applies any changes to the user's role. Note that, bulk updates for existing users are not automated when the default role configuration is changed. - * **User Type** – this allows you to configure end-users of your application as internal or external. It is created upon the creation of the user and updated each time the user logs in. For more information, see [Populate User Types](/developerportal/deploy/populate-user-type/). + * **User Type** – this allows you to configure end-users of your application as internal or external. It is created upon the creation of the user and updated each time the user logs in. For more information, see [Implementing User Metering](/developerportal/deploy/implementing-user-metering/). * By default, the value is set to *Internal*. 2. Under **Attribute Mapping**, for each piece of information you want to add to your custom user entity, select an **IdP Attribute** (claim) and specify the **Configured Entity Attribute** where you want to store the information. diff --git a/content/en/docs/marketplace/platform-supported-content/modules/scim/_index.md b/content/en/docs/marketplace/platform-supported-content/modules/scim/_index.md index 2ef26e39c59..3e3aa913b31 100644 --- a/content/en/docs/marketplace/platform-supported-content/modules/scim/_index.md +++ b/content/en/docs/marketplace/platform-supported-content/modules/scim/_index.md @@ -268,7 +268,7 @@ In the **Provisioning** section of the SCIM server configuration, you need to co * **Allow the module to create users**: this enables the module to create users based on user provisioning and attribute mapping configurations. * By default, the value is set to ***Yes***. * **Default Userrole** – the role assigned to newly created users and remains unchanged even when the user's details are updated. You can select one default user role. To assign additional roles, use the Access Token Parsing Microflow. If the Access Token Processing Microflow is selected, OIDC verifies the updated default role configuration and applies any changes to the user's role. Note that, bulk updates for existing users are not automated when the default role configuration is changed. -* **User Type**: this allows you to configure end-users of your application as internal or external. It is created when the user is created and updated whenever user details, such as name, email, or active status, are changed. For more information, see [Populate User Types](/developerportal/deploy/populate-user-type/). +* **User Type**: this allows you to configure end-users of your application as internal or external. It is created when the user is created and updated whenever user details, such as name, email, or active status, are changed. For more information, see [Implementing User Metering](/developerportal/deploy/implementing-user-metering/). * By default, the value is set to ***Internal***. * **Attribute Mapping**: under **Attribute Mapping**, select an **IdP Attribute** (claim) for each piece of information you want to add to your custom user entity. Specify the **Configured Entity Attribute** where you want to store the information. diff --git a/content/en/docs/marketplace/platform-supported-content/modules/user-classification.md b/content/en/docs/marketplace/platform-supported-content/modules/user-classification.md index c3349a308e6..0160a040097 100644 --- a/content/en/docs/marketplace/platform-supported-content/modules/user-classification.md +++ b/content/en/docs/marketplace/platform-supported-content/modules/user-classification.md @@ -6,7 +6,7 @@ description: "Describes the configuration and usage of the User Classification m ## Introduction -The [User Classification](https://marketplace.mendix.com/link/component/245015) module allows your Mendix application to accurately classify end-users—an essential capability for ensuring compliance with the [Mendix Pricing Plan](/developerportal/deploy/mendix-cloud-deploy/#plans). The module provides logic to set the [user type](/developerportal/deploy/populate-user-type/) as external or internal based on the user roles in your app. If needed, you can implement custom logic instead. Keep in mind that Mendix’s user metering processes will count users as internal unless their user type is explicitly set to external, which may impact licensing calculations. +The [User Classification](https://marketplace.mendix.com/link/component/245015) module allows your Mendix application to accurately classify end-users—an essential capability for ensuring compliance with the [Mendix Pricing Plan](/developerportal/deploy/mendix-cloud-deploy/#plans). The module provides logic to set the [user type](/developerportal/deploy/implementing-user-metering/#user-classification) as external or internal based on the user roles in your app. If needed, you can implement custom logic instead. Keep in mind that Mendix’s user metering processes will count users as internal unless their user type is explicitly set to external, which may impact licensing calculations. This document guides you in implementing the classification logic and configuring the required elements within your Mendix application. For details on the available classification logic options, see the [Configuring Classification Logic](#configure-classification-logic) section below. Using this module, organizations can ensure reliable user classification and maintain accurate metering within their Mendix environment. @@ -94,4 +94,4 @@ Based on your classification logic, use one of the above constants. If both cons ## Read More -* [Populate User Types](/developerportal/deploy/populate-user-type/) +* [Implementing User Metering](/developerportal/deploy/implementing-user-metering/) diff --git a/static/attachments/deployment/general/populate-user-type/user-type-enumeration.png b/static/attachments/deployment/general/implementing-user-metering/user-type-enumeration.png similarity index 100% rename from static/attachments/deployment/general/populate-user-type/user-type-enumeration.png rename to static/attachments/deployment/general/implementing-user-metering/user-type-enumeration.png diff --git a/static/attachments/deployment/general/populate-user-type/correct-user-type.png b/static/attachments/deployment/general/populate-user-type/correct-user-type.png deleted file mode 100644 index 01c9815683c..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/correct-user-type.png and /dev/null differ diff --git a/static/attachments/deployment/general/populate-user-type/grid-data-source.png b/static/attachments/deployment/general/populate-user-type/grid-data-source.png deleted file mode 100644 index 749510fa048..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/grid-data-source.png and /dev/null differ diff --git a/static/attachments/deployment/general/populate-user-type/grid-general.png b/static/attachments/deployment/general/populate-user-type/grid-general.png deleted file mode 100644 index 77aa08ed056..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/grid-general.png and /dev/null differ diff --git a/static/attachments/deployment/general/populate-user-type/retrieve-userreportinfo.png b/static/attachments/deployment/general/populate-user-type/retrieve-userreportinfo.png deleted file mode 100644 index 363c7e428ab..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/retrieve-userreportinfo.png and /dev/null differ diff --git a/static/attachments/deployment/general/populate-user-type/set-user-type.png b/static/attachments/deployment/general/populate-user-type/set-user-type.png deleted file mode 100644 index 8666488c322..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/set-user-type.png and /dev/null differ diff --git a/static/attachments/deployment/general/populate-user-type/user-type-report.png b/static/attachments/deployment/general/populate-user-type/user-type-report.png deleted file mode 100644 index 6d2d780145f..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/user-type-report.png and /dev/null differ diff --git a/static/attachments/deployment/general/populate-user-type/user-type-split.png b/static/attachments/deployment/general/populate-user-type/user-type-split.png deleted file mode 100644 index 68e19cc06d0..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/user-type-split.png and /dev/null differ diff --git a/static/attachments/deployment/general/populate-user-type/usertypereport-properties.png b/static/attachments/deployment/general/populate-user-type/usertypereport-properties.png deleted file mode 100644 index 47ecebf9101..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/usertypereport-properties.png and /dev/null differ diff --git a/static/attachments/deployment/general/populate-user-type/usertypereport.png b/static/attachments/deployment/general/populate-user-type/usertypereport.png deleted file mode 100644 index 54e367f0b92..00000000000 Binary files a/static/attachments/deployment/general/populate-user-type/usertypereport.png and /dev/null differ