From 2602efbb9e36cc7666dc16a6355c36efc13139fb Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 00:14:08 +0000 Subject: [PATCH 1/6] Add docs for experimental mobile watermarking (v11.7) Documents the new Enterprise, experimental "Enable Mobile Watermark" setting introduced by mattermost/mattermost#36025 and the visible mobile watermark overlay introduced by mattermost/mattermost-mobile#9682: - experimental-configuration-settings.rst: new "Enable Mobile Watermark" entry (Experimental > Features, disabled by default, Enterprise-only, v11.7 onward). - deployment-guide/mobile/mobile-security-features.rst: deep-dive "Mobile watermarking" section describing the username/domain/date/time overlay and its DLP-attribution purpose. - security-guide/mobile-security.rst: short overview section linking to the deep-dive and to the experimental config setting. Refs issue #8953. Co-authored-by: Combs7th --- .../experimental-configuration-settings.rst | 28 +++++++++++++++++++ .../mobile/mobile-security-features.rst | 20 +++++++++++++ source/security-guide/mobile-security.rst | 9 ++++++ 3 files changed, 57 insertions(+) diff --git a/source/administration-guide/configure/experimental-configuration-settings.rst b/source/administration-guide/configure/experimental-configuration-settings.rst index 632f704aed7..1ba3781a597 100644 --- a/source/administration-guide/configure/experimental-configuration-settings.rst +++ b/source/administration-guide/configure/experimental-configuration-settings.rst @@ -315,6 +315,34 @@ Changes made when hardened mode is enabled: | This feature's ``config.json`` setting is ``"ExperimentalEnableHardenedMode": false`` with options ``true`` and ``false``. | +----------------------------------------------------------------------------------------------------------------------------+ +.. config:setting:: enable-mobile-watermark + :displayname: Enable Mobile Watermark (Experimental) + :systemconsole: Experimental > Features + :configjson: ExperimentalSettings.EnableMobileWatermark + :environment: N/A + + - **true**: Authenticated Mattermost mobile sessions display a watermark overlay showing the user's username, the server domain, the current date (YYYY-MM-DD), and the current time (HH:mm) for data loss prevention (DLP) purposes. + - **false**: **(Default)** No watermark overlay is displayed in the Mattermost mobile app. + +Enable Mobile Watermark +~~~~~~~~~~~~~~~~~~~~~~~ + +Available on `Enterprise and Enterprise Advanced plans `__ from Mattermost v11.7 onward. + +**True**: Authenticated Mattermost mobile sessions display a watermark overlay showing the user's username, the server domain, the current date (YYYY-MM-DD), and the current time (HH:mm). This experimental capability is intended to support data loss prevention (DLP) workflows by helping identify the user, server, and time associated with mobile screenshots or shared screen captures. + +**False**: No watermark overlay is displayed in the Mattermost mobile app. + +.. note:: + + - This is an experimental setting. Behavior, defaults, and visual presentation may change in future releases. + - This setting only applies to the Mattermost mobile app. It does not add a watermark to the Mattermost web app or desktop apps. + - The watermark overlay is a visual aid and does not, by itself, prevent screenshots, screen recordings, file exports, or other forms of data extraction. Use it in combination with other mobile security controls, such as :ref:`screenshot and screen recording prevention `, where appropriate. + ++--------------------------------------------------------------------------------------------------------------------------------------+ +| This feature's ``config.json`` setting is ``"ExperimentalSettings.EnableMobileWatermark": false`` with options ``true`` and ``false``. | ++--------------------------------------------------------------------------------------------------------------------------------------+ + .. config:setting:: enable-theme-selection :displayname: Enable theme selection (Experimental) :systemconsole: Experimental > Features diff --git a/source/deployment-guide/mobile/mobile-security-features.rst b/source/deployment-guide/mobile/mobile-security-features.rst index 3845a23982b..7b2dac5e8c3 100644 --- a/source/deployment-guide/mobile/mobile-security-features.rst +++ b/source/deployment-guide/mobile/mobile-security-features.rst @@ -53,6 +53,26 @@ Preventing file downloads protects sensitive information from being inadvertentl See the :ref:`secure file preview ` and :ref:`managing PDF link navigation ` configuration settings documentation for details on enabling these features. +Mobile watermarking +------------------- + +Mobile watermarking is an experimental capability available from Mattermost v11.7 onward that helps organizations attribute mobile screenshots and shared screen captures to a specific user, server, and point in time. When this setting is enabled by a system admin, authenticated Mattermost mobile sessions display a visible watermark overlay on top of the app interface that includes: + +- The user's username. +- The server domain. +- The current date in ``YYYY-MM-DD`` format. +- The current time in ``HH:mm`` format. + +The watermark is intended to support data loss prevention (DLP) workflows by making it easier to identify the source and timing of any image taken of the Mattermost mobile app. Mobile watermarking is disabled by default. + +See the :ref:`Enable Mobile Watermark ` configuration setting documentation for details on enabling this experimental feature. + +.. note:: + + - The mobile watermark is a visual overlay only. It does not prevent users from taking screenshots, recording the screen, exporting files, or sharing content through other means. For controls that block screen capture on the device itself, see :ref:`screenshot and screen recording prevention `. + - This feature applies only to the Mattermost mobile app. It does not add a watermark to the Mattermost web app or desktop apps. + - This is an experimental capability. Its behavior, defaults, and visual presentation may change in future releases based on customer feedback. + Microsoft Intune Mobile Application Management (MAM) ---------------------------------------------------- diff --git a/source/security-guide/mobile-security.rst b/source/security-guide/mobile-security.rst index bf2c8cf2d9c..315611c8e08 100644 --- a/source/security-guide/mobile-security.rst +++ b/source/security-guide/mobile-security.rst @@ -87,6 +87,15 @@ Additionally, administrators can control link navigation within PDF files when s Learn more about :ref:`enabling secure file preview on mobile ` and :ref:`allow PDF link navigation on mobile ` in the Mattermost mobile app. +Mobile watermarking +------------------- + +Mobile watermarking is an experimental Enterprise capability available from Mattermost v11.7 onward that helps organizations identify the source and timing of mobile screenshots or shared screen captures. When enabled by a system admin, authenticated Mattermost mobile sessions display a visible watermark overlay that includes the user's username, the server domain, and the current date and time. This supports data loss prevention (DLP) workflows by attributing any image taken of the Mattermost mobile app to a specific user, server, and point in time. + +The mobile watermark is a visual overlay only. It does not prevent screenshots, screen recordings, file exports, or content sharing through other means, and it is not a substitute for screen capture prevention or other mobile security controls. Mobile watermarking is disabled by default. + +Learn more about Mattermost :ref:`mobile watermarking ` and how to :ref:`enable the experimental Mobile Watermark setting `. + Burn-on-read messages --------------------- From 87040f270251d25d5ce7dd4c8b4a06d5da4d95f8 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 00:35:15 +0000 Subject: [PATCH 2/6] Clarify Enterprise plan scope for mobile watermarking Address CodeRabbit review: explicitly state Enterprise and Enterprise Advanced plan availability in the deployment-guide mobile watermarking section to mirror the admin and security pages and avoid misleading self-hosted, non-Enterprise admins. Co-authored-by: Combs7th --- source/deployment-guide/mobile/mobile-security-features.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/deployment-guide/mobile/mobile-security-features.rst b/source/deployment-guide/mobile/mobile-security-features.rst index 7b2dac5e8c3..b58cb289f31 100644 --- a/source/deployment-guide/mobile/mobile-security-features.rst +++ b/source/deployment-guide/mobile/mobile-security-features.rst @@ -56,7 +56,7 @@ See the :ref:`secure file preview `__ from Mattermost v11.7 onward, that helps organizations attribute mobile screenshots and shared screen captures to a specific user, server, and point in time. When this setting is enabled by a system admin, authenticated Mattermost mobile sessions display a visible watermark overlay on top of the app interface that includes: - The user's username. - The server domain. From 57868fc65d276e7e4dda4c6df05fe42b62ad4cf7 Mon Sep 17 00:00:00 2001 From: Combs7th <147677911+Combs7th@users.noreply.github.com> Date: Mon, 11 May 2026 17:39:57 -0700 Subject: [PATCH 3/6] Update generate_changelog.py --- .github/scripts/generate_changelog.py | 28 +++++++-------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/.github/scripts/generate_changelog.py b/.github/scripts/generate_changelog.py index a8c213bc3d2..0efb6614f5d 100644 --- a/.github/scripts/generate_changelog.py +++ b/.github/scripts/generate_changelog.py @@ -79,27 +79,13 @@ def get_milestone_number(repo: str, title: str) -> int | None: """Look up the numeric ID for a milestone by its title in the given repo.""" url = f"https://api.github.com/repos/{repo}/milestones" - page = 1 - recent_titles = [] - while True: - params = { - "state": "all", - "per_page": 100, - "page": page, - "sort": "due_on", # sort by due date - "direction": "desc", # most recently due first, so active milestones are found quickly - } - resp = requests.get(url, headers=HEADERS, params=params, timeout=30) - resp.raise_for_status() - milestones = resp.json() - if not milestones: - break - for m in milestones: - if m["title"] == title: - return m["number"] - if page == 1: - recent_titles = [m["title"] for m in milestones[:10]] - page += 1 + params = {"state": "all", "per_page": 100} + resp = requests.get(url, headers=HEADERS, params=params) + resp.raise_for_status() + milestones = resp.json() + for m in milestones: + if m["title"] == title: + return m["number"] print(f" ⚠️ Milestone '{title}' not found in {repo} — skipping") if recent_titles: print(f" Most recently due milestones: {', '.join(recent_titles)}") From 20a8b9971d0d129d003090b0299167abbed64362 Mon Sep 17 00:00:00 2001 From: Combs7th <147677911+Combs7th@users.noreply.github.com> Date: Mon, 11 May 2026 17:40:33 -0700 Subject: [PATCH 4/6] Update generate_changelog.py --- .github/scripts/generate_changelog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/generate_changelog.py b/.github/scripts/generate_changelog.py index 0efb6614f5d..67a06b1478a 100644 --- a/.github/scripts/generate_changelog.py +++ b/.github/scripts/generate_changelog.py @@ -79,7 +79,7 @@ def get_milestone_number(repo: str, title: str) -> int | None: """Look up the numeric ID for a milestone by its title in the given repo.""" url = f"https://api.github.com/repos/{repo}/milestones" - params = {"state": "all", "per_page": 100} + params = {"state": "all", "per_page": 100} resp = requests.get(url, headers=HEADERS, params=params) resp.raise_for_status() milestones = resp.json() From a678d6300bc89ad84110e667c2332c1fb0423014 Mon Sep 17 00:00:00 2001 From: Combs7th <147677911+Combs7th@users.noreply.github.com> Date: Mon, 11 May 2026 17:41:12 -0700 Subject: [PATCH 5/6] Update generate_changelog.py --- .github/scripts/generate_changelog.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/scripts/generate_changelog.py b/.github/scripts/generate_changelog.py index 67a06b1478a..31fdb38112f 100644 --- a/.github/scripts/generate_changelog.py +++ b/.github/scripts/generate_changelog.py @@ -87,8 +87,9 @@ def get_milestone_number(repo: str, title: str) -> int | None: if m["title"] == title: return m["number"] print(f" ⚠️ Milestone '{title}' not found in {repo} — skipping") - if recent_titles: - print(f" Most recently due milestones: {', '.join(recent_titles)}") + available = [m["title"] for m in milestones] + if available: + print(f" Available milestones: {', '.join(available[:10])}") return None From 9f28b95c633fd94390f295a63201c2b57c323cae Mon Sep 17 00:00:00 2001 From: Combs7th <147677911+Combs7th@users.noreply.github.com> Date: Mon, 11 May 2026 17:41:35 -0700 Subject: [PATCH 6/6] Update generate_changelog.py --- .github/scripts/generate_changelog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/generate_changelog.py b/.github/scripts/generate_changelog.py index 31fdb38112f..7ec3b1da06c 100644 --- a/.github/scripts/generate_changelog.py +++ b/.github/scripts/generate_changelog.py @@ -87,7 +87,7 @@ def get_milestone_number(repo: str, title: str) -> int | None: if m["title"] == title: return m["number"] print(f" ⚠️ Milestone '{title}' not found in {repo} — skipping") - available = [m["title"] for m in milestones] + available = [m["title"] for m in milestones] if available: print(f" Available milestones: {', '.join(available[:10])}") return None