From 95a735e729750941571e0eec96988749954b8a0a Mon Sep 17 00:00:00 2001 From: Amy Blais <29708087+amyblais@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:05:01 +0300 Subject: [PATCH 1/9] Update conf.py --- source/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/conf.py b/source/conf.py index 84429f2a9cc..9cce1a62c66 100644 --- a/source/conf.py +++ b/source/conf.py @@ -526,9 +526,9 @@ def setup(app: Sphinx): # built documents. # # The short X.Y version. -# version = '11.8' +# version = '11.9' # The full version, including alpha/beta/rc tags. -# release = '11.8' +# release = '11.9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From 094da26d7e545d1d86cfbce1313453a1effd26f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20V=C3=A9lez?= Date: Mon, 22 Jun 2026 13:00:15 +0200 Subject: [PATCH 2/9] MM-68992 - add attribute value masking documentation (#9000) * MM-68992 - add attribute value masking documentation * add details about access mode --- .../admin/abac-channel-access-rules.rst | 4 ++++ .../admin/abac-system-wide-policies.rst | 21 ++++++++++++++++++- .../manage/admin/user-attributes.rst | 13 ++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/source/administration-guide/manage/admin/abac-channel-access-rules.rst b/source/administration-guide/manage/admin/abac-channel-access-rules.rst index db3bcb29d59..0208362ef27 100644 --- a/source/administration-guide/manage/admin/abac-channel-access-rules.rst +++ b/source/administration-guide/manage/admin/abac-channel-access-rules.rst @@ -71,6 +71,10 @@ The **Auto-add members based on access rules** toggle controls automatic members - When no rules are configured, this toggle is automatically disabled. - Regardless of the auto-sync setting, users who no longer meet required attribute rules are always removed during synchronization. +.. note:: + + If a policy rule references attribute values from a ``shared_only`` or ``source_only`` attribute that you don't personally hold, those values appear as ``--------`` and the row is read-only. Test and Delete actions are also disabled for those rows. See :ref:`Attribute value masking ` for details. + Validation and safety ~~~~~~~~~~~~~~~~~~~~~ diff --git a/source/administration-guide/manage/admin/abac-system-wide-policies.rst b/source/administration-guide/manage/admin/abac-system-wide-policies.rst index b44cccdadbc..86345c5f498 100644 --- a/source/administration-guide/manage/admin/abac-system-wide-policies.rst +++ b/source/administration-guide/manage/admin/abac-system-wide-policies.rst @@ -130,4 +130,23 @@ Permission policies can be used to restrict the following actions based on user When a permission policy applies, users who don't match the configured attribute values can't perform the restricted action. Users may see file attachments as unavailable or redacted in messages they would otherwise have access to. See :ref:`Restricted file attachments ` for the end-user-facing behavior. -Permission policies follow the same unique-name requirement as access policies: each parent permission policy must have a unique name, and Mattermost surfaces a user-friendly error if a duplicate name is entered. \ No newline at end of file +Permission policies follow the same unique-name requirement as access policies: each parent permission policy must have a unique name, and Mattermost surfaces a user-friendly error if a duplicate name is entered. + +Attribute value masking +----------------------- + +From Mattermost v11.8, when a policy references attribute values that the editing admin doesn't personally hold, those values are hidden in the policy editor. This prevents admins from reading or copying sensitive attribute values they're not authorized to see, while still allowing the policy to enforce access control normally. + +Masking only applies to attributes configured with a ``shared_only`` or ``source_only`` access mode. Attributes with a ``public`` access mode are always visible to all admins. See :ref:`Attribute access modes ` for details on how each mode controls value visibility. + +**What you'll see:** + +- Masked values appear as ``--------`` in the rule editor instead of the raw value. +- Rows containing masked values are **read-only** and cannot be modified. +- **Test rule** and **Delete** actions are disabled for rules that contain masked values. + +**Enforcement is unaffected:** masking applies to the editing UI only. The underlying rules continue to control channel access and permissions as configured. + +**To edit a masked rule**, ask the policy owner or another System Admin who holds the relevant attribute values to make the change. + +This behavior applies to both the table editor and the CEL editor, and also to Team Admin and Channel Admin policy editors in Team Settings and Channel Settings. Requires Enterprise Advanced license and the ``AttributeValueMasking`` feature flag. \ No newline at end of file diff --git a/source/administration-guide/manage/admin/user-attributes.rst b/source/administration-guide/manage/admin/user-attributes.rst index 1a85f7ab892..d792a3c68d4 100644 --- a/source/administration-guide/manage/admin/user-attributes.rst +++ b/source/administration-guide/manage/admin/user-attributes.rst @@ -140,6 +140,19 @@ Manage attributes In cases where multiple system admins manage system attributes, refresh your web browser instance to see real-time updates to system attributes made by other admins. +Attribute access modes +----------------------- + +Each user attribute has an **access mode** that controls who can see its values when those values appear in access control policies. The access mode is set per attribute and determines whether an admin editing a policy can see the raw attribute values referenced in its rules. + +Access modes are not configurable through the System Console. They can only be set programmatically by a Mattermost plugin using the `Property Fields API `_. Attributes created by system admins through the System Console always use the ``public`` access mode. A plugin that needs to restrict attribute visibility must create the field with ``protected: true`` and set the desired ``access_mode`` — this is typically done by plugins that sync sensitive attributes from an external identity source and need to control which admins can read those values. + +- **Public** (default): The attribute value is visible to all admins editing policies that reference it. No masking is applied. +- **Shared only**: The attribute value is only visible to admins who personally hold that same value. Admins who don't hold the value see it masked (``--------``) in the policy editor. +- **Source only**: The attribute value is only visible to the system source that set it (for example, the identity provider). All admins see it masked in the policy editor regardless of their own attribute values. + +Masking in the policy editor only applies to attributes with ``shared_only`` or ``source_only`` access mode. See :ref:`Attribute value masking ` for the editor behavior when masked values are present. + Sync attributes with your identity provider -------------------------------------------- From c31cca02ac2fc30577b8875d907c822afd8cb38b Mon Sep 17 00:00:00 2001 From: Bill Gardner Date: Mon, 22 Jun 2026 17:52:03 -0400 Subject: [PATCH 3/9] Document experimental video calls in DMs (Calls v1.12.0) (#9050) * Document experimental video calls in DMs (Calls v1.12.0) * Note external RTCD v1.2.2+ requirement for DM video calls --- .../plugins-configuration-settings.rst | 33 ++++++++++++++++++- .../end-user-guide/collaborate/make-calls.rst | 6 +++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/source/administration-guide/configure/plugins-configuration-settings.rst b/source/administration-guide/configure/plugins-configuration-settings.rst index 028bce0d3af..bc7722aa4e7 100644 --- a/source/administration-guide/configure/plugins-configuration-settings.rst +++ b/source/administration-guide/configure/plugins-configuration-settings.rst @@ -1029,7 +1029,38 @@ Enable AV1 (Experimental) .. note:: - Avoid enabling both this experimental configuration setting and the `Enable simulcast for screen sharing <#enable-simulcast-for-screen-sharing-experimental>`__ experimental configuration setting at the same time. + Avoid enabling both this experimental configuration setting and the `Enable simulcast for screen sharing <#enable-simulcast-for-screen-sharing-experimental>`__ experimental configuration setting at the same time. + +.. config:setting:: enable-pluginsvideo + :displayname: Enable video calls in DMs (Experimental) (Plugins - Calls) + :systemconsole: Plugins > Calls + :configjson: PluginSettings.Plugins.com.mattermost.calls.enablevideo + :environment: MM_CALLS_ENABLE_VIDEO + + - **true**: Enables experimental video calls in direct message (DM) channels. + - **false**: **(Default)** Video calls are disabled. + +Enable video calls in DMs (Experimental) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++--------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| - **true**: Enables experimental video calls in direct message (DM) | - System Config path: **Plugins > Calls** | +| channels. | - ``config.json`` setting: ``PluginSettings`` > ``Plugins`` > ``com.mattermost.calls`` > ``enablevideo`` | +| - **false**: **(Default)** Video calls are disabled. | - Environment variable: ``MM_CALLS_ENABLE_VIDEO`` | +| | | +| Video is supported in DM calls on the desktop and web apps only. Mobile | | +| users can't start video calls; when joining a DM call that includes | | +| video, they receive voice and screen sharing only. Call recordings | | +| capture voice and screen sharing only — video isn't recorded. | | ++--------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ + +.. note:: + + The ability to enable video calls in DMs is currently :ref:`Experimental `. + +.. note:: + + If your deployment offloads calls to the :doc:`RTCD service `, video in DM calls requires **rtcd v1.2.2 or later**. We recommend running the rtcd version that ships with your Calls plugin release (rtcd v1.2.5 for Calls v1.12.0) and keeping rtcd updated alongside the plugin. Deployments that use the plugin's built-in RTC server (no RTCD) support video without additional configuration. .. config:setting:: enable-pluginsdcsignaling :displayname: Use data channels for signaling media tracks (Plugins - Calls) diff --git a/source/end-user-guide/collaborate/make-calls.rst b/source/end-user-guide/collaborate/make-calls.rst index 8853a61cd68..ea2704f957b 100644 --- a/source/end-user-guide/collaborate/make-calls.rst +++ b/source/end-user-guide/collaborate/make-calls.rst @@ -249,7 +249,11 @@ Yes! From Mattermost v8.0 and Calls v0.17.0, desktop app and web users can go to Is video supported? ~~~~~~~~~~~~~~~~~~~ -The integration currently supports only voice calling and screen sharing. We're considering video support in the future. +From Mattermost Calls plugin v1.12.0, experimental video support is available in direct message (DM) calls on the desktop and web apps. It's disabled by default; a system admin can enable it using the :ref:`Enable video calls in DMs (Experimental) ` plugin setting in the System Console. The following limitations apply: + +- Video is available in DM calls only. All other calls continue to support voice calling and screen sharing only. +- Video isn't available on the mobile app. Mobile users can't start a video call, and when they join a DM call that includes video, it behaves like an audio call — they hear voice and see shared screens, but don't see video. +- Call recordings don't capture video. Recordings include voice and screen sharing only. Can I password-protect a call? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From f25be70ec9e3e3650ac705740606a6c53899ee6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Garc=C3=ADa=20Montoro?= Date: Tue, 30 Jun 2026 12:06:11 +0200 Subject: [PATCH 4/9] MM-69311: Document new metric: mattermost_cluster_reliable_fallback_tcp (#9068) * Document mattermost_cluster_reliable_fallback_tcp * Update source/administration-guide/scale/performance-monitoring-metrics.rst Co-authored-by: Amy Blais <29708087+amyblais@users.noreply.github.com> --------- Co-authored-by: Amy Blais <29708087+amyblais@users.noreply.github.com> --- .../scale/performance-monitoring-metrics.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/source/administration-guide/scale/performance-monitoring-metrics.rst b/source/administration-guide/scale/performance-monitoring-metrics.rst index c2a373f8743..3fafb392142 100644 --- a/source/administration-guide/scale/performance-monitoring-metrics.rst +++ b/source/administration-guide/scale/performance-monitoring-metrics.rst @@ -37,6 +37,7 @@ Cluster metrics - ``mattermost_cluster_cluster_health_score``: A score that gives an idea of how well it is meeting the soft-real time requirements of the gossip protocol. - ``mattermost_cluster_cluster_requests_total``: The total number of inter-node requests. - ``mattermost_cluster_cluster_event_type_totals``: The total number of cluster requests sent for any type. +- ``mattermost_cluster_reliable_fallback_tcp``: The total length in bytes of the ``SendBestEffort`` calls (UDP) that had to fallback to ``SendReliable`` (TCP) because of the message length. This is a histogram with 8 buckets, from 32KiB to 4MiB. Ideally, the count of this metric should be always 0, but plugins may be misusing the websocket API and attempting to send large messages via UDP; in that case, plugins should be fixed to set `ReliableClusterSend `__ to true. Database metrics ~~~~~~~~~~~~~~~~ From f9c50fed21768f61f28aa715747a83922969e804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20V=C3=A9lez?= Date: Thu, 9 Jul 2026 17:07:34 +0200 Subject: [PATCH 5/9] Document DCR redirect URI allowlist wildcard and query matching behavior (#9065) Co-authored-by: Eric Sethna <14333569+esethna@users.noreply.github.com> --- .../configure/integrations-configuration-settings.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/administration-guide/configure/integrations-configuration-settings.rst b/source/administration-guide/configure/integrations-configuration-settings.rst index 769a07f6317..f9309a2f39e 100644 --- a/source/administration-guide/configure/integrations-configuration-settings.rst +++ b/source/administration-guide/configure/integrations-configuration-settings.rst @@ -176,6 +176,15 @@ In the System Console, enter URIs as a comma-separated list. When setting this v This setting applies only when :ref:`Enable dynamic client registration ` is enabled. +Redirect URIs are matched per URL component. Patterns support two wildcards: + +- ``*`` matches any characters except ``/`` (for example, a single path segment or a hostname label). +- ``**`` matches any characters including ``/`` (for example, a multi-segment path). + +Wildcards are applied within URL components only: host wildcards match against the host, path wildcards match against the path, and a wildcard in one component can't satisfy another component. For example, ``https://*.example.com/**`` matches ``https://app.example.com/callback`` but not ``https://attacker.example.net``. + +Query strings are matched only when the pattern explicitly includes one. A pattern without a query string (such as ``https://app.example.com/callback`` or ``https://app.example.com/**``) matches only redirect URIs that have no query string. To allow redirect URIs that carry query parameters, include a query component in the pattern, for example ``https://app.example.com/callback?tenant=*``. To allow a callback both with and without a query string, add both patterns. + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | This feature's ``config.json`` setting is ``"DCRRedirectURIAllowlist": []`` with string array input, such as ``["https://example.com/callback", "https://app.example.com/oauth"]``. | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ From dfb44a71da403fe5c81914cb682296f55393891b Mon Sep 17 00:00:00 2001 From: David Krauser Date: Fri, 10 Jul 2026 01:46:10 -0400 Subject: [PATCH 6/9] Document the Ranked attribute type (#9086) Add a Ranked entry to the user-attribute type list, document its ordered comparison operators in the system-wide access policy match options, and note that classification markings use the same Ranked attribute type. Co-authored-by: Claude Opus 4.8 --- .../configure/site-configuration-settings.rst | 2 +- .../manage/admin/abac-system-wide-policies.rst | 10 +++++++++- .../manage/admin/user-attributes.rst | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/source/administration-guide/configure/site-configuration-settings.rst b/source/administration-guide/configure/site-configuration-settings.rst index 12e68c314c8..839b5074260 100644 --- a/source/administration-guide/configure/site-configuration-settings.rst +++ b/source/administration-guide/configure/site-configuration-settings.rst @@ -2620,7 +2620,7 @@ Classification Markings From Mattermost v11.8, system admins can configure classification markings in the System Console by going to **Site Configuration > Classification Markings**. -Classification markings define reusable classification levels that can be displayed as global or channel-level banners in the web and desktop apps. Each classification level includes a name, color, and rank order. You can select a preset, such as US DoD, NATO, UK GSCP, Canada, or Australia PSPF, or define custom classification levels. +Classification markings define reusable classification levels that can be displayed as global or channel-level banners in the web and desktop apps. Each classification level includes a name, color, and rank order. You can select a preset, such as US DoD, NATO, UK GSCP, Canada, or Australia PSPF, or define custom classification levels. Levels are ordered using the same **Ranked** attribute type available for :doc:`user attributes `, so each level sits at a defined position from lowest to highest. .. note:: diff --git a/source/administration-guide/manage/admin/abac-system-wide-policies.rst b/source/administration-guide/manage/admin/abac-system-wide-policies.rst index 1ecb0213615..c5b22e53a93 100644 --- a/source/administration-guide/manage/admin/abac-system-wide-policies.rst +++ b/source/administration-guide/manage/admin/abac-system-wide-policies.rst @@ -44,7 +44,15 @@ You can add multiple rules to a single policy, and each rule can include multipl - **Ends with**: The attribute value must end with the specified value. - **Contains**: The attribute value must exist somewhere with the specified value. - 3. Specify the attribute values that users must have to be granted access to the channel. + When the selected attribute is a **Ranked** attribute (an ordered list of values, such as clearance or classification levels), the match options are ordered comparisons instead. These let you match everyone at or above a threshold rather than only an exact value: + + - **Is exactly** / **Is not**: The value must exactly match, or must not match, the specified value. + - **Is at least**: The value must be equal to or higher than the specified value - for example, clearance *is at least* Secret matches Secret and every higher level. + - **Is greater than**: The value must be higher than the specified value. + - **Is at most**: The value must be equal to or lower than the specified value. + - **Is less than**: The value must be lower than the specified value. + + 3. Specify the attribute values that users must have to be granted access to the channel. .. tab:: Advanced Mode diff --git a/source/administration-guide/manage/admin/user-attributes.rst b/source/administration-guide/manage/admin/user-attributes.rst index d792a3c68d4..c05430b7211 100644 --- a/source/administration-guide/manage/admin/user-attributes.rst +++ b/source/administration-guide/manage/admin/user-attributes.rst @@ -101,6 +101,7 @@ From Mattermost v11.8, user attributes include both a **Display Name** and a **N - **URL** for web site address-based profile attributes. - **Select** for a list of profile attribute values users can choose from. Specify each value followed by pressing **TAB** or **ENTER**. Values can be up to 64 characters long, and users can choose a single value. - **Multi-select** for a list of profile attribute values users can select from. Specify each value followed by pressing **TAB** or **ENTER**. Values can be up to 64 characters long, and users can choose multiple values. + - **Ranked** for an ordered list of values, where each value ranks higher or lower than the others - for example, clearance or classification levels such as *Public*, *Secret*, and *Top Secret*. Specify each value, then order the values from lowest to highest rank. Users can choose a single value. Because the values are ordered, :doc:`access control policies ` can compare a ranked attribute against a threshold - for example, clearance *is at least* Secret - rather than only checking for an exact match. 3. Specify the attribute's visibility as one of the following: From c64e02f1bc2ddedebc178c59c8999471f5ace588 Mon Sep 17 00:00:00 2001 From: "changelog-automation-docs[bot]" <278388344+changelog-automation-docs[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 09:56:27 +0300 Subject: [PATCH 7/9] v11.9.0 Changelog (#9053) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: add changelog for v11.9.0 * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update source/product-overview/mattermost-v11-changelog.md Co-authored-by: Christopher Poile * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Add 3 bug fix release notes to v11.9.0 changelog * Update source/product-overview/mattermost-v11-changelog.md Co-authored-by: Christopher Poile * Update mattermost-v11-changelog.md * Add Jira plugin v4.7.1 release note to v11.9.0 changelog * Fix: use Pre-packaged for Jira plugin v4.7.1 release note * Add attribute value masking information to 11.8.0 changelog docs (#9076) * Add attribute value masking information to 11.8.0 changelog docs * move changes under v11.9 section * Add inline link for attribute value masking in v11.9 changelog * Update Agents plugin version from v2.4.1 to v2.4.2 in v11.9 changelog * Add Global Relay crash fix to v11.9 Bug Fixes section * Add Global Relay fix to v11.9 Bug Fixes with correct wording * Add inline link for metric on line 106 * Update v11.9 changelog: bug fix, feature flag note, Calls v1.12.1 * Fix formatting: backticks for feature flags, bold for Channel Settings Permissions Policy * Update source/product-overview/mattermost-v11-changelog.md Co-authored-by: Maria A Nunez * Update v11.9 changelog: replace feature flag line 110 with ChannelPermissionPolicies/PolicySimulation description * Add PropertyGroups and channelbookmarks schema changes to v11.9 changelog * Update mattermost-v11-changelog.md * Add ChannelGuards schema change to v11.9 changelog * Add stale config refresh fix to v11.9 changelog * Update mattermost-v11-changelog.md * Add Bot Accounts pagination fix to v11.9 changelog * Remove duplicate Boards plugin version line * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md * Update mattermost-v11-changelog.md --------- Co-authored-by: Changelog Bot Co-authored-by: Amy Blais <29708087+amyblais@users.noreply.github.com> Co-authored-by: Christopher Poile Co-authored-by: Pablo Vélez Co-authored-by: Maria A Nunez --- .../mattermost-v11-changelog.md | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/source/product-overview/mattermost-v11-changelog.md b/source/product-overview/mattermost-v11-changelog.md index 11f8f806e51..78d0be0bad3 100644 --- a/source/product-overview/mattermost-v11-changelog.md +++ b/source/product-overview/mattermost-v11-changelog.md @@ -13,6 +13,170 @@ Platform and OS scope reflects reported and tested environments and may not represent all affected configurations. ``` +(release-v11.9-feature-release)= +## Release v11.9 - [Feature Release](https://docs.mattermost.com/product-overview/release-policy.html#release-types) + +**Release day: 2026-07-16** + +```{Attention} +**Breaking Changes** + - Mattermost v11.9 changes how redirect URI allowlist patterns are matched for OAuth Dynamic Client Registration (DCR). Patterns are now evaluated per URL component (scheme, host, path, and query) rather than as a whole-string glob. See the [Important Upgrade Notes](https://docs.mattermost.com/upgrade/important-upgrade-notes.html) for more details. +``` + +### Upgrade Impact + +#### Database Schema Changes + - The following schema changes are included in the v11.9 release. No database downtime is expected for this upgrade. See the [Important Upgrade Notes](https://docs.mattermost.com/upgrade/important-upgrade-notes.html) for more details. + - Added the ``voipdeviceid`` column to the ``sessions`` table to support VoIP device tracking; metadata-only DDL on PostgreSQL 11+, minimal performance impact expected. + - Added composite index ``idx_access_control_policies_type_id`` on ``AccessControlPolicies(Type, Id)`` to improve policy lookup performance with no downtime or blocking impact. + - Removed orphaned ``threadmemberships`` rows where the user is no longer a channel member; irreversible data-only migration that may run slowly on large instances. + - Added a ``lastused`` column to ``incomingwebhooks`` with a negligible-duration catalog-only lock and no downtime required. + - Added ``'rank'`` to the ``property_field_type`` enum via a catalog-only ``ALTER TYPE`` statement; no user-table locks are acquired and no downtime is required for the upgrade. + - Converted up to three classification-marking ``PropertyFields`` from type ``'select'`` to ``'rank'`` and backfilled rank ordering into their options; negligible performance impact. + - Added ``rank``-type support to the ``AttributeView`` materialized view so ABAC policies can evaluate ranked property options; no performance impact expected on feature-flagged deployments. + - Renamed ``system_classification`` and ``channel_classification`` entries in ``PropertyFields`` to the canonical name ``classification``; affects at most two rows with no performance impact. + - Added an ``expiresat`` column and partial index to ``useraccesstokens`` to support PAT expiry enforcement, with no large-table impact or downtime required. + - Added a ``SchemaVersion`` column to ``PropertyGroups`` with no large-table impact or downtime required. + - Added a ``targetid`` column and ``idx_channelbookmarks_type_targetid`` index to ``channelbookmarks`` to support a new ``board`` bookmark type, with no impact to existing bookmarks or downtime required. + - Added the ``ChannelGuards`` table and a ``PluginId`` index to support plugin-exclusive channel ownership, with no downtime or backwards-compatibility impact. + +#### config.json +New setting options were added to ``config.json``. Below is a list of the additions and their default values on install. The settings can be modified in ``config.json``, or the System Console when available. + - **Changes to All plans:** + - Under ``AccessControlSettings`` in ``config.json``, added ``EnforceDeviceIDConsistency`` configuration setting to enforce device ID consistency across sessions. + - Under ``AccessControlSettings`` in ``config.json``, added ``TrustProxyDeviceIdentityHeader`` configuration setting to trust a proxy-supplied device identity header for session attribute collection. + - **Changes to All plans:** + - Under ``FileSettings`` in ``config.json``, added ``AzureStorageAccount``, ``AzureAccessKey``, ``AzureContainer``, ``AzurePathPrefix``, ``AzureEndpoint``, ``AzureSSL``, and ``AzureRequestTimeoutMilliseconds`` configuration settings for Azure Blob Storage filestore backend support. + - Under ``FileSettings`` in ``config.json``, added ``AzureCloud``, ``ExportAzureCloud``, ``AzureAuthMode``, ``ExportAzureAuthMode``, and ``ExportAzurePresignExpiresSeconds`` configuration settings for Azure Blob Storage support. + - Under ``FileSettings`` in ``config.json``, added ``ExtractContentTimeout`` configuration setting to limit how long a single uploaded document's content extraction occupies a worker (default 10 seconds). + - Under ``ServiceSettings`` in ``config.json``, added ``MaximumPersonalAccessTokenLifetimeDays`` configuration setting to require personal access tokens to expire within a configured maximum lifetime (``0`` imposes no policy). + +```{Important} +If you upgrade from a release earlier than v11.8, please read the other [Important Upgrade Notes](https://docs.mattermost.com/administration-guide/upgrade/important-upgrade-notes.html). In case of an upgrade failure, please check the [Downgrade Guide](https://docs.mattermost.com/administration-guide/upgrade/downgrading-mattermost-server.html) and the [Recovery Guide](https://docs.mattermost.com/deployment-guide/backup-disaster-recovery.html) for rollback steps and interim mitigation strategy. +``` + +### Improvements +See [this blog post](https://mattermost.com/blog/mattermost-v11-9-0-is-now-available/) on the highlights in our latest release. + +#### User Interface + - Pre-packaged Jira plugin version [v4.7.1](https://github.com/mattermost/mattermost-plugin-jira/releases/tag/v4.7.1). + - Pre-packaged Playbooks plugin version [v2.10.0](https://github.com/mattermost/mattermost-plugin-playbooks/releases/tag/v2.10.0). + - Pre-packaged Agents plugin version [v2.4.2](https://github.com/mattermost/mattermost-plugin-agents/releases/tag/v2.4.2). + - Pre-packaged [Calls plugin](https://docs.mattermost.com/end-user-guide/collaborate/make-calls.html) version [v1.12.1](https://github.com/mattermost/mattermost-plugin-calls/releases/tag/v1.12.1). + - Pre-packaged Boards plugin version [v9.3.0](https://github.com/mattermost/mattermost-plugin-boards/releases/tag/v9.3.0). + - Pre-packaged GitLab plugin version [v1.13.0](https://github.com/mattermost/mattermost-plugin-gitlab/releases/tag/v1.13.0). + - Added zoom and pan support to the image file preview: use the scroll wheel to zoom at the cursor, click-and-drag to pan, and +/-/0 keyboard shortcuts (reported on webapp). + - Added a toast notification for plugin-rejected file uploads, consistent with the existing notification for rejected downloads. + - Added a Data Spillage Handling feature discovery page in the System Console for lower-tier licenses. + - Added clearer validation messaging for invalid user attribute names in the System Console. + - Incoming webhooks now show information about the last time they were triggered. + - Threads started by a webhook are no longer highlighted for the user who owns the webhook. + - Added user setting "Auto-follow threads on channel-wide mentions" (Settings → Notifications). When disabled, @channel/@all/@here mentions no longer force thread membership; users still receive mention notifications but must manually follow the thread. + - Hardened the web app against crashes caused by components rendered by a plugin. + +#### Plugins/Integrations + - Implemented clickable action buttons inside post markdown for bots, webhooks, and plugins. Integrations bind ``mmaction://`` markdown links to actions defined in a new ``mm_blocks_actions`` post property. + - Added channel bookmark type ``board`` with an optional ``target_id``. The bookmarks API rejects creating, updating, or deleting board bookmarks but allows reordering them when the caller has bookmark order permission. + - Added a webapp hook ``registerChannelTypeOption``. + - Added a ``MessagesWillBeConsumedWithContext`` plugin hook. + - Added a ``ChannelWillBeUpdated`` plugin hook. + - Added a ``ChannelWillBeRestored`` plugin hook. + - Added a ``ScheduledPostWillBeCreated`` plugin hook. + - Added a ``DraftWillBeUpserted`` plugin hook. + - Added a webapp hook ``registerChannelIconOverride``. + - Added a webapp hook ``registerChannelComposerBannerComponent``. + - Added a webapp hook ``registerPostHeaderComponent``. + - Added a webapp hook ``registerComposerPlaceholder``. + - Added a webapp hook ``registerProductSwitcherMenuItem``. + - Added ``RegisterChannelGuard`` and ``UnregisterChannelGuard`` plugin api methods. + +#### Administration + - Added [Azure Blob Storage](https://docs.mattermost.com/administration-guide/configure/azure-blob-storage.html) support. + - Added Azure Blob Storage as a selectable backend in the File Storage and Export Storage admin console panels. The S3 Test Connection control is now backend-agnostic and validates the active driver. + - Added an Azure Cloud selector to the Azure Blob Storage admin panels with built-in support for Azure Commercial and Azure Government endpoints. Choose "Custom Endpoint" to point at Azurite, a reverse proxy, or any other Azure cloud by providing the full Blob service URL. + - Added a Microsoft Entra ID / ``DefaultAzureCredential`` authentication mode to the Azure Blob Storage admin panels alongside the existing shared-key path. Select "Default credential (Microsoft Entra ID)" to authenticate via managed identity, workload identity, service principal environment variables, or ``az login`` — whichever the host environment provides — with no access key required. + - Added Azure Blob Storage support for the optional presigned export-download feature (``EnableExportDirectDownload``). Bulk-export downloads now generate a time-limited Shared Access Signature when the export backend is Azure, matching the existing S3 behavior. A new ``FileSettings.ExportAzurePresignExpiresSeconds`` configuration field controls the SAS lifetime (defaults to 6 hours, capped at Azure's 7-day SAS limit). + - Added validation of the Azure file storage account name and routed Azure custom-endpoint requests through the standard outbound HTTP transport. + - Added SAML connectivity status and error diagnostics to support packet output. + - Added OAuth2/OpenID Connect provider connectivity status (GitLab, Google, Office365, OpenID) to the support packet diagnostics. + - Added database diagnostics to the support packet, covering connection pool stats on every supported driver and PostgreSQL aggregate performance indicators (cache hit ratio, deadlocks, temp files, lock wait/idle activity, longest running query, and Posts autovacuum/dead tuples). Per-query timeouts and partial-failure handling keep packet generation resilient when individual pg_stat queries fail. + - Personal access tokens can now be required to expire within a configured maximum lifetime via the new ``MaximumPersonalAccessTokenLifetimeDays`` System Console setting (non-zero = expiry required and capped to that many days; ``0``, the default, imposes no policy). The policy applies only to newly created tokens; bot tokens are exempt. The ``POST /users/{id}/tokens`` endpoint now accepts a client-supplied ``expires_at`` (Unix millis), and ``mmctl user token generate`` gained an ``--expires-in`` flag (e.g. ``--expires-in 90d``) for creating expiring tokens via CLI. Added an ``ExpiresAt`` column to the ``UserAccessTokens`` table and enforced expiry at token validation time. Expired personal access tokens are now rejected with HTTP 401 and reaped hourly by a new background job (``cleanup_expired_access_tokens``); audit events are emitted on rejection (``rejectExpiredUserAccessToken``) and reap (``expireUserAccessToken``). Tokens with ``ExpiresAt = 0`` remain non-expiring, preserving behavior for all pre-existing tokens. Added an expiry chooser to the **Personal Access Token** creation user interface in **Account Settings**, backed by the new ``ServiceSettings.MaximumPersonalAccessTokenLifetimeDays`` admin policy, which is now also configurable in the ``System Console`` under ``Integrations > Integration Management``. The token list (user and admin) shows each token's expiry and status (active / expired / disabled) with a warning when a token is within 7 days of expiry. + - Added a pre-migration setup to fix incorrect database migration numbers that prevented upgrading Mattermost from v10.11 to v11.7. + - Added a new ``FileSettings.ExtractContentTimeout`` setting (default 10 seconds) that limits how long a single uploaded document's content extraction occupies a worker, and moved document content extraction to a dedicated, non-blocking worker pool so it no longer delays file uploads for other users. + - Stopped logging the email subject in the "sending mail" server log to prevent potential exposure of PII such as sender names from Direct Message and mention notifications. + - Enabled CJK (Chinese, Japanese, Korean) search by default for PostgreSQL. + - Added support for OpenSearch v3, while continuing to support OpenSearch v2. + - User attributes can now be synced with AD/LDAP or SAML whether they are user-editable or admin-managed. When an attribute is synced, the "Editable by users" toggle is disabled; remove the sync link to change it again. + - Added [attribute value masking](https://docs.mattermost.com/administration-guide/manage/admin/abac-system-wide-policies.html) for access control policies: admins who don't hold specific attribute values see a masked placeholder (``--------``) instead of the raw value, with affected rule rows set to read-only and save/delete actions disabled. Applies to the table editor, CEL editor, and team settings modal. Requires Enterprise Advanced license. + - Added support for iOS Calls ring for Direct/Group Message channels. + - Expanded session attribute collection to include values provided by Desktop App and Mobile clients. + - Removed legacy interactive dialog code path on webapp. + - Added a channel-guard enforcement for scheduled posts and drafts. + - Added Phase 8b, 8c, 8d, 8e, 8f, 8h, 12, and 12e of the ``mbe-tech-preview``. + - Added a ``mattermost db ping`` [subcommand](https://docs.mattermost.com/deployment-guide/reference-architecture/deployment-scenarios/air-gapped-deployment.html) that waits for the database to become reachable, with configurable ``--timeout`` and ``--retry-interval`` flags. + - Added a new "rank" [custom profile attribute](https://docs.mattermost.com/administration-guide/manage/admin/abac-system-wide-policies.html#define-access-control-policies) type whose options carry an explicit ordering. System Admins can create and manage ranked attributes in the **System Console** and assign ranked values to users, enabling attribute-based access control policies that compare clearance- or classification-style attributes with ordinal operators (for example, "is at least Secret") instead of enumerating every qualifying value. + - Added a new ``ClusterReliableFallbackLength`` [metric](https://docs.mattermost.com/administration-guide/scale/performance-monitoring-metrics.html) with the total length in bytes of the ``SendBestEffort`` calls (UDP) that had to fallback to TCP because of the message length. + - Made ``SendBestEffort`` cluster messages fall back to using TCP when their length is larger than a UDP datagram. + - Added a license preview and diff view when uploading a new license in the System Console, allowing administrators to compare the new license's features with the current license before applying. + - Added a new ``mattermost_system_server_info`` Prometheus metric that exposes the server version and build hash as labels. + - Enabled support for [permission-action rules](https://docs.mattermost.com/administration-guide/manage/admin/attribute-based-access-control.html) (file upload, file download) on channel-scope access control policies, with a new "Simulate access" modal in System Console and Channel Settings that previews per-user, per-action decisions before saving. Requires the Enterprise Advanced license. + +#### Performance + - Benchmarking test results showed no significant difference: a +1.44% increase in the number of supported users for the new release, which lies within the ``[-5%, +5%]`` prediction interval. View the full raw data and methodology in our [Performance Reports repository](https://github.com/mattermost/performance-reports/tree/main/performance-comparisons/v11.9). + - Improved the performance of concurrent logins by removing a global mutex in favour of database serialization for computing login attempts. This, in turn, fixed the semantics of the ``MaximumLoginAttempts`` setting, which is now honored across all nodes in the cluster: instead of allowing ``n*MaximumLoginAttempts`` attempts, with ``n`` the number of nodes, we now allow ``MaximumLoginAttempts`` attempts regardless of the number of nodes. + - Reduced cluster send error logs from oversized ``plugin_statuses_changed`` WebSocket events. + +### Bug Fixes + - Fixed an issue where a file read failure while building a Global Relay compliance export could crash the server. + - Fixed display of long usernames in the user account menu. + - Fixed a white flash that appeared in the global header and left sidebar when switching between products (Playbooks/Boards) and Channels. + - Fixed an issue where the AI actions toolbar separator was shown when no AI actions button was available. + - Fixed an issue where the Incoming Webhooks list reordered entries between page navigations. + - Fixed a JavaScript error when reviewers received content review updates for permanently removed flagged posts. + - Fixed an issue where the Global Threads view showed only 1 quick reaction emoji in the post hover toolbar instead of 3 (reported on webapp). + - Fixed IPv6 addresses containing hex segments (e.g. ``:beef:``) being incorrectly rendered as custom emoji in the web app. + - Fixed a bulk-import failure ("ChannelMember not found") when a group-channel hash already existed but its membership was incomplete — for example with concurrent import workers, a prior import that crashed mid-loop, or a pre-existing group channel whose membership had drifted. + - Fixed an issue where the content review bot Direct Message displayed an empty ``""`` block under "With comment" when the reporter or reviewer did not enter a comment. + - Fixed incorrect encoding of image URLs containing query parameters when using an image proxy (reported on webapp). + - Fixed an issue where the SAML metadata endpoint did not correctly pull the IDP public certificate. + - Fixed an issue where selecting a new role for a team or channel linked to a group in the System Console would not update the role dropdown in the user interface. + - Fixed an issue where importing direct or group message channels without scheme flags in the payload (notably from mmetl Slack exports) produced channel members with no effective role, breaking the message input for those channels on the web client. + - Fixed the Membership Policies row action Edit option to open the membership policy editor. + - Fixed the onboarding checklist button positioning when a bottom classification banner is visible. + - Fixed a regression that made the Integrations and Custom Emoji pages illegible when using a dark theme (reported on webapp). + - Fixed an issue where the Role and Permissions column values in the System Console Permission Policies (and Membership Policies) list ran together without a separator and were truncated mid-word instead of showing an ellipsis. + - Fixed an issue where a channel member removed by an attribute-based access control (ABAC) access-rule change could still appear in the Channel Info Members list until a full page reload, even though the member count was correct. + - Fixed an issue where "Mark as Unread" from the channel sidebar did nothing when the most recent message in the channel was a system join/leave message (reported on MacOS / Desktop App). + - Fixed an issue where channel admins saw "Failed to load this channel's permission policy" on the Permissions Policy tab when the channel had no access control policy configured. + - [Fixed](https://docs.mattermost.com/end-user-guide/collaborate/react-with-emojis-gifs.html) custom emoji upload size and GIF frame limits. + - Fixed file moves and copies on S3 file stores failing for files larger than 5 GiB (for example, finalizing an ``mmctl`` import upload of an import archive over 5 GiB) by using a server-side multipart copy. + - Fixed an issue where a bot user created by a plugin could become the first system admin on a fresh install (reported on webapp and browser). + - Fixed an issue where a custom classification selection was lost if a user selected a preset from the classification preset options. + - Fixed validation for ``PUT /api/v4/users/{user_id}/auth`` to reject unknown auth services and prevent auth data on email/password users. + - Fixed an issue that caused a flagged post to continue being visible for content reviewers until a refresh after deletion. + - Preserved unknown permissions during migrations on downgrade. + - Fixed an issue where channels with a permission-only access control policy (and no membership policy) were incorrectly hidden from the channel picker in the Invite People → Invite as Guest flow. + - Tightened authorization on the OAuth deauthorization and personal access token management endpoints. + - Tightened validation when updating channel member roles via the API. + - Fixed an issue where the **Channel Settings Permissions Policy** rule editor cleared all entered fields (role, conditions, and permissions) when a validation error was shown on save. + - Avoided saving stale configurations from the System Console by refreshing a system admin's snapshot of the configuration whenever it changed. + - Fixed an issue where the Bot Accounts page loaded at most 200 bots, hiding newer bots from the list and search on servers with more than 200 bot accounts. + +### API Changes + - Added ``POST /file/test`` (``testFileStore``) API endpoint for backend-agnostic file store connection testing. + - Added ``POST /file/s3_test`` (``testFileStore``) API endpoint. + - Removed ``POST /file/s3_test`` (``testS3``) API endpoint. + - Added ``GET /access_control/policy`` (``getTeamAccessControlPolicy``) API endpoint. + - Added ``GET /sessions/attributes/manifest`` (``getSessionAttributesManifest``) API endpoint. + - Added a new API file: ``team_abac_api_test.go``. + - Added a new API file: ``team_membership_enforcement_test.go``. + +### Audit Log Event Changes + - Added ``AuditEventRejectExpiredUserAccessToken`` audit log event. + +### Go Version + - v11.9 is built with Go ``v1.26.4``. + (release-v11.8-feature-release)= ## Release v11.8 - [Feature Release](https://docs.mattermost.com/product-overview/release-policy.html#release-types) @@ -64,6 +228,10 @@ New setting options were added to ``config.json``. Below is a list of the additi - **Changes to Enterprise plans:** - Under ``ElasticsearchSettings`` in ``config.json``, added ``EnableSearchPublicChannelsWithoutMembership`` configuration setting to allow searching in public channels the user isn't a member of. - Under ``TeamSettings`` in ``config.json``, added ``EnableChannelCategorySorting`` configuration setting to add, edit, and remove managed categories. + +```{Important} +If you upgrade from a release earlier than v11.7, please read the other [Important Upgrade Notes](https://docs.mattermost.com/administration-guide/upgrade/important-upgrade-notes.html). In case of an upgrade failure, please check the [Downgrade Guide](https://docs.mattermost.com/administration-guide/upgrade/downgrading-mattermost-server.html) and the [Recovery Guide](https://docs.mattermost.com/deployment-guide/backup-disaster-recovery.html) for rollback steps and interim mitigation strategy. +``` ### Improvements From 3d05391f081b0892715cef567d4cad280f1ca645 Mon Sep 17 00:00:00 2001 From: Amy Blais <29708087+amyblais@users.noreply.github.com> Date: Mon, 13 Jul 2026 09:58:57 +0300 Subject: [PATCH 8/9] Update version-archive.rst (#9092) --- source/product-overview/version-archive.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/product-overview/version-archive.rst b/source/product-overview/version-archive.rst index f512f006304..22678771669 100644 --- a/source/product-overview/version-archive.rst +++ b/source/product-overview/version-archive.rst @@ -11,6 +11,11 @@ If you want to check that the version of Mattermost you are installing is the of .. tab:: Mattermost Enterprise + Mattermost Enterprise Edition v11.9.0 - `View Changelog `__ - `Download `__ + - ``https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz`` + - SHA-256 Checksum: ``8b335213debfa817084870f09e28c3ecabb899cbfbf39a167d81dee68d96d6e3`` + - GPG Signature: https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz.sig + - SBOM Download Link: https://releases.mattermost.com/11.9.0/sbom-enterprise-v11.9.0.json Mattermost Enterprise Edition v11.8.3 - `View Changelog `__ - `Download `__ - ``https://releases.mattermost.com/11.8.3/mattermost-11.8.3-linux-amd64.tar.gz`` - SHA-256 Checksum: ``960131db16510e4b524a20775dad3ac42085445c2ef3b66e7a2809185a65cd5d`` @@ -489,6 +494,11 @@ If you want to check that the version of Mattermost you are installing is the of We generally recommend installing Enterprise Edition, even if you don't currently need a license. This provides the flexibility to seamlessly unlock Enterprise features should you need them. However, if you only want to install software with a fully open source code base, then Team Edition is the best choice for you. + Mattermost Team Edition v11.9.0 - `View Changelog `__ - `Download `__ + - ``https://releases.mattermost.com/11.9.0/mattermost-team-11.9.0-linux-amd64.tar.gz`` + - SHA-256 Checksum: ``5f1172535f43a5444a0896e8ad3ca2dbef7b2c20ca4e616a92691eaca03ae05f`` + - GPG Signature: https://releases.mattermost.com/11.9.0/mattermost-team-11.9.0-linux-amd64.tar.gz.sig + - SBOM Download Link: https://github.com/mattermost/mattermost/releases/download/v11.9.0/sbom-mattermost-v11.9.0.json Mattermost Team Edition v11.8.3 - `View Changelog `__ - `Download `__ - ``https://releases.mattermost.com/11.8.3/mattermost-team-11.8.3-linux-amd64.tar.gz`` - SHA-256 Checksum: ``5c864ac5fc83f95f94d2c04a7f40eb9248e6118d84ec916f3e6290768e488aa9`` From 545530bbced16e82df08713fe89bbdc440e8c456 Mon Sep 17 00:00:00 2001 From: Amy Blais <29708087+amyblais@users.noreply.github.com> Date: Mon, 13 Jul 2026 09:59:44 +0300 Subject: [PATCH 9/9] v11.9 release docs (#9058) * Add v11.9 release docs scaffolding Mechanical version scaffolding for the v11.9 (2026-07-16) feature release: - Add v11.9 row to the server Latest releases table - Bump latest-release download to 11.9.0 in deploy-rhel and deploy-tar - Add v11.9.0 server entry to open source components - Add v11.9 to the Desktop App v6.2 "Compatible with" list Co-authored-by: Amy Blais * Update open-source-components.rst * Update ui-ada-changelog.rst * Update release-policy.md * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * Update ui-ada-changelog.rst * Update important-upgrade-notes.rst * Update ui-ada-changelog.rst * Resolve conflict in deploy-rhel.rst * Resolve conflict in deploy-tar.rst * Resolve conflict in mattermost-server-releases.md * Update important-upgrade-notes.rst * Update important-upgrade-notes.rst * MM-69392 - DCR changes upgrade notes (#9089) --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Amy Blais --- .../upgrade/important-upgrade-notes.rst | 439 ++++++++++++++++++ .../upgrade/open-source-components.rst | 2 + .../server/linux/deploy-rhel.rst | 2 +- .../server/linux/deploy-tar.rst | 2 +- .../mattermost-desktop-releases.md | 2 +- .../mattermost-server-releases.md | 1 + source/product-overview/release-policy.md | 3 +- source/product-overview/ui-ada-changelog.rst | 16 + 8 files changed, 463 insertions(+), 4 deletions(-) diff --git a/source/administration-guide/upgrade/important-upgrade-notes.rst b/source/administration-guide/upgrade/important-upgrade-notes.rst index 8bb4ae6d2a1..fa6bd01b6e3 100644 --- a/source/administration-guide/upgrade/important-upgrade-notes.rst +++ b/source/administration-guide/upgrade/important-upgrade-notes.rst @@ -12,6 +12,445 @@ We recommend reviewing the `additional upgrade notes <#additional-upgrade-notes> | If you're upgrading | Then... | | from a version earlier than... | | +====================================================+==================================================================================================================================================================+ +| v11.9 | Mattermost v11.9 changes how redirect URI allowlist patterns are matched for OAuth Dynamic Client Registration (DCR). Patterns are now evaluated per URL | +| | component (scheme, host, path, and query) rather than as a whole-string glob. As a result, a pattern such as ``https://*.example.com/**`` no longer matches | +| | redirect URIs that include a query string (for example, ``https://app.example.com/callback?tenant=foo``); redirect URIs without a query string continue to | +| | match as expected. | +| | | +| | Admins using DCR with redirect URIs that include query strings must update their allowlist. To allow redirect URIs both with and without a query string, add | +| | two separate entries: | +| | | +| | - ``https://*.example.com/**`` — matches redirect URIs with no query string. | +| | - ``https://*.example.com/**?**`` — matches redirect URIs with any query string. | +| | | +| | A pattern that includes a query component (such as ``?**``) only matches URIs that also carry a query string; it will not match URIs without one. Both entries | +| | are required to cover both cases. | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Mattermost 11.9.0 introduces a schema change in the form of a new column added to the ``incomingwebhooks`` table. The ``incomingwebhooks`` table receives an | +| | ``AccessExclusiveLock`` when adding the column; however, because PostgreSQL 11+ treats ``ADD COLUMN`` with a non-volatile constant default as a metadata-only | +| | operation, the lock is held for only microseconds and is not proportional to row count. All concurrent reads and writes are blocked only for the instant the | +| | catalog entry is updated, then immediately released — impact to concurrent operations is negligible. Zero downtime is possible when upgrading to this release. | +| | The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- up | +| | ALTER TABLE incomingwebhooks ADD COLUMN IF NOT EXISTS lastused bigint NOT NULL DEFAULT 0; | +| | -- down | +| | ALTER TABLE incomingwebhooks DROP COLUMN IF EXISTS lastused; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | This migration adds a new ``voipdeviceid`` column (``VARCHAR(512) NOT NULL DEFAULT ''``) to the ``sessions`` table to support associating VoIP device | +| | identifiers with user sessions. The column is defined with an empty-string default, ensuring existing rows and any rows written by older server versions | +| | automatically satisfy the ``NOT NULL`` constraint without requiring a data backfill. On PostgreSQL 11 and later, adding a column with a constant default is a | +| | metadata-only operation — no table rewrite occurs — so the ``ACCESS EXCLUSIVE`` lock on ``sessions`` is held for only a brief period (typically milliseconds). | +| | Administrators on large deployments should be aware that ``sessions`` is one of the most frequently accessed tables, and any long-running transactions already | +| | holding locks on it could cause a transient increase in lock-wait times during the migration. The migrations are fully backwards-compatible and no database | +| | downtime is expected for this upgrade. The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- up | +| | ALTER TABLE sessions ADD COLUMN IF NOT EXISTS voipdeviceid VARCHAR(512) NOT NULL DEFAULT ''; | +| | | +| | -- down | +| | ALTER TABLE sessions DROP COLUMN IF EXISTS voipdeviceid; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | This migration adds a composite index, ``idx_access_control_policies_type_id``, on the ``AccessControlPolicies`` table covering the ``Type`` and ``Id`` columns. | +| | The index is intended to improve query performance when filtering or looking up access control policies by type and identifier. The index is built using | +| | ``CREATE INDEX CONCURRENTLY``, meaning it is constructed in the background without blocking reads or writes on the ``AccessControlPolicies`` table. No columns, | +| | constraints, or existing indexes are modified or removed by this change. The migrations are fully backwards-compatible and no database downtime is expected for | +| | this upgrade. The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- Up migration (PostgreSQL) | +| | CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_access_control_policies_type_id ON AccessControlPolicies(Type, Id); | +| | | +| | .. code-block:: sql | +| | | +| | -- Down migration (PostgreSQL) | +| | DROP INDEX CONCURRENTLY IF EXISTS idx_access_control_policies_type_id; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | This migration removes orphaned rows from the ``threadmemberships`` table — specifically, rows where the associated user is no longer a member of the channel | +| | that the thread belongs to. The cleanup is performed via a filtered ``DELETE`` using a three-way join across ``threadmemberships``, ``threads``, and | +| | ``channelmembers``. No schema objects (tables, columns, or indexes) are added or removed; only data rows are affected. Note for large instances: this migration | +| | issues a single unbatched delete that scans the entirety of ``threadmemberships`` with a join against ``threads`` and ``channelmembers``. On databases with tens | +| | of millions of rows or significant historical channel-membership churn, this query may run for an extended period, block autovacuum on ``threadmemberships``, | +| | increase WAL pressure, and contribute to replication lag. Administrators of large deployments should test execution time on a representative dataset before | +| | upgrading and consider scheduling the upgrade during a low-traffic window. The down migration contains no rollback SQL because the deleted rows cannot be | +| | recovered; this migration is irreversible. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries | +| | included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- Drop ThreadMembership rows whose user is no longer a member of the thread's channel. | +| | DELETE FROM threadmemberships WHERE (postid, userid) IN ( | +| | SELECT | +| | threadmemberships.postid, | +| | threadmemberships.userid | +| | FROM | +| | threadmemberships | +| | JOIN threads ON threads.postid = threadmemberships.postid | +| | LEFT JOIN channelmembers ON channelmembers.userid = threadmemberships.userid | +| | AND threads.channelid = channelmembers.channelid | +| | WHERE | +| | channelmembers.channelid IS NULL | +| | ); | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Migration 000199 extends the ``property_field_type`` enum in PostgreSQL by adding the new value ``'rank'`` to support rank-type property fields. The change is | +| | made via ``ALTER TYPE property_field_type ADD VALUE IF NOT EXISTS 'rank'``, which is a catalog-only operation that touches only the ``pg_enum`` system catalog | +| | and acquires no locks on user tables such as ``PropertyFields`` or ``PropertyValues``. Existing rows and application code are entirely unaffected by the | +| | addition. The rollback (down) migration is intentionally destructive: any ``PropertyFields`` rows carrying ``Type = 'rank'`` are coerced to ``'select'``, the | +| | enum is rebuilt without the ``'rank'`` value, and the ``AttributeView`` materialized view is dropped and recreated — all of which require an | +| | ``AccessExclusiveLock`` on ``PropertyFields`` and should only be executed during a maintenance window. The migrations are fully backwards-compatible and no | +| | database downtime is expected for this upgrade. The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- Postgres cannot remove a value from an existing enum in place, so rebuild | +| | -- the type without 'rank'. Any rows still holding 'rank' (e.g. fields created | +| | -- via the property API after this migration ran) are coerced to 'select' | +| | -- first so the recreated enum can accept them; 'select' has the same storage | +| | -- shape (single option ID). | +| | -- | +| | -- The AttributeView materialized view reads PropertyFields.Type, so Postgres | +| | -- refuses to rebuild the enum on that column while the view exists. Drop the | +| | -- view before the ALTER and recreate it afterwards. | +| | | +| | UPDATE PropertyFields SET Type = 'select' WHERE Type = 'rank'; | +| | | +| | DROP MATERIALIZED VIEW IF EXISTS AttributeView; | +| | | +| | ALTER TYPE property_field_type RENAME TO property_field_type_old; | +| | | +| | CREATE TYPE property_field_type AS ENUM ( | +| | 'text', | +| | 'select', | +| | 'multiselect', | +| | 'date', | +| | 'user', | +| | 'multiuser' | +| | ); | +| | | +| | ALTER TABLE PropertyFields | +| | ALTER COLUMN Type TYPE property_field_type USING Type::text::property_field_type; | +| | | +| | DROP TYPE property_field_type_old; | +| | | +| | -- Recreate the no-rank AttributeView (matches 000177 / 000198 down). | +| | CREATE MATERIALIZED VIEW IF NOT EXISTS AttributeView AS | +| | SELECT | +| | pv.GroupID, | +| | pv.TargetID, | +| | pv.TargetType, | +| | jsonb_object_agg( | +| | pf.Name, | +| | CASE | +| | WHEN pf.Type = 'select' THEN ( | +| | SELECT to_jsonb(options.name) | +| | FROM jsonb_to_recordset(pf.Attrs->'options') AS options(id text, name text) | +| | WHERE options.id = pv.Value #>> '{}' | +| | LIMIT 1 | +| | ) | +| | WHEN pf.Type = 'multiselect' AND jsonb_typeof(pv.Value) = 'array' THEN ( | +| | SELECT jsonb_agg(option_names.name) | +| | FROM jsonb_array_elements_text(pv.Value) AS option_id | +| | JOIN jsonb_to_recordset(pf.Attrs->'options') AS option_names(id text, name text) | +| | ON option_id = option_names.id | +| | ) | +| | ELSE pv.Value | +| | END | +| | ) AS Attributes | +| | FROM PropertyValues pv | +| | LEFT JOIN PropertyFields pf ON pf.ID = pv.FieldID | +| | WHERE (pv.DeleteAt = 0 OR pv.DeleteAt IS NULL) | +| | AND (pf.DeleteAt = 0 OR pf.DeleteAt IS NULL) | +| | AND pf.ObjectType = 'user' | +| | GROUP BY pv.GroupID, pv.TargetID, pv.TargetType; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Migration 000195 updates up to three rows in the ``PropertyFields`` table that belong to the ``access_control`` property group, converting their ``Type`` value | +| | from ``'select'`` to ``'rank'`` and backfilling a ``rank`` integer key into each element of the ``options`` array stored in the ``Attrs`` JSONB column. The | +| | affected fields are ``classification`` (``ObjectType = 'template'``), ``system_classification`` (``ObjectType = 'system'``), and ``channel_classification`` | +| | (``ObjectType = 'channel'``), which are part of the classification-markings feature gated behind a feature flag. No schema structure changes (DDL) are made — | +| | only targeted DML ``UPDATE`` statements are executed, touching at most three rows regardless of server size. Both statements run within a single transaction, | +| | so no intermediate state is ever visible to other sessions. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. | +| | The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- up migration | +| | | +| | -- Convert the classification-markings property fields from 'select' to 'rank'. | +| | -- Each (Name, ObjectType) pair is matched explicitly so unrelated fields that | +| | -- happen to share a name cannot be touched. At most three rows are updated. | +| | UPDATE PropertyFields | +| | SET Type = 'rank' | +| | WHERE Type = 'select' | +| | AND GroupID = (SELECT ID FROM PropertyGroups WHERE Name = 'access_control') | +| | AND ( | +| | (Name = 'classification' AND ObjectType = 'template') | +| | OR (Name = 'system_classification' AND ObjectType = 'system') | +| | OR (Name = 'channel_classification' AND ObjectType = 'channel') | +| | ); | +| | | +| | -- Backfill a rank onto every option. | +| | UPDATE PropertyFields pf | +| | SET Attrs = jsonb_set( | +| | pf.Attrs, | +| | '{options}', | +| | ( | +| | SELECT jsonb_agg(elem.opt || jsonb_build_object('rank', elem.ord) ORDER BY elem.ord) | +| | FROM jsonb_array_elements(pf.Attrs->'options') WITH ORDINALITY AS elem(opt, ord) | +| | ) | +| | ) | +| | WHERE pf.Type = 'rank' | +| | AND pf.GroupID = (SELECT ID FROM PropertyGroups WHERE Name = 'access_control') | +| | AND ( | +| | (pf.Name = 'classification' AND pf.ObjectType = 'template') | +| | OR (pf.Name = 'system_classification' AND pf.ObjectType = 'system') | +| | OR (pf.Name = 'channel_classification' AND pf.ObjectType = 'channel') | +| | ) | +| | AND jsonb_typeof(pf.Attrs->'options') = 'array' | +| | AND jsonb_array_length(pf.Attrs->'options') > 0; | +| | | +| | .. code-block:: sql | +| | | +| | -- down migration | +| | | +| | UPDATE PropertyFields pf | +| | SET Attrs = jsonb_set( | +| | pf.Attrs, | +| | '{options}', | +| | ( | +| | SELECT jsonb_agg(elem.opt - 'rank' ORDER BY elem.ord) | +| | FROM jsonb_array_elements(pf.Attrs->'options') WITH ORDINALITY AS elem(opt, ord) | +| | ) | +| | ) | +| | WHERE pf.Type = 'rank' | +| | AND pf.GroupID = (SELECT ID FROM PropertyGroups WHERE Name = 'access_control') | +| | AND ( | +| | (pf.Name = 'classification' AND pf.ObjectType = 'template') | +| | OR (pf.Name = 'system_classification' AND pf.ObjectType = 'system') | +| | OR (pf.Name = 'channel_classification' AND pf.ObjectType = 'channel') | +| | ) | +| | AND jsonb_typeof(pf.Attrs->'options') = 'array' | +| | AND jsonb_array_length(pf.Attrs->'options') > 0; | +| | | +| | UPDATE PropertyFields | +| | SET Type = 'select' | +| | WHERE Type = 'rank' | +| | AND GroupID = (SELECT ID FROM PropertyGroups WHERE Name = 'access_control') | +| | AND ( | +| | (Name = 'classification' AND ObjectType = 'template') | +| | OR (Name = 'system_classification' AND ObjectType = 'system') | +| | OR (Name = 'channel_classification' AND ObjectType = 'channel') | +| | ); | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Migration 000196 updates data within the ``PropertyFields`` table as part of the Access Control / Properties framework. Specifically, it renames two | +| | classification field entries inside the ``access_control`` ``PropertyGroups`` group: the ``system_classification`` entry (``ObjectType = 'system'``) and the | +| | ``channel_classification`` entry (``ObjectType = 'channel'``) are both renamed to the canonical value ``classification``. The rows remain distinct because the | +| | unique index on ``PropertyFields`` incorporates ``ObjectType``, preventing collisions. This change affects at most two rows and completes near-instantly with | +| | no measurable performance impact. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included | +| | are: | +| | | +| | .. code-block:: sql | +| | | +| | -- Up migration | +| | -- Rename the system- and channel-scoped classification linked fields so all | +| | -- three classification fields share the canonical Name 'classification'. They | +| | -- remain distinct rows because the typed unique index keys on ObjectType as | +| | -- well, so template/system/channel rows do not collide. | +| | UPDATE PropertyFields | +| | SET Name = 'classification' | +| | WHERE GroupID = (SELECT ID FROM PropertyGroups WHERE Name = 'access_control') | +| | AND ( | +| | (Name = 'system_classification' AND ObjectType = 'system') | +| | OR (Name = 'channel_classification' AND ObjectType = 'channel') | +| | ); | +| | | +| | -- Down migration | +| | -- Restore the previous names so the rows can be matched by 000195's down | +| | -- migration. Identified by ObjectType since all three classification rows | +| | -- share the same Name='classification' at this point. | +| | UPDATE PropertyFields | +| | SET Name = 'system_classification' | +| | WHERE GroupID = (SELECT ID FROM PropertyGroups WHERE Name = 'access_control') | +| | AND Name = 'classification' | +| | AND ObjectType = 'system'; | +| | | +| | UPDATE PropertyFields | +| | SET Name = 'channel_classification' | +| | WHERE GroupID = (SELECT ID FROM PropertyGroups WHERE Name = 'access_control') | +| | AND Name = 'classification' | +| | AND ObjectType = 'channel'; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Migration 000178 extends the ``AttributeView`` materialized view — part of the ABAC/property system — to add support for ``rank``-typed property fields. | +| | Previously, ``rank``-typed values were stored as raw values in the view; they are now materialized as ``{"name": , "rank": }`` JSON | +| | objects, enabling ABAC policies to compare rank values without embedding rank integers directly in policy expressions. The migration drops and recreates | +| | ``AttributeView`` in a single transaction, performing a full scan of ``PropertyValues`` and ``PropertyFields`` at migration time. Because these tables are gated | +| | behind a feature flag and expected to be empty or near-empty at the time of this migration, the performance impact is negligible for most deployments. The | +| | migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- Extend the AttributeView matview to materialize rank-typed property values | +| | -- as {"name": , "rank": } so ABAC policies can | +| | -- compare ranks without storing rank integers in policy expressions. | +| | DROP MATERIALIZED VIEW IF EXISTS AttributeView; | +| | | +| | CREATE MATERIALIZED VIEW IF NOT EXISTS AttributeView AS | +| | SELECT | +| | pv.GroupID, | +| | pv.TargetID, | +| | pv.TargetType, | +| | jsonb_object_agg( | +| | pf.Name, | +| | CASE | +| | WHEN pf.Type = 'select' THEN ( | +| | SELECT to_jsonb(options.name) | +| | FROM jsonb_to_recordset(pf.Attrs->'options') AS options(id text, name text) | +| | WHERE options.id = pv.Value #>> '{}' | +| | LIMIT 1 | +| | ) | +| | WHEN pf.Type = 'multiselect' AND jsonb_typeof(pv.Value) = 'array' THEN ( | +| | SELECT jsonb_agg(option_names.name) | +| | FROM jsonb_array_elements_text(pv.Value) AS option_id | +| | JOIN jsonb_to_recordset(pf.Attrs->'options') AS option_names(id text, name text) | +| | ON option_id = option_names.id | +| | ) | +| | WHEN pf.Type = 'rank' THEN ( | +| | SELECT jsonb_build_object( | +| | 'name', options.name, | +| | 'rank', options.rank | +| | ) | +| | FROM jsonb_to_recordset(pf.Attrs->'options') | +| | AS options(id text, name text, rank int) | +| | WHERE options.id = pv.Value #>> '{}' | +| | LIMIT 1 | +| | ) | +| | ELSE pv.Value | +| | END | +| | ) AS Attributes | +| | FROM PropertyValues pv | +| | LEFT JOIN PropertyFields pf ON pf.ID = pv.FieldID | +| | WHERE (pv.DeleteAt = 0 OR pv.DeleteAt IS NULL) | +| | AND (pf.DeleteAt = 0 OR pf.DeleteAt IS NULL) | +| | AND pf.ObjectType = 'user' | +| | GROUP BY pv.GroupID, pv.TargetID, pv.TargetType; | +| | | +| | .. code-block:: sql | +| | | +| | -- Restore the 000177 matview definition (no rank branch). | +| | DROP MATERIALIZED VIEW IF EXISTS AttributeView; | +| | | +| | CREATE MATERIALIZED VIEW IF NOT EXISTS AttributeView AS | +| | SELECT | +| | pv.GroupID, | +| | pv.TargetID, | +| | pv.TargetType, | +| | jsonb_object_agg( | +| | pf.Name, | +| | CASE | +| | WHEN pf.Type = 'select' THEN ( | +| | SELECT to_jsonb(options.name) | +| | FROM jsonb_to_recordset(pf.Attrs->'options') AS options(id text, name text) | +| | WHERE options.id = pv.Value #>> '{}' | +| | LIMIT 1 | +| | ) | +| | WHEN pf.Type = 'multiselect' AND jsonb_typeof(pv.Value) = 'array' THEN ( | +| | SELECT jsonb_agg(option_names.name) | +| | FROM jsonb_array_elements_text(pv.Value) AS option_id | +| | JOIN jsonb_to_recordset(pf.Attrs->'options') AS option_names(id text, name text) | +| | ON option_id = option_names.id | +| | ) | +| | ELSE pv.Value | +| | END | +| | ) AS Attributes | +| | FROM PropertyValues pv | +| | LEFT JOIN PropertyFields pf ON pf.ID = pv.FieldID | +| | WHERE (pv.DeleteAt = 0 OR pv.DeleteAt IS NULL) | +| | AND (pf.DeleteAt = 0 OR pf.DeleteAt IS NULL) | +| | AND pf.ObjectType = 'user' | +| | GROUP BY pv.GroupID, pv.TargetID, pv.TargetType; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Added an ``expiresat`` column and partial index to ``useraccesstokens`` to support PAT expiry enforcement. Large-dataset testing was not required for this | +| | migration as ``useraccesstokens`` is not a large table. ``useraccesstokens`` receives a brief ACCESS EXCLUSIVE lock when adding the column (Migration 000187, | +| | metadata-only, no table rewrite on PostgreSQL 11+), and a SHARE UPDATE EXCLUSIVE lock during the index build via CREATE INDEX CONCURRENTLY (Migration 000188), | +| | which never blocks concurrent reads or writes. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL | +| | queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- Migration 000187 (transactional): | +| | ALTER TABLE useraccesstokens ADD COLUMN IF NOT EXISTS expiresat bigint NOT NULL DEFAULT 0; | +| | | +| | -- Migration 000188 (run via morph as nontransactional): | +| | CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_useraccesstokens_expiresat | +| | ON useraccesstokens (expiresat) | +| | WHERE expiresat > 0; | +| | | +| | -- Down migrations: | +| | DROP INDEX CONCURRENTLY IF EXISTS idx_useraccesstokens_expiresat; | +| | ALTER TABLE useraccesstokens DROP COLUMN IF EXISTS expiresat; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Added support for ``board`` as a new channel bookmark type by introducing a ``targetid`` column and a corresponding index on the ``channelbookmarks`` table. | +| | The only table touched is ``channelbookmarks``. The nullable column add is metadata-only with a negligible exclusive lock duration. The index build uses | +| | ``CONCURRENTLY`` and runs online without blocking DML. Existing ``link`` and ``file`` bookmark rows and queries are unaffected, and the new ``targetid`` column | +| | is nullable with no default, which is inert to old code. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. | +| | The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- 000190_channel_bookmarks_board_target_id.up.sql | +| | ALTER TYPE channel_bookmark_type ADD VALUE IF NOT EXISTS 'board'; | +| | ALTER TABLE channelbookmarks ADD COLUMN IF NOT EXISTS targetid varchar(26) DEFAULT NULL; | +| | | +| | -- 000191_channel_bookmarks_target_id_index.up.sql | +| | -- morph:nontransactional | +| | CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channelbookmarks_type_targetid ON channelbookmarks (type, targetid) WHERE targetid IS NOT NULL; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Added a ``SchemaVersion`` column (``integer DEFAULT 1 NOT NULL``) to the ``PropertyGroups`` table. Large-dataset testing was not performed for this migration. | +| | The only table touched is ``PropertyGroups``, which is a small registry table holding one row per registered property group. ``PropertyGroups`` receives a brief | +| | access exclusive lock when adding the column, held only momentarily for a metadata-only catalog update with no table rewrite. The migrations are fully | +| | backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | ALTER TABLE PropertyGroups ADD COLUMN IF NOT EXISTS SchemaVersion integer DEFAULT 1 NOT NULL; | +| +------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| | Two new database migrations introduce the ``ChannelGuards`` table, which enables plugins to register exclusive ownership of channels. Migration ``000185`` | +| | creates the ``ChannelGuards`` table with three columns — ``ChannelId``, ``PluginId``, and ``CreatedAt`` — and a composite primary key on | +| | (``ChannelId, PluginId``) to enforce uniqueness per plugin per channel. Migration ``000186`` adds the secondary index ``idx_channel_guards_plugin_id`` on the | +| | ``PluginId`` column to support efficient plugin-scoped queries against the table. Both migrations are safe to run online with no locking impact on existing | +| | production tables. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included are: | +| | | +| | .. code-block:: sql | +| | | +| | -- 000185_create_channel_guards.up.sql | +| | CREATE TABLE IF NOT EXISTS ChannelGuards ( | +| | ChannelId varchar(26) NOT NULL, | +| | PluginId varchar(190) NOT NULL, | +| | CreatedAt bigint NOT NULL, | +| | PRIMARY KEY (ChannelId, PluginId) | +| | ); | +| | | +| | .. code-block:: sql | +| | | +| | -- 000185_create_channel_guards.down.sql | +| | DROP TABLE IF EXISTS ChannelGuards; | +| | | +| | .. code-block:: sql | +| | | +| | -- 000186_create_channel_guards_plugin_id_index.up.sql | +| | -- morph:nontransactional | +| | CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channel_guards_plugin_id ON ChannelGuards(PluginId); | +| | | +| | .. code-block:: sql | +| | | +| | -- 000186_create_channel_guards_plugin_id_index.down.sql | +| | -- morph:nontransactional | +| | DROP INDEX CONCURRENTLY IF EXISTS idx_channel_guards_plugin_id; | ++----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | v11.8 | The Custom Profile Attributes property group is renamed from ``custom_profile_attributes`` to ``access_control``, and CPA fields and values are migrated from | | | the legacy property model to the v2 model. The functionality of the CPA feature is unchanged. Plugin developers that use CPA will need to register against the | | | new group name. | diff --git a/source/administration-guide/upgrade/open-source-components.rst b/source/administration-guide/upgrade/open-source-components.rst index 2acb77f5446..ab16f0e8ec2 100644 --- a/source/administration-guide/upgrade/open-source-components.rst +++ b/source/administration-guide/upgrade/open-source-components.rst @@ -39,6 +39,7 @@ Desktop Mobile ------- +- Mattermost Mobile v2.42.0 - `View Open Source Components `__. - Mattermost Mobile v2.41.0 - `View Open Source Components `__. - Mattermost Mobile v2.40.0 - `View Open Source Components `__. - Mattermost Mobile v2.39.0 - `View Open Source Components `__. @@ -141,6 +142,7 @@ Mobile Server ------------------------------ +- Mattermost Enterprise Edition v11.9.0 - `View Open Source Components `__. - Mattermost Enterprise Edition v11.8.0 - `View Open Source Components `__. - Mattermost Enterprise Edition v11.7.0 - `View Open Source Components `__. - Mattermost Enterprise Edition v11.6.0 - `View Open Source Components `__. diff --git a/source/deployment-guide/server/linux/deploy-rhel.rst b/source/deployment-guide/server/linux/deploy-rhel.rst index f98a3ebc70b..b6e651fa573 100644 --- a/source/deployment-guide/server/linux/deploy-rhel.rst +++ b/source/deployment-guide/server/linux/deploy-rhel.rst @@ -44,7 +44,7 @@ In a terminal window, ssh onto the system that will host the Mattermost Server. .. code-block:: sh - wget https://releases.mattermost.com/11.8.3/mattermost-11.8.3-linux-amd64.tar.gz + wget https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz .. tab:: Current ESR diff --git a/source/deployment-guide/server/linux/deploy-tar.rst b/source/deployment-guide/server/linux/deploy-tar.rst index 658cef73313..d2fcd140e4c 100644 --- a/source/deployment-guide/server/linux/deploy-tar.rst +++ b/source/deployment-guide/server/linux/deploy-tar.rst @@ -45,7 +45,7 @@ In a terminal window, ssh onto the system that will host the Mattermost Server. .. code-block:: sh - wget https://releases.mattermost.com/11.8.3/mattermost-11.8.3-linux-amd64.tar.gz + wget https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz .. tab:: Current ESR diff --git a/source/product-overview/mattermost-desktop-releases.md b/source/product-overview/mattermost-desktop-releases.md index 6785bf74da8..6ab38e2c42c 100644 --- a/source/product-overview/mattermost-desktop-releases.md +++ b/source/product-overview/mattermost-desktop-releases.md @@ -18,7 +18,7 @@ Mattermost releases a new desktop app version every 4 months, in February, May, | **Release** | **Support** | **Compatible with** | |:---|:---|:---| -| v6.2 [Download](https://github.com/mattermost/desktop/releases/tag/v6.2.2) \| {ref}`Changelog ` \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.2.2/sbom-desktop-v6.2.2.json) | Released: 2026-05-15
Support Ends: 2027-05-15 {ref}`EXTENDED ` | {ref}`v11.8 `, {ref}`v11.7 `, {ref}`v11.6 `, {ref}`v11.5 `, {ref}`v10.11 ` | +| v6.2 [Download](https://github.com/mattermost/desktop/releases/tag/v6.2.2) \| {ref}`Changelog ` \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.2.2/sbom-desktop-v6.2.2.json) | Released: 2026-05-15
Support Ends: 2027-05-15 {ref}`EXTENDED ` | {ref}`v11.9 `, {ref}`v11.8 `, {ref}`v11.7 `, {ref}`v11.6 `, {ref}`v11.5 `, {ref}`v10.11 ` | | v6.1 [Download](https://github.com/mattermost/desktop/releases/tag/v6.1.2) \| {ref}`Changelog ` \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.1.2/sbom-desktop-v6.1.2.json) | Released: 2026-03-02
Support Ends: 2026-05-15 | {ref}`v11.6 `, {ref}`v11.5 `, {ref}`v11.4 `, {ref}`v11.3 `, {ref}`v11.2 `, {ref}`v10.11 ` | | v6.0 [Download](https://github.com/mattermost/desktop/releases/tag/v6.0.4) \| {ref}`Changelog ` \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.0.4/sbom-desktop-v6.0.4.json) | Released: 2025-11-14
Support Ends: 2026-03-15 | {ref}`v11.4 `, {ref}`v11.3 `, {ref}`v11.2 `, {ref}`v11.1 `, {ref}`v11.0 `, {ref}`v10.12 `, {ref}`v10.11 ` | | v5.13 [Download](https://github.com/mattermost/desktop/releases/tag/v5.13.7) \| {ref}`Changelog ` \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v5.13.7/sbom-desktop-v5.13.7.json) | Released: 2025-08-15
Support Ends: 2026-08-15 {ref}`EXTENDED ` | {ref}`v11.0 `, {ref}`v10.12 `, {ref}`v10.11 `, {ref}`v10.10 `, {ref}`v10.9 `, {ref}`v10.5 ` | diff --git a/source/product-overview/mattermost-server-releases.md b/source/product-overview/mattermost-server-releases.md index a7aea6755fc..94f6b96294f 100644 --- a/source/product-overview/mattermost-server-releases.md +++ b/source/product-overview/mattermost-server-releases.md @@ -19,6 +19,7 @@ Mattermost releases a new server version on the 16th of each month in [binary fo | **Release** | **Released on** | **Support ends** | |:---|:---|:---| +| v11.9 [Download](https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz) \| {ref}`Changelog ` \|
SBOM
| 2026-07-16 | 2026-10-15 | | v11.8 [Download](https://releases.mattermost.com/11.8.3/mattermost-11.8.3-linux-amd64.tar.gz) \| {ref}`Changelog ` \|
SBOM
| 2026-06-16 | 2026-09-15 | | v11.7 [Download](https://releases.mattermost.com/11.7.6/mattermost-11.7.6-linux-amd64.tar.gz) \| {ref}`Changelog ` \|
SBOM
| 2026-05-15 | 2027-05-15 {ref}`EXTENDED ` | | v11.6 [Download](https://releases.mattermost.com/11.6.6/mattermost-11.6.6-linux-amd64.tar.gz) \| {ref}`Changelog ` \|
SBOM
| 2026-04-16 | 2026-07-15 | diff --git a/source/product-overview/release-policy.md b/source/product-overview/release-policy.md index 58a54b18ac7..e5ea9bb4722 100644 --- a/source/product-overview/release-policy.md +++ b/source/product-overview/release-policy.md @@ -57,10 +57,11 @@ gantt v11.3 :done, 2026-01-16, 2026-04-15 v11.4 :done, 2026-02-16, 2026-05-15 v11.5 :done, 2026-03-16, 2026-06-15 - v11.6 :active, 2026-04-16, 2026-07-15 + v11.6 :done, 2026-04-16, 2026-07-15 v11.7 & Desktop App v6.2 Extended Support :crit, 2026-05-15, 2027-05-15 v11.8 :active, 2026-06-16, 2026-09-15 v11.9 :active, 2026-07-16, 2026-10-15 + v11.10 :active, 2026-08-16, 2026-11-15 ``` **Timeline Legend:** diff --git a/source/product-overview/ui-ada-changelog.rst b/source/product-overview/ui-ada-changelog.rst index 5905cc0a596..c429b74f77b 100644 --- a/source/product-overview/ui-ada-changelog.rst +++ b/source/product-overview/ui-ada-changelog.rst @@ -12,6 +12,22 @@ Changelog * - Version - Change Description + * - v11.9 + - (UI) Added zoom and pan support to the image file preview: use the scroll wheel to zoom at the cursor, click-and-drag to pan, and +/-/0 keyboard shortcuts (reported on webapp). + * - v11.9 + - (UI) Added a toast notification for plugin-rejected file uploads, consistent with the existing notification for rejected downloads. + * - v11.9 + - (UI) Added a Data Spillage Handling feature discovery page in the System Console for lower-tier licenses. + * - v11.9 + - (UI) Added clearer validation messaging for invalid user attribute names in the System Console. + * - v11.9 + - (UI) Incoming webhooks now show information about the last time they were triggered. + * - v11.9 + - (UI) Threads started by a webhook are no longer highlighted for the user who owns the webhook. + * - v11.9 + - (UI) Added user setting "Auto-follow threads on channel-wide mentions" (Settings → Notifications). When disabled, @channel/@all/@here mentions no longer force thread membership; users still receive mention notifications but must manually follow the thread. + * - v11.9 + - (UI) Hardened the web app against crashes caused by components rendered by a plugin. * - v11.8 - (UI) Added a new keyboard shortcut, ``Shift`` + ``ESC``, that marks all channels, threads, and direct messages as read for a team on webapp / desktop app. * - v11.8