snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
This commit is contained in:
@@ -0,0 +1,874 @@
|
||||
---
|
||||
title: "Configure Microsoft Intune Mobile Application Management (MAM)"
|
||||
sidebar_label: "Configure Microsoft Intune MAM"
|
||||
---
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
You can configure the Mattermost Mobile App on iOS to enforce Microsoft Intune App Protection Policies (MAM) so organizational data remains protected on Bring Your Own Device (BYOD) and mixed-use devices without requiring device enrollment (MDM).
|
||||
|
||||
This guide documents the required configuration to enable Intune MAM successfully on iOS.
|
||||
|
||||
## Read This First
|
||||
|
||||
Intune MAM enforcement in Mattermost is identity-based and applies only to the sign-in method selected as the enforced **Auth Provider** in **System Console \> Environment \> Mobile Security**.
|
||||
|
||||
- The enforced authentication provider must resolve users using Azure AD `objectId` (`IdAttribute = objectId`).
|
||||
- MSAL access tokens must include the `oid` claim, and it must match the same Azure AD `objectId` (confirm identity alignment: `objectId ↔ oid`).
|
||||
|
||||
<Important>
|
||||
|
||||
If Intune MAM enrollment fails due to a technical error, the affected Mattermost server is removed from the mobile app and cached data for that server is wiped from the device.
|
||||
|
||||
</Important>
|
||||
|
||||
## Unsupported Scenarios
|
||||
|
||||
This guide doesn't apply when:
|
||||
|
||||
- You require Intune MAM on Android devices.
|
||||
- You want Intune MAM enforcement for a sign-in method not backed by Microsoft Entra ID.
|
||||
- The enforced authentication provider cannot resolve users to Azure AD `objectId`.
|
||||
- You require a rollout model where users can bypass or defer Intune MAM for the enforced sign-in method.
|
||||
|
||||
Other authentication methods, such as guest access, may still be enabled separately, but they aren't evaluated by Intune MAM.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Confirm the following before continuing:
|
||||
|
||||
- Microsoft Entra ID is used for authentication.
|
||||
- You can commit to Azure AD `objectId` as the authoritative identity.
|
||||
- Mattermost Enterprise Advanced licensing is available for the server.
|
||||
- Target users are licensed for Microsoft Intune.
|
||||
- You can register applications and grant tenant-wide admin consent in Microsoft Entra.
|
||||
- If enforcing Intune MAM on SAML, users already exist in Mattermost (mobile sign-in does not create users for SAML).
|
||||
|
||||
<Note>
|
||||
|
||||
In this guide, OpenID Connect (OIDC) refers to the Microsoft Entra sign-in method used by the Mattermost Mobile App via MSAL.
|
||||
|
||||
</Note>
|
||||
|
||||
## Configuration Overview
|
||||
|
||||
Successful Intune MAM enforcement requires coordinated configuration across:
|
||||
|
||||
- **Microsoft Entra ID** – app registration, scope, API permissions, admin consent
|
||||
- **Microsoft Intune** – iOS App Protection Policies
|
||||
- **Mattermost Server** – MAM enablement and provider selection
|
||||
- **Mattermost Mobile App (iOS)** – enrollment and enforcement
|
||||
|
||||
Complete the steps below in order.
|
||||
|
||||
## Setup Summary
|
||||
|
||||
1. Confirm identity requirements and alignment (`objectId ↔ oid`).
|
||||
2. Configure Microsoft Entra (server-referenced application).
|
||||
3. Configure Intune App Protection Policies.
|
||||
4. Enable Intune MAM in Mattermost and select the enforced provider.
|
||||
5. Deploy the official Mattermost iOS app.
|
||||
6. Validate enrollment and enforcement.
|
||||
|
||||
## Values You’ll Need Later
|
||||
|
||||
Capture these during setup:
|
||||
|
||||
<table style={{width: '99%'}}>
|
||||
<colgroup>
|
||||
<col style={{width: '23%'}} />
|
||||
<col style={{width: '30%'}} />
|
||||
<col style={{width: '46%'}} />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Value</th>
|
||||
<th>Where to get it</th>
|
||||
<th>Where you use it</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Directory (tenant) ID</td>
|
||||
<td>Entra app registration overview</td>
|
||||
<td>Mattermost System Console</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Application (client) ID</td>
|
||||
<td>Entra app registration overview</td>
|
||||
<td>Mattermost System Console</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Application ID URI</td>
|
||||
<td>Entra app > Expose an API</td>
|
||||
<td>Used to form the <code>api://<APPLICATION-ID>/login.mattermost</code> scope reference in Authorized client applications</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>login.mattermost</code> scope</td>
|
||||
<td>Entra app > Expose an API</td>
|
||||
<td>Authorized client applications</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mobile client application ID</td>
|
||||
<td>Provided by Mattermost</td>
|
||||
<td>Entra app > Authorized client applications</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>iOS bundle IDs (prod/beta)</td>
|
||||
<td>This guide</td>
|
||||
<td>Intune App Protection Policies</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Step 1: Identity Configuration for Intune MAM
|
||||
|
||||
<div id="step-1-identity-configuration-for-intune-mam">
|
||||
|
||||
This step defines the required identity model for the authentication provider selected for Intune MAM enforcement.
|
||||
|
||||
</div>
|
||||
|
||||
### Required Identity Model
|
||||
|
||||
Microsoft Intune MAM for Mattermost requires Azure AD `objectId` as the authoritative user identifier. The following is non-negotiable.
|
||||
|
||||
- `IdAttribute` must equal `objectId` for the enforced provider.
|
||||
- MSAL access tokens must include the `oid` claim.
|
||||
- Confirm identity alignment (`objectId ↔ oid`) before enabling Intune MAM.
|
||||
|
||||
### Confirm Identity Alignment (objectId ↔ oid)
|
||||
|
||||
<div id="identity-alignment-objectid-oid">
|
||||
|
||||
For the same user, the following values must match:
|
||||
|
||||
</div>
|
||||
|
||||
- Azure AD `objectId`
|
||||
- MSAL access token `oid` claim
|
||||
- SAML `objectidentifier` (if applicable)
|
||||
- LDAP `msDS-aadObjectId` (if applicable)
|
||||
|
||||
Any mismatch prevents enrollment.
|
||||
|
||||
### Identity Enforcement by Authentication Method
|
||||
|
||||
**OIDC (Mobile sign-in via MSAL)**
|
||||
|
||||
- Mattermost uses the MSAL access token for identity and enrollment.
|
||||
- Confirm identity alignment (`objectId ↔ oid`).
|
||||
|
||||
**SAML (Entra-backed)**
|
||||
|
||||
- `SamlSettings.IdAttribute` must map to `objectidentifier`.
|
||||
- Email, UPN, and `immutableID` aren't supported.
|
||||
- Users must already exist in Mattermost before mobile sign-in.
|
||||
|
||||
**LDAP (Entra ID Domain Services)**
|
||||
|
||||
- Use `msDS-aadObjectId`.
|
||||
- Do not use `objectGUID`.
|
||||
|
||||
### Runtime Enforcement Behavior
|
||||
|
||||
When Intune MAM is enabled for a provider:
|
||||
|
||||
- Enforcement occurs during active sessions, not only at login.
|
||||
- If Intune MAM becomes newly required due to policy, licensing, or configuration changes, enrollment may be triggered immediately.
|
||||
- Users can’t bypass enforcement for the enforced provider.
|
||||
|
||||
### Pre-flight Checklist
|
||||
|
||||
- Licensed Intune test user available
|
||||
- Ability to grant tenant-wide admin consent
|
||||
- Enforced provider identified (OIDC or SAML)
|
||||
- `IdAttribute = objectId` configured
|
||||
- Identity alignment verified (`objectId ↔ oid`)
|
||||
- Official Mattermost iOS app deployed
|
||||
- Target bundle IDs known: `com.mattermost.rn` (Production), `com.mattermost.rnbeta` (Beta)
|
||||
|
||||
## Step 2: Microsoft Entra Configuration for Intune MAM
|
||||
|
||||
<div id="step-2-microsoft-entra-configuration-for-intune-mam">
|
||||
|
||||
You register a single-tenant Microsoft Entra application that is referenced by Mattermost Server. This application validates MSAL access tokens and supports Intune MAM enrollment.
|
||||
|
||||
</div>
|
||||
|
||||
You don't register the Mattermost Mobile app itself. Redirect URI configuration isn't required.
|
||||
|
||||
### Entra Application Registration
|
||||
|
||||
1. Go to **Identity \> Applications \> App registrations**
|
||||
2. Select **New registration**
|
||||
3. Configure:
|
||||
- **Name**: Mattermost Mobile (Intune MAM)
|
||||
- **Supported account types**: Single tenant
|
||||
4. Register the app
|
||||
5. Copy:
|
||||
- **Application (client) ID**
|
||||
- **Directory (tenant) ID**
|
||||
|
||||
### Expose the API and Create the Scope
|
||||
|
||||
1. Go to **Expose an API**
|
||||
2. Confirm **Application ID URI** is set (for example, `api://<APPLICATION-ID>`)
|
||||
3. Add a scope named `login.mattermost`
|
||||
4. Save your changes.
|
||||
|
||||
### Authorize the Official Mobile Client
|
||||
|
||||
Authorize the official Mattermost Mobile client application ID (provided by Mattermost) to request the `login.mattermost` scope.
|
||||
|
||||
1. In the Entra app registration, go to **Expose an API**.
|
||||
2. Under **Authorized client applications**, select **Add a client application**.
|
||||
3. Add the official Mattermost Mobile client application ID (provided by Mattermost) as:
|
||||
|
||||
> - Beta: `64e9952b-20eb-46dc-92ad-99089ed24903`
|
||||
> - Production: `9ac649f1-4f77-44d6-9792-b2f54ab3c9a7`
|
||||
|
||||
4. Authorize the `api://<APPLICATION-ID>/login.mattermost` scope.
|
||||
5. Save your changes.
|
||||
|
||||
### API Permissions and Admin Consent
|
||||
|
||||
<div id="api-permissions-admin-consent">
|
||||
|
||||
1. Go to **API permissions**.
|
||||
2. Select **Add a permission**.
|
||||
3. Add the following **Microsoft Graph** delegated permissions:
|
||||
- Microsoft Graph → `email` (Delegated)
|
||||
- Microsoft Graph → `profile` (Delegated)
|
||||
4. Select **Grant admin consent** for your tenant.
|
||||
|
||||
</div>
|
||||
|
||||
These are the permissions the customer admin must grant for the Entra application referenced by Mattermost Server.
|
||||
|
||||
If these permissions are missing or lack tenant-wide admin consent, enrollment can fail with an Entra permissions/admin-consent error (for example, `AADSTS650057`) or a user-visible **Consent Denied** message during first sign-in.
|
||||
|
||||
### Configure MSAL tokens and required claims
|
||||
|
||||
Before enabling Intune MAM, ensure the Entra app registration issues access tokens with the claims Mattermost expects during mobile sign-in.
|
||||
|
||||
1. In the Entra app registration, go to **Token configuration**.
|
||||
2. Select **Add optional claim**.
|
||||
3. Under **Token type**, select **Access**.
|
||||
4. Add the following optional claims:
|
||||
- `email`
|
||||
- `family_name`
|
||||
- `given_name`
|
||||
- `preferred_username`
|
||||
- `upn`
|
||||
5. Save your changes.
|
||||
|
||||
<Note>
|
||||
|
||||
Mattermost Intune MAM enforcement uses the MSAL access token. If required claims are missing, sign-in and/or enrollment may fail.
|
||||
|
||||
</Note>
|
||||
|
||||
### Enable MSAL v2 access tokens
|
||||
|
||||
1. Open the app **Manifest**.
|
||||
2. Set the token version to `2`:
|
||||
- If your manifest shows `api.requestedAccessTokenVersion`, set it to `2`.
|
||||
- Otherwise set `accessTokenAcceptedVersion` to `2`.
|
||||
3. Save your changes.
|
||||
|
||||
## Step 3: Configure Intune App Protection Policies
|
||||
|
||||
1. Go to **Intune admin center \> Apps \> App protection policies**.
|
||||
2. Create a policy:
|
||||
- **Platform**: iOS/iPadOS
|
||||
- **Targeted app**: Managed apps
|
||||
3. Add the Mattermost app by bundle ID:
|
||||
- `com.mattermost.rn` (Production)
|
||||
- `com.mattermost.rnbeta` (Beta)
|
||||
4. Configure protection settings.
|
||||
5. Assign to Entra ID user groups.
|
||||
6. Save your changes.
|
||||
|
||||
Separate policies are required for Production and Beta apps.
|
||||
|
||||
## Step 4: Configure Mattermost Server for Intune MAM
|
||||
|
||||
<div id="step-4-configure-mattermost-server-for-intune-mam">
|
||||
|
||||
1. Go to **System Console \> Environment \> Mobile Security**
|
||||
2. Set **Enable Microsoft Intune MAM** to **True**
|
||||
3. Select **Auth Provider**:
|
||||
- OpenID Connect (Entra-backed)
|
||||
- SAML 2.0 (Entra-backed)
|
||||
4. Enter:
|
||||
- **Tenant ID**
|
||||
- **Application (Client) ID**
|
||||
5. Save your changes.
|
||||
|
||||
</div>
|
||||
|
||||
The enforced provider must resolve identity using `IdAttribute = objectId`.
|
||||
|
||||
## Step 5: Deploy the Mattermost iOS App
|
||||
|
||||
Download and install the official Mattermost iOS app using:
|
||||
|
||||
- Apple App Store (Production)
|
||||
- TestFlight (Beta)
|
||||
|
||||
Wrapped, re-signed, or privately distributed apps aren't supported.
|
||||
|
||||
## Step 6: Validate Enrollment
|
||||
|
||||
Validate with a licensed test user on iOS.
|
||||
|
||||
Confirm:
|
||||
|
||||
- Enrollment completes successfully
|
||||
- Enforcement applies at sign-in and mid-session
|
||||
- Identity alignment is correct (`objectId ↔ oid`)
|
||||
|
||||
## Expected Behavior During Mobile Sign-In
|
||||
|
||||
1. User signs in via MSAL.
|
||||
2. Mattermost validates the access token.
|
||||
3. Intune MAM enrollment is triggered.
|
||||
4. App Protection Policies are applied.
|
||||
|
||||
If enrollment is required but cannot complete, access is blocked until enrollment succeeds.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<div id="troubleshooting">
|
||||
|
||||
Most failures are caused by:
|
||||
|
||||
</div>
|
||||
|
||||
- Identity mismatch (`objectId ↔ oid`)
|
||||
- `IdAttribute` not set to `objectId`
|
||||
- Missing Entra API permissions or admin consent
|
||||
- App Protection Policy not targeting the user or app
|
||||
- Unsupported client or platform
|
||||
|
||||
### Quick Diagnostics
|
||||
|
||||
1. Confirm identity alignment (`objectId ↔ oid`).
|
||||
2. Confirm `IdAttribute = objectId`.
|
||||
3. Confirm Entra permissions and admin consent.
|
||||
4. Confirm Auth Provider selection.
|
||||
5. Confirm Intune policy targeting.
|
||||
|
||||
If the user declines enrollment, retry is allowed.
|
||||
|
||||
### Intune MAM Errors
|
||||
|
||||
The errors below may occur during mobile sign-in or when Intune MAM enforcement is triggered mid-session. Some errors are shown in the Mattermost Mobile App, while others are silent and must be diagnosed using Mattermost server logs.
|
||||
|
||||
<Note>
|
||||
|
||||
In the table below, **Fallback: Web SSO** means the mobile app uses the **non-Intune** version of the configured sign-in method (SAML or OpenID Connect) as if Intune MAM were not enabled.
|
||||
|
||||
</Note>
|
||||
|
||||
<style>
|
||||
/* Compact, scannable 3-column table with full inline metadata and strong grid lines */
|
||||
.mm-intune-errors {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed; /* prevents horizontal scrolling */
|
||||
margin: 0.75rem 0 1rem 0;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.35;
|
||||
border: 1px solid #b3b3b3;
|
||||
}
|
||||
|
||||
.mm-intune-errors th,
|
||||
.mm-intune-errors td {
|
||||
padding: 0.6rem 0.7rem;
|
||||
vertical-align: top;
|
||||
border: 1px solid #b3b3b3;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
white-space: normal;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Light mode header: explicit contrast */
|
||||
.mm-intune-errors th {
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
background-color: #f2f2f2;
|
||||
color: #111111;
|
||||
}
|
||||
|
||||
/* Strong row separation */
|
||||
.mm-intune-errors tbody tr + tr td {
|
||||
border-top-width: 2px;
|
||||
}
|
||||
|
||||
.mm-intune-errors code {
|
||||
font-size: 0.9em;
|
||||
white-space: normal;
|
||||
padding: 0.1em 0.25em;
|
||||
border-radius: 4px;
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.mm-intune-errors .meta {
|
||||
opacity: 0.92;
|
||||
font-size: 0.92em;
|
||||
margin-top: 0.35rem;
|
||||
}
|
||||
|
||||
.mm-intune-errors .meta div {
|
||||
margin: 0.08rem 0;
|
||||
}
|
||||
|
||||
.mm-intune-errors .label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Dark mode override */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.mm-intune-errors,
|
||||
.mm-intune-errors th,
|
||||
.mm-intune-errors td {
|
||||
border-color: #666;
|
||||
}
|
||||
|
||||
.mm-intune-errors th {
|
||||
background-color: #2a2a2a;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.mm-intune-errors code {
|
||||
background: rgba(255, 255, 255, 0.14);
|
||||
}
|
||||
|
||||
.mm-intune-errors .meta {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<table class="mm-intune-errors" aria-label="Microsoft Intune MAM errors and admin remediation steps">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{width: '30%'}}>Error</th>
|
||||
<th style={{width: '22%'}}>Meaning</th>
|
||||
<th style={{width: '48%'}}>Admin cause & next step</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{/* Enrollment Failed */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Enrollment Failed</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>(varies)</code></div>
|
||||
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
|
||||
<div><span class="label">Scenario:</span> Enrollment failed (technical)</div>
|
||||
<div><span class="label">User message:</span> "Enrollment Failed"</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
Intune MAM enrollment failed due to a technical error.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Enrollment could not be completed due to a technical failure (MSAL error, Intune enrollment API failure, identity mismatch, or missing Entra permissions).<br/>
|
||||
<span class="label">Behavior:</span> The server is removed immediately and there is no retry option; cached data for that server is wiped.<br/>
|
||||
<span class="label">Next step:</span> Fix the underlying issue, then have the user re-add the server in the mobile app.<br/>
|
||||
<span class="label">Admin checks:</span> Verify <code>IdAttribute = objectId</code>; confirm identity alignment (<code>objectId ↔ oid</code>); confirm tenant-wide admin consent; confirm App Protection Policy targets the user and the correct iOS bundle ID.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Enrollment Declined */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Enrollment Declined</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>(varies)</code></div>
|
||||
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
|
||||
<div><span class="label">Scenario:</span> User declined enrollment</div>
|
||||
<div><span class="label">User message:</span> "Enrollment Declined"</div>
|
||||
<div><span class="label">Retry:</span> Yes</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The user declined Intune MAM enrollment.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> The user canceled the enrollment prompt.<br/>
|
||||
<span class="label">Behavior:</span> A <strong>Retry</strong> option is shown; no server data is removed unless a later technical enrollment failure occurs.<br/>
|
||||
<span class="label">Next step:</span> Instruct the user to retry enrollment when ready.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Consent Denied (admin consent missing) */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Consent Denied</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>(varies)</code></div>
|
||||
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
|
||||
<div><span class="label">Scenario:</span> Admin consent missing (first login)</div>
|
||||
<div><span class="label">User message:</span> "You denied consent for Intune management. The affected accounts have been unenrolled and signed out."</div>
|
||||
<div><span class="label">Retry:</span> Yes (after admin consent)</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
Enrollment cannot complete because required Entra app permissions don’t have tenant-wide admin consent.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Tenant-wide admin consent has not been granted for the required delegated permissions on the Entra app registration configured in Mattermost Server.<br/>
|
||||
<span class="label">Behavior:</span> The message may appear as if the user denied consent, but the underlying issue is missing admin consent.<br/>
|
||||
<span class="label">Next step:</span> In Microsoft Entra, grant tenant-wide admin consent for Microsoft Graph delegated permissions <code>email</code> and <code>profile</code> on the same Entra app registration configured in Mattermost, then have the user retry mobile sign-in.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Enterprise not compiled */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>(silent)</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>api.user.login_by_intune.not_available.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 501</div>
|
||||
<div><span class="label">Scenario:</span> Enterprise not compiled</div>
|
||||
<div><span class="label">User message:</span> (silent)</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> Standard SSO (non-Intune)</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
Intune MAM login is not available on this server.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> The server does not support Intune MAM (feature not available in this build or not enabled for the deployment).<br/>
|
||||
<span class="label">Next step:</span> Confirm the server build includes Intune MAM support and the deployment is licensed for Enterprise Advanced.<br/>
|
||||
<span class="label">User guidance:</span> Have the user sign in via web/desktop using the standard (non-Intune) SSO flow for their provider (SAML or OpenID Connect) while the server is updated or configuration is corrected.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Intune not configured */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>(silent)</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>api.user.login_by_intune.not_configured.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 400</div>
|
||||
<div><span class="label">Scenario:</span> Intune not configured</div>
|
||||
<div><span class="label">User message:</span> (silent)</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> Standard SSO (non-Intune)</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
Intune MAM is enabled for the org but not configured on the server.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Intune MAM isn't fully configured in <strong>System Console > Environment > Mobile Security</strong>.<br/>
|
||||
<span class="label">Next step:</span> Enable Microsoft Intune MAM and ensure <strong>Tenant ID</strong>, <strong>Application (Client) ID</strong>, and <strong>Auth Provider</strong> are set correctly.<br/>
|
||||
<span class="label">Admin checks:</span> Confirm the selected auth provider is Entra-backed and required permissions/admin consent have been granted for the Entra app registration.<br/>
|
||||
<span class="label">User guidance:</span> Have the user sign in via web/desktop using the standard (non-Intune) SSO flow for their provider (SAML or OpenID Connect) while the server is updated or configuration is corrected.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Bot login forbidden */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Bot accounts cannot sign in using this method.</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>api.user.login_by_intune.bot_login_forbidden.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 403</div>
|
||||
<div><span class="label">Scenario:</span> Bot tried to login</div>
|
||||
<div><span class="label">User message:</span> "Bot accounts cannot sign in using this method."</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The account cannot use Intune MAM sign-in.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Bot accounts are not allowed to authenticate via Intune MAM.<br/>
|
||||
<span class="label">Next step:</span> Use a human user account for Intune MAM enrollment and access.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Account locked/deactivated */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Your account has been deactivated. Please contact your administrator.</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>api.user.login_by_intune.account_locked.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 409</div>
|
||||
<div><span class="label">Scenario:</span> User deleted/disabled</div>
|
||||
<div><span class="label">User message:</span> "Your account has been deactivated. Please contact your administrator."</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The account is not permitted to sign in.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> The user is deleted, disabled, or locked in Mattermost.<br/>
|
||||
<span class="label">Next step:</span> Re-enable or restore the user account in Mattermost, then retry sign-in and enrollment.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* IsConfigured() false */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>(silent)</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>ent.intune.login.not_configured.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 403</div>
|
||||
<div><span class="label">Scenario:</span> IsConfigured() = false</div>
|
||||
<div><span class="label">User message:</span> (silent)</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> Standard SSO (non-Intune)</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
Intune MAM is not configured for the current sign-in path.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Intune MAM isn't configured for the requested authentication path (configuration incomplete or mismatched provider selection).<br/>
|
||||
<span class="label">Next step:</span> Confirm Intune MAM is enabled and configured, and the selected <strong>Auth Provider</strong> matches how users authenticate (OIDC vs SAML).<br/>
|
||||
<span class="label">User guidance:</span> Have the user sign in via web/desktop using the standard (non-Intune) SSO flow for their provider (SAML or OpenID Connect) while the server is updated or configuration is corrected.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* IdAttribute mapping failed */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>We couldn't complete your sign in. Please try again.</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>ent.intune.login.extract_auth_data.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 400</div>
|
||||
<div><span class="label">Scenario:</span> IdAttribute mapping failed</div>
|
||||
<div><span class="label">User message:</span> "We couldn't complete your sign in. Please try again."</div>
|
||||
<div><span class="label">Retry:</span> Yes (1x)</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
Identity mapping failed during sign-in.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> The server couldn’t extract or map the identity attribute required for Intune MAM (commonly <code>IdAttribute</code> is misconfigured or the token isn't MSAL v2).<br/>
|
||||
<span class="label">Next step:</span> Ensure <code>IdAttribute = objectId</code>, then confirm identity alignment (<code>objectId ↔ oid</code>). Verify the Entra app issues v2 tokens (<code>accessTokenAcceptedVersion = 2</code>).
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* SAML user not found */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Your account isn't fully set up yet. Please sign in to Mattermost via the web or desktop app first.</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>ent.intune.login.account_not_found.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 428</div>
|
||||
<div><span class="label">Scenario:</span> SAML user account not found</div>
|
||||
<div><span class="label">User message:</span> "Your account isn't fully set up yet. Please sign in to Mattermost via the web or desktop app first."</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The user does not exist in Mattermost for SAML-based sign-in.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> When SAML is the selected provider for Intune MAM enforcement, mobile sign-in cannot create a new user.<br/>
|
||||
<span class="label">Next step:</span> Have the user sign in once via the web or desktop app to provision the account, then retry mobile sign-in.<br/>
|
||||
<span class="label">Admin checks:</span> Ensure provisioning is in place (web/desktop first sign-in, LDAP sync, or another provisioning method).
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Token validation failed */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>We couldn't verify your sign in. Please try again.</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>ent.intune.validate_token.invalid_token.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 400</div>
|
||||
<div><span class="label">Scenario:</span> Token validation failed</div>
|
||||
<div><span class="label">User message:</span> "We couldn't verify your sign in. Please try again."</div>
|
||||
<div><span class="label">Retry:</span> Yes (1x)</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The access token could not be validated.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Token validation failed (token malformed, wrong issuer/audience, missing permissions, or Entra configuration mismatch).<br/>
|
||||
<span class="label">Next step:</span> Verify the configured <strong>Tenant ID</strong> and <strong>Application (Client) ID</strong> match the Entra app registration referenced by Mattermost Server. Confirm tenant-wide admin consent has been granted for Microsoft Graph delegated permissions <code>email</code> and <code>profile</code> on that same app registration. Then confirm identity alignment (<code>objectId ↔ oid</code>) for the affected user.<br/>
|
||||
<span class="label">Admin checks:</span> Confirm v2 tokens (<code>accessTokenAcceptedVersion = 2</code>) and that Microsoft Graph delegated permissions <code>email</code> and <code>profile</code> have tenant-wide admin consent.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Token expired */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Your sign in session has expired. Please try signing in again.</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>ent.intune.validate_token.token_expired.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 400</div>
|
||||
<div><span class="label">Scenario:</span> Token expired</div>
|
||||
<div><span class="label">User message:</span> "Your sign in session has expired. Please try signing in again."</div>
|
||||
<div><span class="label">Retry:</span> Yes (1x)</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The authentication session expired before enrollment completed.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> The access token or interactive session expired during sign-in/enrollment.<br/>
|
||||
<span class="label">Next step:</span> Have the user sign in again and complete enrollment promptly.<br/>
|
||||
<span class="label">Admin checks:</span> If repeated, confirm the device can reach Entra/Intune endpoints during enrollment and prompts aren't being blocked.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Missing claims */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>We couldn't complete your sign in. Please contact your IT administrator.</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>ent.intune.validate_token.missing_claims.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 400</div>
|
||||
<div><span class="label">Scenario:</span> Required claims missing</div>
|
||||
<div><span class="label">User message:</span> "We couldn't complete your sign in. Please contact your IT administrator."</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The access token is missing required claims for sign-in and enrollment.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Required claims are missing from the MSAL access token (most commonly <code>oid</code>, or optional claims required by Mattermost).<br/>
|
||||
<span class="label">Next step:</span> Confirm MSAL v2 access tokens are issued (<code>accessTokenAcceptedVersion = 2</code>) and the token includes <code>oid</code>. In the Entra app registration, go to <strong>Token configuration</strong> and ensure optional claims are added for the <strong>Access</strong> token: <code>email</code>, <code>family_name</code>, <code>given_name</code>, <code>preferred_username</code>, and <code>upn</code>. Confirm the enforced provider uses <code>IdAttribute = objectId</code>, then verify identity alignment (<code>objectId ↔ oid</code>).
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Invalid tenant */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>There was a configuration issue. Please contact your IT administrator.</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>ent.intune.validate_token.invalid_tenant_id.app_error</code></div>
|
||||
<div><span class="label">HTTP:</span> 400</div>
|
||||
<div><span class="label">Scenario:</span> Token tenant ≠ configured tenant</div>
|
||||
<div><span class="label">User message:</span> "There was a configuration issue. Please contact your IT administrator."</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The token tenant does not match the configured tenant.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> The token was issued by a different tenant than the one configured in Mattermost.<br/>
|
||||
<span class="label">Next step:</span> Verify the <strong>Tenant ID</strong> configured in <strong>System Console > Environment > Mobile Security</strong> matches the Entra tenant issuing MSAL tokens for the user.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* AADSTS650057 */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>AADSTS650057</strong><br/>
|
||||
<span class="meta">(invalid_resource)</span>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>(AADSTS650057)</code></div>
|
||||
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
|
||||
<div><span class="label">Scenario:</span> invalid_resource</div>
|
||||
<div><span class="label">User message:</span> (MSAL/Entra error)</div>
|
||||
<div><span class="label">Retry:</span> No (until fixed)</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The Entra app configuration is missing required permissions and/or admin consent.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Required Intune MAM API permissions are missing or do not have tenant-wide admin consent.<br/>
|
||||
<span class="label">Next step:</span> In the Microsoft Entra admin center, go to <strong>Enterprise applications</strong> (not App registrations), search for <strong>Mattermost Mobile</strong> / <strong>Mattermost Mobile Beta</strong>, then open <strong>Permissions</strong> and add/grant admin consent for the Intune MAM permissions (for example, <code>https://msmamservice.api.application/.default</code> and <strong>Microsoft Mobile Application Management</strong> → <code>user_impersonation</code> (Delegated)). Then have the user retry sign-in.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* NotLicensed */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>NotLicensed</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>(NotLicensed)</code></div>
|
||||
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
|
||||
<div><span class="label">Scenario:</span> License missing or inactive</div>
|
||||
<div><span class="label">User message:</span> (varies)</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
The server is not licensed for Intune MAM enforcement.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> Enterprise Advanced licensing is missing or not applied to the server.<br/>
|
||||
<span class="label">Next step:</span> Apply an Enterprise Advanced license to the server and confirm the license is active, then retry.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* HTTP 403 Forbidden */}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>HTTP 403 Forbidden</strong>
|
||||
<div class="meta">
|
||||
<div><span class="label">Error ID:</span> <code>(HTTP 403)</code></div>
|
||||
<div><span class="label">HTTP:</span> 403</div>
|
||||
<div><span class="label">Scenario:</span> Server-side access blocked</div>
|
||||
<div><span class="label">User message:</span> (varies)</div>
|
||||
<div><span class="label">Retry:</span> No</div>
|
||||
<div><span class="label">Fallback:</span> None</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
Server-side access is blocked by a gating condition.
|
||||
</td>
|
||||
<td>
|
||||
<span class="label">Cause:</span> A server gating condition is preventing enrollment (not an Intune service failure).<br/>
|
||||
<span class="label">Next step:</span> Verify Enterprise Advanced licensing, Intune MAM is enabled, <strong>Auth Provider</strong> selection matches how users authenticate, configured <strong>Tenant ID</strong> and <strong>Application (Client) ID</strong> are correct, and tenant-wide admin consent is granted. Then confirm identity alignment (<code>objectId ↔ oid</code>) and Intune App Protection Policy targeting for the correct iOS bundle ID.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Consent During First Login
|
||||
|
||||
If a user’s first mobile sign-in fails with **Consent Denied** or:
|
||||
|
||||
`You denied consent for Intune management. The affected accounts have been unenrolled and signed out.`
|
||||
|
||||
Treat this as missing tenant-wide admin consent for the Entra app registration referenced by Mattermost Server. See the **Consent Denied** entry in the [Intune MAM Errors](#intune-mam-errors) table above for remediation steps.
|
||||
|
||||
To resolve this:
|
||||
|
||||
1. In the Microsoft Entra admin center, go to **Enterprise applications**.
|
||||
2. Search for **Mattermost Mobile** or **Mattermost Mobile Beta**.
|
||||
3. Go to **Permissions** and add/grant **tenant-wide admin consent** for the Intune MAM permissions (for example, `https://msmamservice.api.application/.default` and Microsoft Mobile Application Management → `user_impersonation` (Delegated)).
|
||||
4. Have the user retry mobile sign-in.
|
||||
|
||||
## Rollout and Recovery Guidance
|
||||
|
||||
- Pilot with a small group first
|
||||
- Validate identity alignment before broad rollout
|
||||
- Expect enforcement to occur mid-session if requirements change
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: "Mobile VPN options"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
To connect to your private network Mattermost instance, you need to set up a way to connect to your private network Mattermost instance, using an external proxy with encrypted transport through HTTPS and WSS network connections.
|
||||
|
||||
Depending on your security policies, we recommend deploying Mattermost behind a VPN and using a [per-app VPN](#per-app-vpn) with your EMM provider, or a mobile VPN client.
|
||||
|
||||
Also consider deploying a mobile VPN client with multi-factor authentication (MFA) to your preferred login method, such as GitLab SSO with MFA, or run Mattermost Enterprise Edition with [multi-factor authentication (MFA)](/administration-guide/onboard/multi-factor-authentication) enabled.
|
||||
|
||||
## Mobile VPN options
|
||||
|
||||
A Virtual Private Network (VPN) allows a device outside a firewall to access content inside the firewall as if it were on the same network.
|
||||
|
||||
<Note>
|
||||
|
||||
Some mobile VPN options depend on the requirements of your organization and the demands and/or the needs of your users.
|
||||
|
||||
</Note>
|
||||
|
||||
We recommend one of two options: [per-app VPN](#per-app-vpn) or a [device VPN](#device-vpn) to secure your deployment. Both options are compatible with most EMM providers.
|
||||
|
||||
We also recommend you review the following [commonly-asked questions](/deployment-guide/mobile/mobile-faq) about data security on mobile devices:
|
||||
|
||||
- How data is handled on a device after an account is deleted?
|
||||
- What post metadata is sent in mobile push notifications?
|
||||
- What are my options for securing the Mobile apps?
|
||||
- What are my options for securing push notifications?
|
||||
|
||||
### Per-app VPN
|
||||
|
||||
A common approach is to use a per-app VPN. This provides a connection to the VPN when needed (on-demand). If using a per-app VPN with Mattermost, you can configure the following options:
|
||||
|
||||
- **useVPN:** Mattermost waits until the connection to the VPN server is established before making any requests (otherwise they will fail). This is only supported on iOS as Android OS cannot support waiting. It still works but the first connection attempt may fail.
|
||||
- **timeoutVPN (iOS only):** How long to wait for the connection to the VPN server before trying.
|
||||
|
||||
### Device VPN
|
||||
|
||||
With this option, all internet traffic routes through the VPN specified in the profile. This could cause issues for personal applications.
|
||||
|
||||
## Connect via corporate proxy server
|
||||
|
||||
Review the following commonly-asked questions about connecting through a corporate proxy server:
|
||||
|
||||
- [How do I receive mobile push notifications if my IT policy requires the use of a corporate proxy server?](/deployment-guide/mobile/mobile-faq#how-do-i-receive-mobile-push-notifications-if-my-it-policy-requires-the-use-of-a-corporate-proxy-server)
|
||||
- [Deploy Mattermost with connection restricted post-proxy relay in DMZ or a trusted cloud environment](/deployment-guide/mobile/mobile-faq#deploy-mattermost-with-connection-restricted-post-proxy-relay-in-dmz-or-a-trusted-cloud-environment)
|
||||
- [Whitelist Mattermost push notification proxy to bypass your corporate proxy server](/deployment-guide/mobile/mobile-faq#whitelist-mattermost-push-notification-proxy-to-bypass-your-corporate-proxy-server)
|
||||
- [Run App Store versions of the Mattermost Mobile apps](/deployment-guide/mobile/mobile-faq#run-app-store-versions-of-the-mattermost-mobile-apps)
|
||||
@@ -0,0 +1,185 @@
|
||||
---
|
||||
title: "Deploy using an EMM provider"
|
||||
---
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
|
||||
<PlanAvailability slug="entry-ent" />
|
||||
|
||||
You can enhance mobile security by deploying the Mattermost mobile app with [Enterprise Mobility Management (EMM)](https://en.wikipedia.org/wiki/Enterprise_mobility_management) and Mattermost AppConfig compatibility to secure mobile endpoints with management application configuration.
|
||||
|
||||
You can use an EMM to:
|
||||
|
||||
- Enforce users to download the Mattermost pre-built or custom apps managed by your organization.
|
||||
- Set default server url address.
|
||||
- Restrict users from changing servers.
|
||||
- Enforce security policies.
|
||||
|
||||
An EMM provider pushes Mattermost Mobile apps to EMM-enrolled devices. This approach is recommended for organizations that typically use EMM solutions to deploy Mobile apps to meet security and compliance policies.
|
||||
|
||||
## Manage app configuration using AppConfig
|
||||
|
||||
AppConfig is our recommended approach for app configuration and management. It was introduced by the [AppConfig Community](https://www.appconfig.org/), a group of leading EMM providers and app developers who have come together to make it easier for developers and customers to drive mobility in business.
|
||||
|
||||
AppConfig provides an easy way to configure enterprise mobile apps with any EMM providers listed on the [AppConfig website](https://www.appconfig.org/). Using AppConfig, you can manage default settings and security controls on public app stores and custom-built mobile clients. For example, you can pre-configure your Mattermost server URL and username.
|
||||
|
||||
### Mattermost AppConfig values
|
||||
|
||||
The following table shows all the configuration options that can be sent from the EMM provider of your choice to the Mattermost mobile apps. You can also [download an XML template](/files/samples/mattermost-specfile.xml) of the configuration file for use with your EMM provider.
|
||||
|
||||
<style>
|
||||
table.mattermost-plans {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
table.mattermost-plans th, table.mattermost-plans td {
|
||||
border: 1px solid #888;
|
||||
padding: 6px 8px;
|
||||
vertical-align: top;
|
||||
}
|
||||
/* Dark mode border color */
|
||||
body:not([data-custom-theme="light"]) table.mattermost-plans th,
|
||||
body:not([data-custom-theme="light"]) table.mattermost-plans td {
|
||||
border-color: #666;
|
||||
}
|
||||
table.mattermost-plans th {
|
||||
background: #f2f2f2;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
/* Dark mode support for table headers */
|
||||
body:not([data-custom-theme="light"]) table.mattermost-plans th {
|
||||
background: #444;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
<table class="mattermost-plans">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Description</th>
|
||||
<th>Default/Valid Values</th>
|
||||
<th>iOS Support</th>
|
||||
<th>Android for Work Support</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong><code>inAppPinCode</code></strong><br /><em>String</em></td>
|
||||
<td>Require users to authenticate as the device owner before using the app. Prompts for fingerprint or passcode when the app first opens and when the app has been in the background for more than five minutes.</td>
|
||||
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>blurApplicationScreen</code></strong><br /><em>String</em></td>
|
||||
<td>Blur the app when it's set to background to protect any confidential on-screen information. On Android, it also prevents taking screenshots of the app.</td>
|
||||
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>jailbreakDetection</code></strong><br /><em>String</em></td>
|
||||
<td>Disable app launch on jailbroken or rooted devices.</td>
|
||||
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>copyAndPasteProtection</code></strong><br /><em>String</em></td>
|
||||
<td>Disable the ability to copy from or paste into any text inputs in the app.</td>
|
||||
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /> (since v1.24.0)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>serverUrl</code></strong><br /><em>String</em></td>
|
||||
<td>Set a default Mattermost server URL. Supports a single server only while v2.0 of the mobile app supports multiple server connections.</td>
|
||||
<td>Valid: URL</td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>serverName</code></strong><br /><em>String</em></td>
|
||||
<td>Automatically populates the server display name for the URL specified in serverURL.</td>
|
||||
<td>Valid: alphanumeric or empty</td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>allowOtherServers</code></strong><br /><em>String</em></td>
|
||||
<td>Allow the user to change the above server URL. If set to <code>true</code>, users can connect to multiple servers that aren't specified in the server URL setting. If set to <code>false</code>, users can only connect to a single defined server.</td>
|
||||
<td>Default: <code>true</code><br />Valid: <code>true | false</code></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>username</code></strong><br /><em>String</em></td>
|
||||
<td>Set the username or email address to use to authenticate against the Mattermost Server.</td>
|
||||
<td></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>useVPN</code></strong><br /><em>String</em></td>
|
||||
<td>Enable connection to the Mattermost Server to use a per-app VPN or VPN on-demand.</td>
|
||||
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>timeoutVPN</code></strong><br /><em>String</em></td>
|
||||
<td>Set how long the request waits (in milliseconds) for an initial VPN connection to establish before timeout.</td>
|
||||
<td>Default: 30000</td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>vendor</code></strong><br /><em>String</em></td>
|
||||
<td>Name of the EMM vendor or company deploying the app. Used in help text when prompting for passcodes so users are aware why the app is being protected.</td>
|
||||
<td>Default: Mattermost</td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><code>inAppSessionAuth</code></strong><br /><em>String</em></td>
|
||||
<td>Use the app's internal browser for SSO instead of an external browser. From Mattermost v10.2 and mobile v2.2.1, deprecated in favor of the <a href="../../administration-guide/configure/site-configuration-settings.html#mobile-external-browser">mobile external browser</a> server configuration setting.</td>
|
||||
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Other AppConfig settings
|
||||
|
||||
As part of AppConfig, EMM administrators can set the following additional configuration options for the Mattermost mobile apps:
|
||||
|
||||
1. **App Tunnel:** Leverage the "Per-app VPN" capabilities in most commercial VPN solutions.
|
||||
2. **Prevent App Backup:** Prevent users from backing up app data.
|
||||
3. **Enforce App Encryption:** Set security policies such as requiring encryption.
|
||||
4. **Remotely Wipe App:** Use the EMM tool to distribute the app to devices as a managed application so it can be remotely wiped. If the app was previously installed, mark it so the EMM converts the app to a managed app.
|
||||
|
||||
Other configurations may be available depending on your EMM provider.
|
||||
|
||||
<Important>
|
||||
|
||||
\- Mattermost only supports the AppConfig standard for securing Mattermost mobile apps via an EMM provider due to incompatibilities with app wrapping and React Native applications. Different EMM vendors refer to “wrapping” in different ways, but it ultimately comes down to unpacking the mobile client bundle, injecting additional SDKs, and re-packaging/re-signing. React Native is the technology used to develop the Mattermost mobile apps. - Mattermost doesn’t support app wrapping, and Mattermost mobile apps won't function properly when using app wrapping (e.g., Websockets for real-time messaging will break). Use app wrapping/containerization technology at your own risk. - A Mattermost Enterprise subscription plan (or a legacy Enterprise Edition license) is required to request assistance or troubleshooting help from [Mattermost Customer Support](https://mattermost.com/support/) when building and deploying custom mobile apps. Customers on other Mattermost subscription plans can develop and deploy custom mobile apps, but can't request technical support assistance through Mattermost Customer Support. - With the release of Mattermost mobile app v2.0, mobile app v1.55 becomes the official [extended support mobile release](/product-overview/mattermost-mobile-releases), and will be supported for an extended timeframe.
|
||||
|
||||
</Important>
|
||||
|
||||
## Enroll devices
|
||||
|
||||
When building your own custom versions or deploying the pre-built Mattermost Mobile apps, consider your organization’s mobile policy:
|
||||
|
||||
- Can users bring their own device (BYOD) If so, what devices will be used?
|
||||
- Are devices company-owned and company-issued?
|
||||
- Are both options supported?
|
||||
- What operating systems do you want to start testing?
|
||||
|
||||
Once you know what possible device configurations you’ll be supporting, consider creating a sample configuration, then running validation tests against each configuration item.
|
||||
|
||||
## Generate and assign device profiles
|
||||
|
||||
Generate and assign a device profile for device-wide configurations through the EMM provider.
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: "Distribute a custom mobile app"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
To control the look and feel of the Mattermost mobile app requires building your own mobile apps, [hosting your own push proxy service](/deployment-guide/mobile/host-your-own-push-proxy-service), and managing your own app distribution.
|
||||
|
||||
<Note>
|
||||
|
||||
- Mattermost Enterprise customers are eligible for support guidance on distributing their own custom mobile apps.
|
||||
- With the release of Mattermost mobile app v2.0, mobile app v1.55 becomes the official [extended support mobile release](/product-overview/mattermost-mobile-releases), and v1.55 will continue to be supported for an extended timeframe.
|
||||
|
||||
</Note>
|
||||
|
||||
## Key considerations
|
||||
|
||||
The Mattermost Mobile App is an open source project. Customizing Mattermost mobile apps requires a fork of the source code. Your team will be responsible for maintaining that fork, as well as keeping that fork updated with any changes made by Mattermost.
|
||||
|
||||
Building your own mobile apps will present some challenges, including:
|
||||
|
||||
- Installing the necessary developer tools (such as Nodejs, XCode Developer Tools, Android SDKs, as well as others).
|
||||
- Obtaining and providing certificates for your custom Mattermost mobile apps\*.
|
||||
- Signing your custom Mattermost mobile apps\*.
|
||||
- Distributing your Mobile app to your users.
|
||||
|
||||
This means that you manage the maintenance of your custom Mattermost mobile apps, such as rebuilding and incorporating feature and/or security updates. If this isn't done regularly, your applications won't match the functionality of our publicly-available applications, and could be incompatible with future versions of Mattermost Server.
|
||||
|
||||
This process can be complicated and can greatly increase deployment time, not only initially, but whenever the mobile apps need to be updated. We recommend having your development team [review the Mattermost Mobile Apps developer documentation](https://developers.mattermost.com/contribute/mobile/) to ensure they understand the scale and requirements of taking this path. This documentation provides guidance on building, compiling, signing, and white-labeling Mattermost Mobile apps.
|
||||
|
||||
### URL schema limitations
|
||||
|
||||
If you are building your own version of Mattermost's mobile client, you need to be aware of the following limitations:
|
||||
|
||||
- To allow users to simultaneously run the App Store versions of Mattermost, in addition to the custom company version, you will need to adapt the URL schemes used for the app in the build, as well as configure those schemes on the server using [App Custom URL Schemes](/administration-guide/configure/site-configuration-settings#app-custom-url-schemes)
|
||||
- Be aware that the `bundleid` for the application should not include `rnbeta`.
|
||||
- The same change would be required in a custom build of the Mattermost desktop app.
|
||||
- The mobile and desktop custom clients would no longer be able to log into other Mattermost servers (unless they had the same custom app schema configuration change applied).
|
||||
|
||||
## Deployment options
|
||||
|
||||
When you decide to build your own Mattermost mobile apps, you have multiple ways to deploy them to your organization.
|
||||
|
||||
Our recommend approach is to submit your app to an Enterprise App Store. Once your custom app is added to your own enterprise App Store, your users can download it from the store directly or from an EMM catalog.
|
||||
|
||||
Alternatively, use [an Enterprise Mobile Management (EMM) provider](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider) to push the mobile app to the user’s device, and use the AppConfig standard to enforce a selection of app-specific controls. Or, you can use [another distribution method](#using-another-distribution-method), such as a file sharing platform.
|
||||
|
||||
You can also submit your app to [public app stores](#using-public-app-stores). This is the same process Mattermost uses to make Mattermost mobile apps available for everyone. However, before your app can be listed on the public app stores, you need to submit it to the public app stores for review and approval.
|
||||
|
||||
- As part of the submission process, you need to identify an update strategy that accounts for the release of new versions of Mattermost mobile apps that includes reviewing compatibility requirements, validating mobile app versions connecting to the server, and updating Mattermost server.
|
||||
- We highly recommend you update your custom Mattermost mobile apps to incorporate any security or service releases.
|
||||
- Prior to distribution, check any compatibility requirements for the mobile apps and the Mattermost server.
|
||||
- Not all provided updates are compatible with all previous versions of Mattermost server. Updating only Mattermost mobile apps or updating the mobile apps before Mattermost Server can result in incompatibility issues.
|
||||
|
||||
## Custom whitelabeling
|
||||
|
||||
Ensure you select a unique app name that helps users distinguish your version from others, such as "\<Your Company Name\> Collaboration". See our [Brand and Visual Design Guidelines](https://handbook.mattermost.com/operations/operations/company-processes/publishing/publishing-guidelines/brand-and-visual-design-guidelines#name-usage-guidelines.html) in our company Handbook for details.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: "Host your own push proxy service"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Customers building their own custom mobile apps must host their own push proxy service using one of the following methods:
|
||||
|
||||
- Compile your own MPNS from the [open source repository](https://github.com/mattermost/mattermost-push-proxy).
|
||||
- Use the [pre-compiled version of MPNS available on GitHub](https://github.com/mattermost/mattermost-push-proxy/releases).
|
||||
|
||||
See our [developer documentation](https://developers.mattermost.com/contribute/mobile/push-notifications/service/) on working with the Mattermost Push Notification Service.
|
||||
|
||||
## Enable MPNS
|
||||
|
||||
1. Go to **System Console \> Environment \> Push Notification Server**.
|
||||
2. Under **Enable Push Notifications**, select **Manually enter Push Notification Service location**.
|
||||
3. Enter the location of your MPNS in the **Push Notification Server** field, then select **Save**.
|
||||
|
||||
**Deployment recommendations:**
|
||||
|
||||
- Deploy the MPNS on your own infrastructure - whether on-premises behind your firewall or in your public cloud.
|
||||
- Ensure the Mattermost server has network access to the MPNS instance. Mattermost clients don't need any inbound connectivity.
|
||||
- The MPNS does not connect with Mattermost mobile apps directly; the MPNS parses and forwards push notifications from the Mattermost server to the Apple Push Notification Service (APNS) or the Firebase Cloud Messaging (FCM).
|
||||
- The MPNS must be able to communicate with the Apple Push Notification Service over HTTP/2. If an outbound proxy appliance is deployed between the MPNS and APNS, ensure it supports HTTP/2.
|
||||
- Configure TLS encryption between your MPNS and your Mattermost server.
|
||||
- Sign the mobile applications during your build process, and obtain and configure valid push certificates for both Android and iOS. Without these certificates, the apps will be unable to send or receive notifications via your MPNS instance.
|
||||
- Subscribe to [Mattermost Security Bulletins](https://mattermost.com/security-updates/#sign-up) to receive and promptly apply MPNS-related security updates.
|
||||
|
||||
## Configure ID-only push notification contents (Enterprise)
|
||||
|
||||
By default, push notification message content passes through Apple Push Notification Service (APNS) or Google Firebase Cloud Messaging (FCM) before it reaches a device. This potentially presents a problem for organizations with ultra-strict security and compliance requirements.
|
||||
|
||||
With the ID-only option, message contents can be fetched directly from the server once a push notification is delivered to a device. APNS and FCM can’t read push notifications since only a unique message ID is sent in each notification payload. While message content will take slightly longer to send, this feature helps organizations meet advanced compliance requirements.
|
||||
|
||||
To set mobile push notification contents to ID-only:
|
||||
|
||||
1. Go to **System Console \> Site Configuration \> Notifications**.
|
||||
2. Under **Push Notification Contents**, select **Full message content fetched from the server on receipt**, then select **Save**.
|
||||
- As part of the process of building the applications, you'll need to sign the applications. You must also obtain the appropriate certificate for both Android and iOS. If this isn't done, the applications won't be able to interact with your instance of the MPNS. Once this is complete, you can proceed with the deployment of your MPNS instance.
|
||||
- We strongly recommend that you subscribe to [Mattermost Security Bulletins](https://mattermost.com/security-updates/#sign-up). When you're notified of security updates for the MPNS, apply them promptly.
|
||||
32
docs/main/deployment-guide/mobile/mobile-app-deployment.mdx
Normal file
32
docs/main/deployment-guide/mobile/mobile-app-deployment.mdx
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: "Mobile App Deployment"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
The Mattermost mobile app is available for iPhone and Android devices, and provides a native experience on the go, ensuring you can stay connected and productive from anywhere.
|
||||
|
||||
Learn more about [mobile app software requirements](/deployment-guide/software-hardware-requirements#mobile-apps), [available releases and server compatibility](/product-overview/mattermost-mobile-releases), [what's changed across releases](/product-overview/mobile-app-changelog), and [commonly asked questions](/deployment-guide/mobile/mobile-faq).
|
||||
|
||||
<Note>
|
||||
|
||||
Hitting problems with an installation or rollout? See [Mobile deployment troubleshooting](/deployment-guide/mobile/mobile-troubleshooting) at the end of this section, or [Deployment troubleshooting](/deployment-guide/server/troubleshooting) if the problem might not be specific to the mobile apps.
|
||||
|
||||
</Note>
|
||||
|
||||
## Download
|
||||
|
||||
Download and install the Mattermost mobile app from the [Apple App Store (iOS)](https://www.apple.com/app-store/) or [Google Play Store (Android)](https://play.google.com/store/games?hl=en). When new mobile app releases become available, your mobile app is automatically updated.
|
||||
|
||||
If you prefer to manage distribution of the mobile app to your users, we recommend using an [EMM provider](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider) to maintain full control over the distribution process, as well as enforce or restrict specific security policies. See the deployment options below for details.
|
||||
|
||||
## Deployment options
|
||||
|
||||
Learn what’s required to build and deploy Mattermost mobile apps.
|
||||
|
||||
- [Configure Microsoft Intune MAM for Mattermost](/deployment-guide/mobile/configure-microsoft-intune-mam)
|
||||
- [Distribute custom mobile apps](/deployment-guide/mobile/distribute-custom-mobile-apps)
|
||||
- [Host your own push proxy service](/deployment-guide/mobile/host-your-own-push-proxy-service)
|
||||
- [Mobile VPN options](/deployment-guide/mobile/consider-mobile-vpn-options)
|
||||
- [Mobile security features](/deployment-guide/mobile/mobile-security-features)
|
||||
- [Secure mobile file storage](/deployment-guide/mobile/secure-mobile-file-storage)
|
||||
- [Mobile apps FAQ](/deployment-guide/mobile/mobile-faq)
|
||||
368
docs/main/deployment-guide/mobile/mobile-faq.mdx
Normal file
368
docs/main/deployment-guide/mobile/mobile-faq.mdx
Normal file
@@ -0,0 +1,368 @@
|
||||
---
|
||||
title: "Mobile apps FAQ"
|
||||
---
|
||||
## Can I connect to multiple Mattermost servers using the mobile apps?
|
||||
|
||||
Yes, using Mattermost mobile app v2.0. Mobile v1.x only supports connecting to one server at a time.
|
||||
|
||||
## What data is stored?
|
||||
|
||||
The data that can be found on the device depends solely on whether or not the user is logged in to the Mattermost server, and is independent of the state of the device's connection or the state of the app. While logged in, anything that the user is normally allowed to see is eligible for storage on the device, which includes the following content:
|
||||
|
||||
- Messages
|
||||
- Files and images that are attached to messages
|
||||
- Profile pictures, usernames, and email addresses of people in the currently open channel
|
||||
|
||||
In addition, metadata that the app uses for keeping track of its operations is also cached. The metadata includes user IDs, channel IDs, team IDs, and message IDs.
|
||||
|
||||
Currently, cache cannot be reset remotely on connected mobile devices.
|
||||
|
||||
### What about push notifications?
|
||||
|
||||
Push notification storage is managed by the operating system on the device. Mattermost can be configured to send limited amounts of information that does not include the message text or channel name, and it can also be configured to not send push notifications at all.
|
||||
|
||||
## Where is the data stored and how is that data protected?
|
||||
|
||||
The data is stored in the app's local storage. It's protected by the security measures that a device normally provides to the apps that are installed on it.
|
||||
|
||||
## How long is the data stored?
|
||||
|
||||
Data is stored until the user logs out, or until it is purged during normal cache management. Deactivating a user account forces a logout and subsequent purging of data from the device.
|
||||
|
||||
## How is data handled after a user account is deactivated?
|
||||
|
||||
App data is wiped from the device when a user logs out of the app. If the user is logged in when the account is deactivated, then within one minute of deactivation the system logs the user out. Thereafter all app data is wiped from the device.
|
||||
|
||||
If file attachments are enabled on the server, users can download files that are attached to messages and store them on their local file system. After they are downloaded, the files are outside the control of the app and can remain on the device indefinitely.
|
||||
|
||||
## Are messages pre-loaded?
|
||||
|
||||
No. Messages are sent to the device on demand. They are not pre-loaded in anticipation of users scrolling up or switching channels.
|
||||
|
||||
## Do I need to compile the mobile apps to host my own push notification server?
|
||||
|
||||
Yes. To host your own push notification server, you'll need to compile the mobile apps. See [documentation](/deployment-guide/mobile/distribute-custom-mobile-apps) to learn how to compile your own mobile apps.
|
||||
|
||||
## How do push notifications work?
|
||||
|
||||
Your Mattermost server sends push notifications to a hosted push proxy server, which relays them via mobile push notification services provided by Apple and Google.
|
||||
|
||||
To ensure push notifications are coming from a trusted source, Apple and Google only allow push notifications sent from a service using a key or signature corresponding to a secret compiled into the mobile app itself.
|
||||
|
||||
The full process is outlined below:
|
||||
|
||||
1. An action triggering a push notification is detected in the Mattermost server running in your private network.
|
||||
2. Your Mattermost server sends a push notification message to a Mattermost Push Notification Service (MPNS), either self-hosted in your private network, or publicly hosted by Mattermost, Inc.
|
||||
3. MPNS sends a push notification message to either Apple Push Notification Service (APNS) or to Google’s Firebase Cloud Messaging (FCM) service over a TLS connection.
|
||||
|
||||
> - If sent to Apple, the message has a signature corresponding to a secret compiled in the iOS app.
|
||||
> - If sent to Google, the message uses a key corresponding to a secret compiled in the Android app.
|
||||
|
||||
Regardless of whether you're using iOS or Android, the MPNS needs to have access to the appropriate secret compiled into the mobile app.
|
||||
|
||||
This means if you use the Mattermost apps from the [Apple App Store](https://www.apple.com/app-store/) or [Google Play Store](https://play.google.com/store/games?hl=en), you need to use the hosted push notification service from Mattermost, Inc. If you compile the apps yourself, you must also compile and use your own MPNS with the corresponding secret.
|
||||
|
||||
4. Either APNS or FCM receives the push notification message from MPNS over TLS, and then relays the message to the user's iOS or Android device to be displayed.
|
||||
|
||||
<Note>
|
||||
|
||||
The use of push notifications with iOS and Android applications will require a moment where the contents of push notifications are visible and unencrypted by a server controlled by either Apple or Google. This is standard for any iOS or Android app. For this reason, there is an option available in Mattermost Enterprise to omit the contents of Mattermost messages from push notifications, or to configure message contents to be fetched from the server when notifications reach the device. See our [Configuration Settings](/administration-guide/configure/site-configuration-settings#push-notification-contents) documentation for details.
|
||||
|
||||
</Note>
|
||||
|
||||
## Is TLS v1.3 supported?
|
||||
|
||||
Yes. Mattermost mobile app v2.0 supports both TLS v1.2 and TLS v1.3 for websocket connections.
|
||||
|
||||
## What post metadata is sent in mobile push notifications?
|
||||
|
||||
The following post metadata is sent in all push notifications:
|
||||
|
||||
- `Team ID`
|
||||
- `Channel ID`
|
||||
- `Post ID`
|
||||
- `User ID` (post author)
|
||||
- `Username` (post author or webhook override username)
|
||||
- `Root ID` (only if the post is in a thread)
|
||||
- `Type` (create or clear push notification)
|
||||
- `Category` (iOS only, determines if the notifications can be replied to)
|
||||
- `Badge number` (what the notification badge on the app icon should be set to when the notification is received)
|
||||
|
||||
Additional metadata may be sent depending on the System Console setting for [Push Notification Contents](/administration-guide/configure/site-configuration-settings#push-notification-contents):
|
||||
|
||||
- **Generic description with sender and channel names**: `Channel name` metadata will be included.
|
||||
- **Full message content sent in the notification payload**: `Post content` and `Channel name` metadata will be included.
|
||||
- **Full message content fetched from the server on receipt** (available in Mattermost Enterprise): `Post content` and `Channel name` are not included in the notification payload, instead the `Post ID` is used to fetch `Post content` and `Channel name` from the server after the push notification is received on the device.
|
||||
|
||||
## How can I use ID-Only Push Notifications to protect notification content from being exposed to third-party services?
|
||||
|
||||
When it comes to mobile data privacy, many organizations prioritize secure handling of messaging data, particularly when it may contain mission-critical or proprietary information. These organizations may have concerns about using mobile notifications because data must pass through third-party entities like Apple Push Notification Service (APNS) or Google Firebase Cloud Messaging (FCM) before it reaches a device.
|
||||
|
||||
This poses a potential risk for organizations that operate under strict compliance requirements and cannot expose message data to external entities. To solve this, we offer an option for greater protection for Mattermost push notification message data by only sending a unique message ID in the notification payload rather than the full message data (available in Mattermost Enterprise). Once the device receives the ID, it then fetches the message content directly from the server and displays the notification per usual.
|
||||
|
||||
External entities, such as APNS and FCM, handle only the ID and are unable to read any part of the message itself. If your organization has strict privacy or compliance needs, the [ID-Only Push Notification](/administration-guide/configure/site-configuration-settings#push-notification-contents) setting offers a high level of privacy while still allowing your team members to benefit from mobile push notifications.
|
||||
|
||||
The following payload shows an example of the json that is transmitted to the push notification service when using the ID-Only setting:
|
||||
|
||||
> ``` json
|
||||
> {
|
||||
> "ack_id": "nnfbqk5bnffe5karxuzs8o5rec",
|
||||
> "platform": "apple_rn",
|
||||
> "server_id": "aoej8izzfffr9e67d6uz3g387h",
|
||||
> "device_id": "32f198dbdd7427be7e6f03ba721ffdceba58c3f0bfa9c4655a6e7cc8271ba539",
|
||||
> "post_id": "77d9cs9aq3b1fpoepbdbmqfs4c",
|
||||
> "category": "CAN_REPLY",
|
||||
> "message": "You've received a new message.",
|
||||
> "badge": 3,
|
||||
> "channel_id": "et3ghiycm7g7bb41ihg85pqgah",
|
||||
> "type": "message",
|
||||
> "sender_id": "g774dzud4tgaxgphso4wm8xrxe",
|
||||
> "version": "v2",
|
||||
> "is_id_loaded": true
|
||||
> }
|
||||
> ```
|
||||
|
||||
where the following definitions are applied:
|
||||
|
||||
- `ack_id`: An ephemeral identifier generated per notification that determines whether the notification sent was received by the device (using same method that generates identifiers to the rest of the models in the server). This information is available in the `notifications.log` file on the Mattermost server. The `ack_id` is only used for receipt delivery from the mobile app to the Mattermost server to confirm whether the notification sent was received.
|
||||
- `server_id`: A server identifier created on the server, called `DiagnosticId`. In the future, this value will be used in the mobile app (for multi-server support) to identify which server the notification belongs to.
|
||||
- `device_id`: The token that APNs and FCM return when you allow the device to receive notifications. So when the user logs into Mattermost, Mattermost sends this `device_id` to attach it to the session. If the session is terminated, the `device_id` is no longer present in the server database because the session record is removed. When the user logs back in, the `device_id` is registered again with the same value because the identifier is specific to the device. This value won't be the same across apps or devices owned by the same person, but will be the same for each session the user creates from the same app on the same device.
|
||||
- `version`: Tells the mobile app how data is structured so it can parse it properly. Current value is `v2`.
|
||||
- `is_id_loaded`: (Mattermost Enterprise only) When true, the mobile app look for the contents of the notification on the server because those details are not part of the payload.
|
||||
|
||||
## What are my options for securing the mobile apps?
|
||||
|
||||
The following options for secure mobile app deployments are available:
|
||||
|
||||
1. Securing network connection to mobile apps
|
||||
|
||||
> - Use HTTPS and WSS network connections to encrypt transport.
|
||||
> - Use of a mobile VPN client on mobile devices to establish secure connection to Mattermost server within private network.
|
||||
|
||||
2. Use multifactor authentication options
|
||||
|
||||
> - If a VPN client with multifactor authentication is not in use, it's highly recommended that MFA is required on authenticating into Mattermost, either within Mattermost itself or via your SSO provider.
|
||||
|
||||
## What are my options for securing push notifications?
|
||||
|
||||
The following options are available for securing your push notification service:
|
||||
|
||||
1. Protecting notification contents
|
||||
|
||||
> - You can [choose what type of information to include in push notifications](/administration-guide/configure/site-configuration-settings#push-notification-contents), such as excluding the message contents if your compliance policies require it. Default server settings have message contents turned off.
|
||||
|
||||
2. Disabling push notifications
|
||||
|
||||
> - Push notifications can also be disabled entirely depending on security requirements. Default server settings have push notifications disabled.
|
||||
|
||||
3. Encrypting connections for apps you compile yourself:
|
||||
|
||||
> - When using a privately-hosted Mattermost Push Notification Service (MPNS), use encrypted TLS connections between:
|
||||
> - MNPS and Apple Push Notification Service (APNS)
|
||||
> - MPNS and Google’s Firebase Cloud Messaging (FCM)
|
||||
> - MPNS and your Mattermost server
|
||||
|
||||
4. Securing apps installed through the Apple App Store and Google Play:
|
||||
|
||||
> - When using Mattermost mobile apps from the App Store and Google Play, purchase an annual subscription to Mattermost Enterprise or Professional to use Mattermost's [Hosted Push Notification Service (HPNS)](/administration-guide/configure/environment-configuration-settings#enable-push-notifications).
|
||||
|
||||
<Note>
|
||||
|
||||
For configuration details, see guides for [deploying the Mattermost mobile app](/deployment-guide/mobile/mobile-app-deployment) and [deploying your own version of the apps](/deployment-guide/mobile/distribute-custom-mobile-apps).
|
||||
|
||||
</Note>
|
||||
|
||||
## Why do I sometimes see a delay in receiving a push notification?
|
||||
|
||||
[Apple Push Notification Service (APNS)](https://developer.apple.com/documentation/usernotifications) and [Google Fire Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) determine when your device receives a push notification from Mattermost. Thus, a delay is usually as a result of those services.
|
||||
|
||||
The technical flow for the device to receive a push notification is as follows:
|
||||
|
||||
1. User posts a message in Mattermost.
|
||||
2. Mattermost server identifies if notifications need to be sent.
|
||||
3. If yes, Mattermost server sends a payload containing the push notification to the push proxy.
|
||||
4. The push proxy parses the notification and relays it to APNS and FCM.
|
||||
5. APNS and FCM informs the relevant devices that there is a push notification for Mattermost. This usually happens almost immediately, but may be delayed by a couple of minutes.
|
||||
6. Mattermost processes the notification and displays it on the user's device.
|
||||
|
||||
## How do I deploy Mattermost with Enterprise Mobility Management (EMM) providers?
|
||||
|
||||
Mattermost enables customers with high privacy and custom security requirements to deploy mobile app and push notification services using keys that they alone control.
|
||||
|
||||
[Learn more about using AppConfig for EMM providers](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider).
|
||||
|
||||
## How do I host the Mattermost push notification service?
|
||||
|
||||
First, you can use the [Mattermost Hosted Push Notification Service (HPNS)](/administration-guide/configure/environment-configuration-settings#enable-push-notifications). Organizations can also [host their own push proxy server](/deployment-guide/mobile/host-your-own-push-proxy-service) instead. This is applicable when you want to:
|
||||
|
||||
1. Customize the Mattermost mobile apps;
|
||||
2. Deploy your own push notification service, or
|
||||
3. Repackage the mobile apps with BlueCedar or AppDome (both of which are not officially supported but have been successfully deployed by some organizations).
|
||||
|
||||
## How do I white label the app and customize build settings?
|
||||
|
||||
All files in the `/assets/base` folder can be overridden as needed without conflicting with changes made to the upstream version of the app. To do this:
|
||||
|
||||
1. Create the folder `/assets/override`.
|
||||
2. Copy any files or folders that you wish to replace from `/assets/base` into `/assets/override`.
|
||||
3. Make your changes to the files in `/assets/override`.
|
||||
|
||||
When you compile the app or run `make dist/assets`, the contents of those two folders will be merged with files in `/assets/override`, taking precedence in the case of any conflicts. For binary files such as images, an overridden file will completely replace the base version, while `JSON` files will be merged so that fields not set in the overridden copy use the base version.
|
||||
|
||||
For a more specific example of how to use this feature, see the following section.
|
||||
|
||||
## How do I preconfigure the server URL for my users?
|
||||
|
||||
You can preconfigure the server URL and other settings by overriding default `config.json` settings and building the mobile apps yourself.
|
||||
|
||||
1. Fork the [mattermost-mobile repository](https://github.com/mattermost/mattermost-mobile).
|
||||
2. Create the file `/assets/override/config.json` in your forked mattermost-mobile repository.
|
||||
3. Copy and paste all the settings from `assets/base/config.json` to the newly-created `/assets/override/config.json` file that you want to override.
|
||||
4. To override the server URL, set `DefaultServerURL` to the server URL of your Mattermost server in `/assets/override/config.json`.
|
||||
5. (Optional) If you want to prevent users from changing the server URL, set `AutoSelectServerUrl` to `true`.
|
||||
6. (Optional) Override any other settings you like.
|
||||
|
||||
After the above, your `/assets/override/config.json` file would look something like this:
|
||||
|
||||
> ``` json
|
||||
> {
|
||||
> "DefaultServerURL": "my-mattermost-instance.example.com",
|
||||
> "AutoSelectServerUrl": true,
|
||||
> "ExperimentalUsernamePressIsMention": true
|
||||
> }
|
||||
> ```
|
||||
|
||||
7. Finally, [compile your own version](https://developers.mattermost.com/contribute/mobile/build-your-own/) of the Mattermost mobile app and Mattermost push proxy server.
|
||||
|
||||
## How can I get Google SSO to work with the Mattermost mobile app?
|
||||
|
||||
The apps on the Apple App Store and Google Play Store cannot support Google SSO out of the box. This is because Google requires a unique Google API key that's specific to each organization.
|
||||
|
||||
If you need Google SSO support, you can create a custom version of the app for your own organization. Fork the [mattermost-mobile](https://github.com/mattermost/mattermost-mobile) repository and add support for Google SSO before compiling the app yourself. If this is something you’re interested in, please [file an issue in GitHub](https://github.com/mattermost/mattermost-mobile/issues) to start the discussion.
|
||||
|
||||
## How do I configure deep linking?
|
||||
|
||||
The app checks for platform-specific configuration on app install. If no configuration is found, then the deep linking code sits silently and permalinks act as regular links.
|
||||
|
||||
**Set up for iOS**
|
||||
|
||||
1. Create an `apple-app-site-association` file in the `.well-known` directory at the root of your server. It should be accessible by navigating to `https://<your-site-name>/.well-known/apple-app-site-association`. There should not be a file extension.
|
||||
2. In order to handle deep links, paste the following `JSON` into the `apple-app-site-association` file. Make sure to place your app ID in the `appID` property:
|
||||
|
||||
{/* */}
|
||||
|
||||
{
|
||||
"applinks": {
|
||||
"apps": [],
|
||||
"details": [
|
||||
{
|
||||
"appID": "<your-app-id-here>",
|
||||
"paths": ["**/pl/*", "**/channels/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
3. Add the associated domains entitlement to your app via the Apple developer portal.
|
||||
4. Add an entitlement that specifies the domains your app supports via the Xcode entitlements manager.
|
||||
5. Before installing the app with the new entitlement, make sure that you can view the contents of the `apple-app-site-association` file via a browser by navigating to `https://<your-site-name>/.well-known/apple-app-site-association`. The app will check for this file on install and, if found, will allow outside permalinks to open the app.
|
||||
|
||||
Official documentation for configuring deep linking on iOS can be found [here](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html).
|
||||
|
||||
**Set up for Android**
|
||||
|
||||
Please refer to the the App Links Assistant in Android Studio for configuring [deep linking on Android](https://developer.android.com/studio/write/app-link-indexing).
|
||||
|
||||
## How do I connect users across internal and external networks?
|
||||
|
||||
By setting up global network traffic management, you can send a user to an internal or external network when connecting with a mobile app. Moreover, you can have two separate layers of restrictions on internal and external traffic, such as:
|
||||
|
||||
> - In the internal network, deploy on a private network via per device VPN.
|
||||
> - In the external network, deploy with [TLS mutual auth](/administration-guide/onboard/ssl-client-certificate) with an NGINX proxy, and [client-side certificates](/administration-guide/onboard/certificate-based-authentication) for desktop and iOS.
|
||||
|
||||
Many services such as Microsoft Azure provide options for [managing network traffic](https://learn.microsoft.com/en-us/azure/traffic-manager/traffic-manager-overview), or you can engage a services partner to assist.
|
||||
|
||||
## How do I receive mobile push notifications if my IT policy requires the use of a corporate proxy server?
|
||||
|
||||
When your IT policy requires a corporate proxy to scan and audit all outbound traffic the following options are available:
|
||||
|
||||
### Deploy Mattermost in a proxy-aware configuration with a pre-proxy relay
|
||||
|
||||
The Mattermost push notification service is designed to send traffic directly to the [Apple Push Notification Service (APNS)](https://developer.apple.com/documentation/usernotifications) and [Google Fire Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) services.
|
||||
|
||||
In a proxy-aware configuration, a pre-proxy relay accepts messages from the [Mattermost Push Proxy](https://developers.mattermost.com/contribute/mobile/push-notifications/service/) and forwards them to a corporate proxy enforcing your internal IT requirements, before transmitting to their final destination.
|
||||
|
||||
See a sample architectural overview below:
|
||||
|
||||

|
||||
|
||||
This enables the **pre-proxy relay** to act as the APNS and to forward the request to its final destination via your corporate proxy, not requiring the APNS traffic to be proxy-aware. The APNS traffic is redirected to the pre-proxy relay via `/etc/hosts` entry. The entry uses a trusted CA that signs a certificate for the Mattermost Push Proxy to trust the pre-proxy relay. See the Apple Developer documentation on [user notifications](https://developer.apple.com/documentation/usernotifications) for more information.
|
||||
|
||||
Google's [FCM traffic](https://firebase.google.com/docs/cloud-messaging) is proxy-aware via environment variables, so no actions are required for it.
|
||||
|
||||
Moreover, APNS traffic requires HTTP/2, so your corporate proxy server must support HTTP/2 requests in order to send the push notifications to Apple devices. HTTP/2 support for the pre-proxy relay is also required.
|
||||
|
||||
### Deploy Mattermost with connection restricted post-proxy relay in DMZ or a trusted cloud environment
|
||||
|
||||
Some legacy corporate proxy configurations may be incompatible with the requirements of modern mobile architectures, such as the requirement of HTTP/2 requests from Apple to send push notifications to iOS devices.
|
||||
|
||||
In this case, a post-proxy relay can be deployed to take messages from the Mattermost server passing through your corporate IT proxy in the incompatible format, e.g. HTTP/1.1, transform it to HTTP/2 and relay it to its final destination, either to the [Apple Push Notification Service (APNS)](https://developer.apple.com/documentation/usernotifications) and [Google Fire Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) services.
|
||||
|
||||
Ths **post-proxy relay** [can be configured using the Mattermost Push Proxy installation guide](https://developers.mattermost.com/contribute/mobile/push-notifications/service/) with connection restrictions to meet your custom security and compliance requirements.
|
||||
|
||||
In place of a DMZ, you can also host in a trusted cloud environment such as AWS or Azure depending on your internal approvals and policies.
|
||||
|
||||

|
||||
|
||||
### Whitelist Mattermost push notification proxy to bypass your corporate proxy server
|
||||
|
||||
Depending on your internal IT policy and approved waivers/exceptions, you may choose to deploy the [Mattermost Push Proxy](https://developers.mattermost.com/contribute/mobile/push-notifications/service/) to connect directly to [Apple Push Notification Service (APNS)](https://developer.apple.com/documentation/usernotifications) without your corporate proxy.
|
||||
|
||||
You will need to [whitelist one subdomain and one port from Apple](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW1) for this option:
|
||||
|
||||
- Development server: `api.development.push.apple.com:443`
|
||||
- Production server: `api.push.apple.com:443`
|
||||
|
||||
### Run App Store versions of the Mattermost mobile apps
|
||||
|
||||
You can use the mobile applications hosted by Mattermost in the [Apple App Store](https://apps.apple.com/ca/app/mattermost/id1257222717) or [Google Play Store](https://play.google.com/store/apps/details?id=com.mattermost.rn) and connect with the [Mattermost Hosted Push Notification Service (HPNS)](/administration-guide/configure/push-notification-server-configuration-settings#hosted-push-notifications-service-hpns) through your corporate proxy.
|
||||
|
||||
<Note>
|
||||
|
||||
The use of hosted applications by Mattermost [can be deployed with Enterprise Mobility Management solutions via AppConfig](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider) but wrapping is not supported. See the [product documentation](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider#manage-app-configuration-using-appconfig) for details.
|
||||
|
||||
</Note>
|
||||
|
||||
### How the `deviceId` behaves
|
||||
|
||||
The `deviceId` is a identifier provided by a push notification service, such as Apple Push Notification service (APNs) and Firebase Cloud Messaging (FCM), that identifies the relationship between device, app, and the notification service.
|
||||
|
||||
When the app starts, if the push notification permissions are enabled, the app will try to connect with the corresponding notification service (APNs for iOS, FCM for Android) to get the `deviceId`. If there is any change to the `deviceId`, the app will notify any connected server about this change.
|
||||
|
||||
Based on the [Apple Developer Documentation on registering apps with APNS](https://developer.apple.com/documentation/usernotifications/registering-your-app-with-apns?changes=_8) and the [Google Documentation on FCM](https://firebase.google.com/docs/cloud-messaging/android/client#java_1), the `deviceId` only will change in the following cases:
|
||||
|
||||
- The app is restored from a backup from a different device
|
||||
- The user clears the app data
|
||||
- The user reinstalled the app
|
||||
- The user installed the app on a different device
|
||||
|
||||
If the device has a `deviceId`, when the user logs into a Mattermost server, an audit log entry `login` will store the `deviceId`, and the `deviceId` will also be added in the session data in the database. However, it's possible the `deviceId` isn't available, due to several reasons including:
|
||||
|
||||
- The device is not connected to the network
|
||||
- The notification service is not reachable for any reason
|
||||
- The app is not properly signed
|
||||
- The device has not been granted the needed permissions
|
||||
|
||||
In these scenarios, the `login` audit log won't have the `deviceId`, and the session data won't have the `deviceId`. If the app receives the `deviceId` later, the device will send the new `deviceId` to the server, generating an `attachDeviceId` audit log, and adding the `deviceId` to the session data in the database.
|
||||
|
||||
Since the `deviceId` relates to the application, connections through the web browser, even on mobile, won't have a `deviceID`.
|
||||
|
||||
## Where can I find mobile message notification logs?
|
||||
|
||||
Notification messages are logged to the `notifications.log` file. System admins must enable notification logs in the `config.json` file by setting `EnableFile` to `true`, and specifying an optional file location via `FileLocation`. When no location is configured, the `notifications.log` file is stored in the default Mattermost directory. See the [logging configuration settings](/administration-guide/configure/environment-configuration-settings#logging) documentation for details.
|
||||
|
||||
The team members / users can access their notification logs based on their device platform. Android users can view the logs using `logcat`. iOS users can acess the logs in the `console app` on their MacOS.
|
||||
|
||||
## How do I gather mobile app logs?
|
||||
|
||||
See the Mattermost Support Knowledge Base article on [gathering mobile app logs](https://support.mattermost.com/hc/en-us/articles/30147601934100-How-to-Gather-Mobile-App-Logs) for details.
|
||||
162
docs/main/deployment-guide/mobile/mobile-security-features.mdx
Normal file
162
docs/main/deployment-guide/mobile/mobile-security-features.mdx
Normal file
@@ -0,0 +1,162 @@
|
||||
---
|
||||
title: "Mobile security features"
|
||||
---
|
||||
<PlanAvailability slug="ent-adv" />
|
||||
|
||||
This document outlines the key security features implemented in the mobile application, explains the significance of each control, and details our continuous security practices to maintain an up-to-date security posture.
|
||||
|
||||
## Jailbreak and root detection
|
||||
|
||||
Mattermost leverages built-in checks from the Expo framework to identify jailbroken (iOS) and rooted (Android) devices:
|
||||
|
||||
- On **Android**, the app looks for the presence of known jailbreak/root binaries, such as the `su` binary in `/system/xbin/su`, which is a common indicator that the device has been rooted to allow unauthorized elevated access.
|
||||
- On **iOS**, the detection process involves checking for unusual apps (e.g., Cydia), modified system paths, and testing whether the app can alter protected system files—all signs that the device may be jailbroken.
|
||||
|
||||
See the [jailbreak/root protection configuration setting](/administration-guide/configure/environment-configuration-settings#enable-jailbreakroot-protection) documentation for details on enabling this feature.
|
||||
|
||||
<Note>
|
||||
|
||||
Client-side detection methods are not bulletproof and can be bypassed by a sufficiently motivated user with root or jailbreak access. Determined users can employ reverse engineering to disable or modify these checks to produce false positives/negatives or even modify and recompile the source code to remove them entirely, allowing app usage on rooted/jailbroken devices.
|
||||
|
||||
</Note>
|
||||
|
||||
## Biometric authentication
|
||||
|
||||
Mattermost integrates with iOS Face ID/Touch ID and Android’s Biometric API. When enabled by the server administrator, biometric checks are required before accessing specific servers, and the Mattermost mobile app mandates that a device PIN or biometric lock is active.
|
||||
|
||||
See the [biometric authentication configuration setting](/administration-guide/configure/environment-configuration-settings#enable-biometric-authentication) documentation for details on enabling this feature and the user workflows in which users must authenticate.
|
||||
|
||||
<Note>
|
||||
|
||||
Biometric authentication, such as Face ID or fingerprint recognition, is handled by the device’s operating system. Mattermost does not provide or warrant the biometric functionality. The app will unlock if the OS determines that the biometric input is a positive match. Accuracy, security, and availability of biometric authentication depend entirely on the device and its underlying platform.
|
||||
|
||||
</Note>
|
||||
|
||||
## Screenshot and screen recording prevention
|
||||
|
||||
Preventing screenshots and screen recordings protects sensitive information from being inadvertently or maliciously shared. This control is essential in ensuring that confidential communications and data remain within the secure confines of the app. By blocking unauthorized screen captures, Mattermost significantly reduces the risk of data leakage via visual content.
|
||||
|
||||
- On **iOS**, the app detects attempts to capture the screen. For screen recordings, it immediately applies a blur overlay to the view to obscure any sensitive information, while screenshots will capture no content at all.
|
||||
- On **Android**, the app utilizes the FLAG_SECURE flag to block screen captures and recordings.
|
||||
|
||||
See the [prevent screen capture configuration setting](/administration-guide/configure/environment-configuration-settings#prevent-screen-capture) documentation for details on enabling this feature.
|
||||
|
||||
<Note>
|
||||
|
||||
This feature prevents screen recording and screenshot capture on the mobile device where the Mattermost app is running. It cannot control or prevent recording from external devices, such as another phone or camera pointed at the screen. Mattermost provides these protections through mobile OS-level capabilities but cannot guarantee absolute prevention of visual data capture through other means.
|
||||
|
||||
</Note>
|
||||
|
||||
## Secure file previews
|
||||
|
||||
Preventing file downloads protects sensitive information from being inadvertently or maliciously shared. This control is essential in ensuring that confidential documents and media remain within the secure confines of the app. By enabling in-app previews for supported file types and restricting downloads, Mattermost significantly reduces the risk of data leakage while maintaining essential file-viewing capabilities.
|
||||
|
||||
See the [secure file preview](/administration-guide/configure/environment-configuration-settings#enable-secure-file-preview-on-mobile) and [managing PDF link navigation](/administration-guide/configure/environment-configuration-settings#allow-pdf-link-navigation-on-mobile) configuration settings documentation for details on enabling these features.
|
||||
|
||||
## Mobile watermarking
|
||||
|
||||
Mobile watermarking is an experimental Enterprise Advanced capability 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 [Enable Mobile Watermark](/administration-guide/configure/experimental-configuration-settings#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 [screenshot and screen recording prevention](#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.
|
||||
|
||||
</Note>
|
||||
|
||||
## Microsoft Intune Mobile Application Management (MAM)
|
||||
|
||||
Mattermost supports Microsoft Intune MAM to enforce identity-based, app-level data protection on iOS devices without requiring full device enrollment in a mobile device management (MDM) solution.
|
||||
|
||||
<Important>
|
||||
|
||||
Microsoft Intune MAM enforcement for Mattermost is currently supported on **iOS** only. We recommend using Android for Work profiles until Android Intune support is available.
|
||||
|
||||
</Important>
|
||||
|
||||
Intune MAM applies security policies directly to the Mattermost mobile app using Microsoft Entra ID as the identity authority. This enables organizations to protect corporate or mission-sensitive data on Bring Your Own Device (BYOD) and mixed-use devices while preserving user privacy.
|
||||
|
||||
Key security capabilities enabled through Intune MAM include:
|
||||
|
||||
- **Mandatory enrollment** before accessing Mattermost on mobile
|
||||
- **Identity-based enforcement** using Microsoft Entra ID
|
||||
- **Selective wipe** of Mattermost work data without affecting personal apps or device data
|
||||
- **Clipboard, file sharing, and data transfer restrictions**
|
||||
- **Screenshot and screen recording prevention**
|
||||
- **Managed browser enforcement** and controlled link handling
|
||||
- **Immediate enforcement** when policies or licensing change, including during active sessions
|
||||
|
||||
Intune MAM enforcement is applied **per Mattermost workspace** and evaluated continuously at runtime. If a device becomes non-compliant, enrollment fails, or required policies are not met, access to protected content is blocked automatically.
|
||||
|
||||
This approach allows organizations to extend zero-trust and data loss prevention (DLP) controls to mobile users without assuming ownership or management of the underlying device.
|
||||
|
||||
See the [Microsoft Intune MAM configuration guide](/deployment-guide/mobile/configure-microsoft-intune-mam) for deployment and configuration details.
|
||||
|
||||
## Mobile Ephemeral Mode
|
||||
|
||||
Mobile applications typically cache messages, files, and attachments on-device indefinitely. Two security concerns drive the need for administrator-controlled data lifecycle management on mobile devices:
|
||||
|
||||
- **Unbounded sensitive data accumulation.** Without data-age controls, weeks or months of sensitive content can accumulate on any device a user has logged into — well beyond what operational need justifies.
|
||||
- **Offline exposure after device loss.** Remotely wiping a device requires it to be reachable — the condition least likely to hold when a device is lost, stolen, or in an adversarial environment. Unmanaged or personally-owned devices may not be enrolled in MDM at all, leaving cached content with no remote deletion path.
|
||||
|
||||
Mobile Ephemeral Mode addresses both concerns by giving administrators direct, server-side control over how long data persists on mobile devices. The app enforces this policy locally — including while offline and across app and device restarts — so data is removed based on elapsed time, not device reachability.
|
||||
|
||||
Mobile Ephemeral Mode generates an [audit log](/administration-guide/manage/logging#audit-logging) event for each delete, purge, and wipe operation. Because these operations can execute on a device that is unreachable — where no administrator has direct visibility — audit logging provides verifiable proof that ephemeral policies were enforced. This supports compliance requirements for data lifecycle management and destruction accountability. Events that occur while the device is offline are reported to the server on reconnection.
|
||||
|
||||
See the [Mobile Ephemeral Mode configuration settings](/administration-guide/configure/environment-configuration-settings#mobile-ephemeral-mode) to configure these controls.
|
||||
|
||||
## Mobile data isolation
|
||||
|
||||
Mattermost mobile applications are designed to ensure that sensitive data is stored securely and isolated from other applications on the device. This isolation is achieved through a combination of OS-level security features, app sandboxing, and secure data storage practices.
|
||||
|
||||
Mattermost stores 3 types of data within the mobile app:
|
||||
|
||||
- **SQLite Database**: For offline access to posts and channels that the user has viewed.
|
||||
- **Cached Files**: For temporary storage (e.g., PDFs) of viewed files. They are periodically purged.
|
||||
- **Logs**: Minimal logs kept for troubleshooting purposes.
|
||||
|
||||
The Mattermost mobile app for Apple iOS and Android devices uses the native OS security architecture to encrypt data-at-rest on mobile devices, ensuring that stored information remains secure even if the device is lost or stolen. This encryption protects sensitive data, such as messages and files, from unauthorized access.
|
||||
|
||||
Data stored by the Mattermost mobile app only resides within the app’s private storage container. This storage location is isolated by each platform’s rigorous sandboxing model. Learn more about [secure file storage](/deployment-guide/mobile/secure-mobile-file-storage) for Mattermost mobile applications.
|
||||
|
||||
### Security measures
|
||||
|
||||
- **OS sandboxing & app access isolation**: Mattermost’s data is confined within its app-specific sandbox (see [Apple’s iOS sandboxing](https://support.apple.com/guide/security/security-of-runtime-process-sec15bfe098e/web) and [Android’s sandboxing](https://source.android.com/docs/security/app-sandbox) guidelines). This sandboxing mechanism ensures that all stored data—whether in the SQLite databases, cached files, or logs—is isolated and inaccessible to other applications. This is why TikTok, and any other application is blocked from accessing Mattermost data.
|
||||
- **iOS** employs a rigorous sandboxing model that relies on containerized file systems and strict process isolation. Each app operates within its own sandbox, with its home directory randomly assigned during installation. As a result, data stored within the Mattermost app’s sandbox directory remains accessible only to the app unless explicitly shared by the user.
|
||||
- **Android** employs scoped storage by assigning each app its own Linux user ID and a dedicated private directory. This model prevents other applications from accessing an app’s private directory without explicit permission. As a result, the Mattermost app’s data remain inaccessible to other apps—unless the device is rooted, or the user explicitly shares the data.
|
||||
- **Cache invalidation**: Cached files are periodically deleted.
|
||||
- **No Google or Apple Cloud backup**: Mattermost files are not backed up during normal cloud backup procedures.
|
||||
- On **Android**, the application explicitly disables backups (using the appropriate manifest settings), ensuring that all Mattermost files remain strictly on-device.
|
||||
- On **iOS**, although the operating system automatically backs up files stored in the app's `Documents` folder, Mattermost intentionally stores its files in the `Library/Caches` directory, which is excluded from iCloud backups.
|
||||
- **Controlled data export**: Data only leaves Mattermost through explicit user actions such as:
|
||||
- Manually exporting a file.
|
||||
- Takes a screenshot (if not blocked by policy or with a secondary camera).
|
||||
- Sharing content using OS features (e.g., share sheet).
|
||||
|
||||
<Note>
|
||||
|
||||
This feature restricts direct access to stored data through robust OS-level sandboxing and storage controls. However, it cannot prevent unauthorized extraction if attackers employ alternative methods. For instance, on jailbroken (iOS) or rooted (Android) devices, where system integrity is compromised, an attacker may bypass standard security measures.
|
||||
|
||||
Similarly, exploiting zero-day or known OS vulnerabilities—or malicious apps that exploit permission weaknesses—could grant access to device storage. Mattermost uses mobile OS-level safeguards but cannot guarantee absolute prevention of such unauthorized data access.
|
||||
|
||||
</Note>
|
||||
|
||||
## Security compliance
|
||||
|
||||
- **Secure SDLC**: The mobile app adheres to the same secure Software Development Lifecycle (SDLC) process as all Mattermost components. This guarantees that new mobile features undergo comprehensive security reviews and that any issues are addressed before release.
|
||||
- **Vulnerability management**: The Mattermost mobile app is included in Mattermost’s public bug bounty program, inviting security researchers to rigorously assess the application. Additionally, established remediation SLAs ensure that any security issues are resolved promptly.
|
||||
- **Continuous dependency scanning**: Mattermost uses Snyk Open Source to conduct daily scans of all dependencies. This continuous approach ensures that any newly disclosed vulnerabilities are quickly identified and addressed within defined SLAs.
|
||||
- **BESPIN compliance**: Mattermost adheres to strict security evaluations including:
|
||||
- Device Protection Profiles (NIAP Evaluation)
|
||||
- Security Dependency & Code Analysis
|
||||
- Code Complexity & Testing Standards
|
||||
153
docs/main/deployment-guide/mobile/mobile-troubleshooting.mdx
Normal file
153
docs/main/deployment-guide/mobile/mobile-troubleshooting.mdx
Normal file
@@ -0,0 +1,153 @@
|
||||
---
|
||||
title: "Mobile deployment troubleshooting"
|
||||
---
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
## I keep getting a message "Cannot connect to the server. Please check your server URL and internet connection."
|
||||
|
||||
First, confirm that your server URL has no typos and that it includes `http://` or `https://` according to the server deployment configuration.
|
||||
|
||||
If the server URL is correct, there could be an issue with the SSL certificate configuration.
|
||||
|
||||
To check your SSL certificate set up, test it by visiting a site such as [SSL Labs](https://www.ssllabs.com/ssltest/index.html). If there’s an error about the missing chain or certificate path, there is likely an intermediate certificate missing that needs to be included.
|
||||
|
||||
Please note that the apps cannot connect to servers with self-signed certificates, consider using [Let's Encrypt](/deployment-guide/server/setup-nginx-proxy#configure-nginx-with-ssl-and-http2) instead.
|
||||
|
||||
## Login with ADFS/Office365 is not working
|
||||
|
||||
In line with Microsoft guidance we recommend [configuring intranet forms-based authentication for devices that do not support WIA](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configure-intranet-forms-based-authentication-for-devices-that-do-not-support-wia).
|
||||
|
||||
## How do I attach mobile app logs to a message?
|
||||
|
||||
Use `/mobile-logs` during mobile troubleshooting to let users attach Mattermost mobile app logs to messages. Running `/mobile-logs on` shows the **Attach app logs** option in the attachment menu of the message composer, so users can include device-side logs when messaging an administrator or support engineer. Users can also turn this option on or off from the **Report a problem** screen in the mobile app. The command responds with an ephemeral message visible only to the user who ran it.
|
||||
|
||||
<Important>
|
||||
|
||||
This command requires Mattermost mobile app v2.38 or later.
|
||||
|
||||
</Important>
|
||||
|
||||
- Enable **Attach app logs** for yourself using `/mobile-logs on`.
|
||||
- Disable **Attach app logs** for yourself using `/mobile-logs off`.
|
||||
- Check whether **Attach app logs** is enabled using `/mobile-logs status`.
|
||||
- System admins can manage the setting for another user by appending a username, such as `/mobile-logs on @username`, `/mobile-logs off @username`, or `/mobile-logs status @username`.
|
||||
|
||||
<Important>
|
||||
|
||||
Non-admin users can only manage their own preference. Attempts to target another account return a neutral **Unable to change mobile log settings for that user** message to avoid username enumeration. Preference changes made through this command are recorded in the audit log.
|
||||
|
||||
</Important>
|
||||
|
||||
## I see a “Connecting…” bar that does not go away
|
||||
|
||||
If your app is working properly, you should see a grey “Connecting…” bar that clears or says “Connected” after the app reconnects.
|
||||
|
||||
If you are seeing this message all the time, and your internet connection seems fine, ask your server administrator if the server uses NGINX or another webserver as a reverse proxy. If so, they should check that it is configured correctly for [supporting the websocket connection for APIv4 endpoints](/deployment-guide/server/setup-nginx-proxy#configure-nginx-as-a-proxy-for-mattermost-server).
|
||||
|
||||
## All my outbound connections need to go through a proxy. How can I connect to the Mattermost Hosted Push Notification Service?
|
||||
|
||||
You can set up an internal server to proxy the connection out of their network to the Mattermost Hosted Push Notification Service (HPNS) by following the steps below:
|
||||
|
||||
1. Make sure your proxy server is properly configured to support SSL. Confirm it works by checking the URL at [https://www.digicert.com/help/](https://www.digicert.com/help/).
|
||||
2. Setup a proxy to forward requests to the HPNS URL matching your server's [push notification server location](/administration-guide/configure/push-notification-server-configuration-settings#push-notification-server): `https://global.push.mattermost.com`, `https://us.push.mattermost.com`, `https://eu.push.mattermost.com`, or `https://ap.push.mattermost.com`.
|
||||
3. In Mattermost set **System Console** \> **Notification Settings** \> **Mobile Push** \> **Enable Push Notifications** in prior versions or **System Console \> Environment \> Push Notification Server \> Enable Push Notifications** in versions after 5.12 to "Manually enter Push Notification Service location"
|
||||
4. Enter the URL of your proxy in the **Push Notification Server** field.
|
||||
|
||||
<Note>
|
||||
|
||||
Depending on how your proxy is configured you may need to add a port number and create a URL like `https://push.internalproxy.com:8000` mapped to your region's HPNS URL, such as `https://us.push.mattermost.com`.
|
||||
|
||||
</Note>
|
||||
|
||||
## Build gets stuck at `bundleReleaseJsAndAssets`
|
||||
|
||||
As a workaround, you can bundle the `js` manually first with
|
||||
|
||||
``` sh
|
||||
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
|
||||
```
|
||||
|
||||
and then ignore the gradle task with
|
||||
|
||||
``` sh
|
||||
./gradlew assembleRelease -x bundleReleaseJsAndAssets
|
||||
```
|
||||
|
||||
## No image previews available in the mobile app
|
||||
|
||||
This can happen if the server running Mattermost has its mime types not set up correctly. A server running Linux has this file located in `/etc/mime.types`. This might vary depending on your specific OS and distribution.
|
||||
|
||||
Some distributions also ship without `mailcap` which can result in missing or incorrectly configured mime types.
|
||||
|
||||
## Messages with emojis aren't being sent from the Mobile App
|
||||
|
||||
This can occur if the server running Mattermost is configured with an incorrect character set. To resolve this issue, in the `config.json` file under `SqlSettings`, ensure that the `DataSource` key is configured correctly, then restart the Mattermost server.
|
||||
|
||||
For example:
|
||||
|
||||
``` text
|
||||
"SqlSettings": {
|
||||
"DataSource": "<user:pass>@<servername>/mattermost?charset=utf8mb4,utf8",
|
||||
[...]
|
||||
}
|
||||
```
|
||||
|
||||
See our [Configuration Settings](/administration-guide/configure/environment-configuration-settings#data-source) documentation for details on configuring the connection string to the master database.
|
||||
|
||||
## Testing mobile push notifications
|
||||
|
||||
Make sure to configure push notifications for your [pre-built mobile apps](/deployment-guide/mobile/mobile-app-deployment), or for [your custom built mobile apps](/deployment-guide/mobile/distribute-custom-mobile-apps).
|
||||
|
||||
Then use the following instructions to confirm push notifications are working properly.
|
||||
|
||||
1. Log in to your mobile app with an account on your Mattermost Server, which we’ll refer to as “Account A”.
|
||||
2. (iOS) When the app asks whether you wish to receive notifications, **confirm you want to receive notifications**.
|
||||
|
||||
<img src={useBaseUrl('/images/mobile_push_prompt.png')} width="300" alt="Mattermost prompts you to confirm whether you want to allow mobile push notifications. To test mobile push notifications, you must select Allow." />
|
||||
|
||||
3. Confirm push notifications are enabled for “Account A”.
|
||||
|
||||
1. Go to the notification settings menu in the mobile app.
|
||||
|
||||
<img src={useBaseUrl('/images/mobile_notification_settings.gif')} width="300" alt="Access notification settings by selecting your profile picture to access Settings > Notifications." />
|
||||
|
||||
2. Check that the mobile push notifications are set to send.
|
||||
|
||||
<img src={useBaseUrl('/images/mobile_push_send_for.png')} width="300" alt="Select Push Notifications to confirm when mobile push notifications will be sent." />
|
||||
|
||||
<img src={useBaseUrl('/images/mobile_push_send_when.png')} width="300" alt="Specify whether all new messages or only mentions and direct messages send push notifications." />
|
||||
|
||||
4. Have “Account A” put the app to background or close the app.
|
||||
5. Using a browser, log in to “Account B” on the same Mattermost Server.
|
||||
6. Open a direct message with “Account A”, and send a message.
|
||||
7. A push notification with the message should appear on the mobile device of “Account A”.
|
||||
|
||||
## Troubleshooting push notifications
|
||||
|
||||
If you did not receive a push notification when testing push notifications, use the following procedure to troubleshoot:
|
||||
|
||||
1. In **System Console \> Environment \> Logging \> File Log Level**, select **DEBUG** in order to watch for push notifications in the server log.
|
||||
2. Delete your mobile application, and reinstall it.
|
||||
3. Log in with "Account A" and **confirm you want to receive push notifications** when prompted by the mobile app.
|
||||
4. Go to **Profile** \> **Security** \> **View and Logout of Active Sessions** to confirm that there is a session for the native mobile app matching your login time.
|
||||
5. Retest push notifications.
|
||||
6. If no push notification displays, go to **System Console** \> **Server Logs**, then select **Reload**. Look at the bottom of the logs for a message similar to:
|
||||
|
||||
`[2016/04/21 03:16:44 UTC] [DEBG] Sending push notification to 608xyz0... wi msg of '@accountb: Hello'`
|
||||
|
||||
> - If the log message displays, it means a message was sent to the HPNS server and was not received by your mobile app. Please [create a support ticket](https://support.mattermost.com/hc/en-us/requests/new) with the subject "HPNS issue" for help from Mattermost's Support team.
|
||||
> - If the log message does not display, it means no mobile push notification was sent to “Account A”. Please repeat the process starting at step 2 and double-check each step.
|
||||
|
||||
<Important>
|
||||
|
||||
To conserve disk space, once your push notification issue is resolved, go to **System Console \> Environment \> Logging \> File Log Level**, then select **ERROR** to switch your logging detail level from **DEBUG** to **Errors Only**.
|
||||
|
||||
</Important>
|
||||
|
||||
If push notifications are not being delivered on the mobile device, confirm that you're logged in to the **Native** mobile app session through **Profile \> Security \> View and Log Out of Active Sessions**. Otherwise, the <code>DeviceId</code> won't get registered in the <code>Sessions</code> table and notifications won't be delivered.
|
||||
|
||||
## Integration posts (Mattermost Blocks) do not render or respond
|
||||
|
||||
If buttons, menus, or structured content from an integration post is missing or unresponsive on mobile, see the [Mattermost Blocks reference](https://developers.mattermost.com/integrate/reference/mm-blocks/) in the developer documentation.
|
||||
163
docs/main/deployment-guide/mobile/secure-mobile-file-storage.mdx
Normal file
163
docs/main/deployment-guide/mobile/secure-mobile-file-storage.mdx
Normal file
@@ -0,0 +1,163 @@
|
||||
---
|
||||
title: "Secure file storage"
|
||||
---
|
||||
<PlanAvailability slug="ent-plus" />
|
||||
|
||||
This document outlines the security measures governing file storage in the Mattermost mobile app for iOS and Android. It describes how files are stored, accessed, and protected within the application container, addressing concerns related to sensitive data on mobile devices. The objective is to ensure that only authorized personnel can view, access, or share such data while preventing exposure to unauthorized parties and ensuring isolation from third-party applications.
|
||||
|
||||
Mattermost leverages robust sandboxing mechanisms on both iOS and Android to securely store files in its cache folder within the application container, ensuring isolation from unauthorized third-party apps. User-initiated actions (download, share, copy link) are controlled by server-side permissions, allowing administrators to restrict access to sensitive data, like HIPAA-regulated information, to authorized personnel only.
|
||||
|
||||
## File storage and app sandbox security
|
||||
|
||||
Files uploaded or accessed via the Mattermost mobile app are stored in the app’s cache folder, which resides within the app’s private storage container. This storage location is isolated by each platform’s sandboxing model:
|
||||
|
||||
### iOS – app sandbox
|
||||
|
||||
- **Sandboxing & storage:**
|
||||
|
||||
iOS employs a rigorous sandboxing model that relies on containerized file systems and strict process isolation. Each app operates within its own sandbox, with its home directory randomly assigned during installation. As a result, files stored within the Mattermost app’s cache folder remain accessible only to the app unless explicitly shared by the user.
|
||||
|
||||
- **Secure file viewing:**
|
||||
|
||||
- Non-image and non-video files are rendered using secure frameworks such as QLPreviewController. This controller displays file previews within the app’s sandbox, ensuring that raw file data isn’t exposed to external processes.
|
||||
- Supported image and video files are previewed directly within the app, with the files downloaded to the app's cache folder located within its secure sandbox. For unsupported image and video formats, the Mattermost mobile app uses the QLPreviewController framework, just as it does for other file types.
|
||||
- If the file format is also unsupported by QLPreviewController and [mobile downloads are enabled](/administration-guide/configure/site-configuration-settings#allow-file-downloads-on-mobile) on the server, users can download the file to a location of their choosing. However, if mobile downloads are disabled, these files become unavailable to the user.
|
||||
|
||||
- **Official references:**
|
||||
|
||||
- [Apple App Sandbox Design Guide](https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html)
|
||||
- [Security of runtime process in iOS, iPadOS and visionOS](https://support.apple.com/en-gb/guide/security/sec15bfe098e/web)
|
||||
- [Apple Security Guide](https://help.apple.com/pdf/security/en_GB/apple-platform-security-guide-b.pdf)
|
||||
|
||||
### Android – scoped storage
|
||||
|
||||
- **Sandboxing & storage:**
|
||||
|
||||
Android employs scoped storage by assigning each app its own Linux user ID and a dedicated private directory. This model prevents other applications from accessing an app’s cache without explicit permission. As a result, the Mattermost app’s files remain inaccessible to other apps—unless the device is rooted, or the user explicitly shares the data.
|
||||
|
||||
- **Secure file viewing:**
|
||||
|
||||
- When users attempt to view non-image/video files, Mattermost uses an `Intent.ACTION_VIEW` to open the file. This intent delegates rendering to an external app only if the user explicitly triggers the action, while the file remains securely stored within Mattermost’s cache folder.
|
||||
- Viewing non-image/video files is available only if [mobile downloads are enabled](/administration-guide/configure/site-configuration-settings#allow-file-downloads-on-mobile) on the server.
|
||||
- Image and video files with supported formats are previewed directly within the app, with the files downloaded to the app's cache folder located within its secure sandbox. For unsupported image and video formats, the Mattermost mobile app uses `Intent.ACTION_VIEW` to open the file with an external application, just as it does for other file types.
|
||||
|
||||
- **Official reference:**
|
||||
|
||||
- [Scoped Storage](https://developer.android.com/about/versions/10/privacy/changes#scoped-storage)
|
||||
|
||||
Additionally, both platforms may clear cached data automatically (e.g., under low storage conditions or upon user logout), thereby reducing the risk of sensitive information remaining on the device.
|
||||
|
||||
## Differentiating file handling to external applications
|
||||
|
||||
- **Previewing files:**
|
||||
|
||||
File previewing follows the secure viewing practices described above in the “Secure File Viewing” sections for iOS and Android. All files prior to being previewed are stored in the cache folder of the Mattermost app sandbox. Images and videos with supported formats are previewed directly within the Mattermost mobile app. Non‑image and non‑video files are also previewed in-app in iOS but are handed off to an external application in Android while the raw data remains securely stored in the app’s cache. Previewing non-image/non-video files is possible only if [mobile downloads are enabled](/administration-guide/configure/site-configuration-settings#allow-file-downloads-on-mobile) on the server side.
|
||||
|
||||
- **Downloading files:**
|
||||
|
||||
- When a user initiates a file download, the file is first stored in Mattermost’s private cache directory. The user is then immediately prompted to save it to another destination via platform-specific sharing methods.
|
||||
- On **iOS** devices:
|
||||
- The built-in sandboxing ensures that the downloaded files remain inaccessible to other apps unless the user explicitly shares or saves them through the system’s file sharing mechanisms. Once downloaded, the file appears in the gallery.
|
||||
- If the server has the download setting enabled, the user has two options:
|
||||
1. Download the file: Opens the **Files** app, allowing the user to save the file to any permitted location, including iCloud.
|
||||
2. Share the file: Launches the native share sheet, enabling the user to share the file with other compatible applications.
|
||||
- On **Android** devices, the app employs the system’s file picker. This allows the end-user to select a preferred storage location. Once saved, the file becomes accessible to other apps based on the chosen location and the device’s file sharing permissions.
|
||||
|
||||
## File accessibility options
|
||||
|
||||
Depending on server configuration, users may download files, share them, or copy a public link directly from the Mattermost mobile app. These actions are always user‑initiated, ensuring that sensitive data is only exposed with explicit consent.
|
||||
|
||||
Additionally, administrators have the option to restrict mobile file uploading and downloading to ensure that sensitive content remains within approved channels. When mobile file downloads are disabled, the app allows only image and video file previews. However, if general file sharing is enabled on the Mattermost server, file operations via mobile browsers will still be possible.
|
||||
|
||||
## Layered defense strategies for sensitive eata
|
||||
|
||||
Mattermost is designed to protect sensitive data—such as sensitive information and HIPAA-regulated information—by ensuring that only authorized personnel can access or share it. The platform combines secure mobile app features with powerful server-side controls, providing a layered defense that minimizes the risk of data exposure.
|
||||
|
||||
### Core defense pillars
|
||||
|
||||
- **Robust authentication:** Mattermost requires user authentication through SSO (e.g., SAML, LDAP, OpenID Connect) or traditional username/password logins. This authentication is managed by server-side identity controls, ensuring that only verified users can access the app and its data. For more details, see the [Mattermost Security Overview](/security-guide/security-guide-index).
|
||||
- **Server-side access controls:** Administrators can enforce policies through the System Console to restrict file downloads, sharing, and public link generation. Currently, policies are applied at the server level. For more details, see [Configuration Settings - File Sharing and Downloads](/administration-guide/configure/site-configuration-settings#file-sharing-and-downloads).
|
||||
- **Sandbox isolation:** As discussed earlier, Mattermost’s mobile apps store files in a sandboxed environment. This isolation ensures that even if a device is shared or compromised, other apps cannot access the cached files without explicit user action.
|
||||
- **Controlled file previews:** File previews (via QLPreviewController on **iOS** or open intent on **Android**) occur within the application’s controlled environment or delegate to OS-approved apps without duplicating sensitive data outside the sandbox.
|
||||
- **OS-Level encryption:** While files in the cache folder are stored unencrypted by default, they are protected at rest by OS-level encryption (iOS File Data Protection and Android Full Disk Encryption).
|
||||
|
||||
By combining strict authentication, server-side controls, sandbox isolation, and secure file handling, Mattermost ensures that sensitive data remains confined to authorized users, with access and sharing tightly controlled by server policies, platform security features, and explicit user consent.
|
||||
|
||||
## Testing procedure to validate file isolation
|
||||
|
||||
The playbook below aims to test and confirm that files stored in the Mattermost app’s private cache folder—where sensitive data may reside—are not accessible by unauthorized third-party applications. The tests are designed to show that while public directories, such as Downloads/ can be accessed, the private Mattermost cache remains isolated unless a file is explicitly shared by an authorized user.
|
||||
|
||||
1. **Preparation**
|
||||
|
||||
- On **Android**:
|
||||
- Install Adobe Acrobat Reader for PDF viewing.
|
||||
- Install Files by Google as a file manager.
|
||||
- Install Google Chrome as a system browser.
|
||||
|
||||
- On **iOS**:
|
||||
- Install Adobe Acrobat Reader (from the App Store).
|
||||
- Use the built-in Files app.
|
||||
- Use Safari as the default browser.
|
||||
|
||||
- Any PDF viewer, file manager, or browser can be used for these steps.
|
||||
|
||||
2. **Control test: Verify public directory accessibility**
|
||||
|
||||
- **Android:**
|
||||
- Open Files by Google.
|
||||
- Navigate to a known public directory (e.g., Downloads/).
|
||||
- Confirm that files in this location are visible and can be opened.
|
||||
|
||||
- **iOS:**
|
||||
- Open the Files app.
|
||||
- Browse to an accessible directory (e.g., iCloud Drive or “On My iPhone” public folders).
|
||||
- Confirm these files are accessible.
|
||||
|
||||
This step demonstrates that allowed directories can be accessed, setting a baseline for comparison.
|
||||
|
||||
3. **Attempt unauthorized access to Mattermost’s private cache**
|
||||
|
||||
- **Android:**
|
||||
- In Files by Google, try navigating through the directory structure to identify files of the Mattermost application.
|
||||
- Verify that you cannot access private directories such as Mattermost app’s private cache folder.
|
||||
|
||||
- **iOS:**
|
||||
- Open the Files app.
|
||||
- Verify that the Mattermost app’s private cache folder does not appear under “On My iPhone/iPad.”
|
||||
|
||||
4. **Attempt unauthorized access to a specific file in Mattermost’s private cache**
|
||||
|
||||
- **Android:**
|
||||
- Use the search functionality in Files by Google to search for a known file name from the Mattermost cache.
|
||||
- Verify that the file does not appear in search results.
|
||||
|
||||
- **iOS:**
|
||||
- Use the Files app’s search capability to look for a specific file name from the Mattermost cache.
|
||||
- Confirm that the file does not appear in search results.
|
||||
|
||||
5. **Attempt authorized access to downloaded file**
|
||||
|
||||
- **Android:**
|
||||
- Confirm that mobile downloads are enabled on the server.
|
||||
- Download a file using the Mattermost mobile app.
|
||||
- Open the Files by Google app and verify that the downloaded file is visible and opens correctly.
|
||||
|
||||
- **iOS:**
|
||||
- Confirm that mobile downloads are enabled on the server.
|
||||
- Download a file using the Mattermost mobile app.
|
||||
- Open the iOS Files app and verify that the downloaded file appears and can be opened successfully.
|
||||
|
||||
6. **Repeat across multiple apps and devices**
|
||||
|
||||
The steps above use the Files app of Google and iOS. Repeat these tests using each suggested app on different devices and OS versions (both Android and iOS) to ensure that the private cache folder remains inaccessible under all conditions.
|
||||
|
||||
## Test execution & findings
|
||||
|
||||
Mattermost executed the playbook above, including scanning for hidden files, both during normal operation and after forcing the app to stop or crash, and observed the following results:
|
||||
|
||||
- **Devices Tested**: iPhone 12, iOS 18.4, Android 11
|
||||
- **Apps Used**: Adobe Reader, Google Files app, Android’s native Files app, iOS Files app, Files Media Manager, Hidden Files Finder, Hidden Files Finder & Recover
|
||||
- **Results**: Third-party file browsers and recovery tools consistently failed to access the Mattermost app’s cache folder or its contents. Access was only possible when files were explicitly downloaded or shared via Mattermost’s controlled functionality by an authorized user.
|
||||
- **Outcome**: Files remain isolated within the app container, adhering to platform security guidelines and protecting against unauthorized access.
|
||||
|
||||
The documented testing procedures confirm that the app’s file storage remains inaccessible to unauthorized third-party applications, thereby maintaining a strong security posture. Coupled with strong authentication and native OS encryption, the Mattermost mobile app provides a robust framework that keeps sensitive data on mobile devices confined to authorized users while addressing key access control and risk mitigation requirements.
|
||||
Reference in New Issue
Block a user