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,332 @@
|
||||
---
|
||||
title: "Channel-specific access rules"
|
||||
---
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
Channel and Team Admins can self-manage access controls for their channels directly through the Channel Settings modal, without requiring System Admin intervention. For organization-wide policies created by System Admins, see [System-wide attribute-based access policies](/administration-guide/manage/admin/abac-system-wide-policies). For team-scoped policies that apply rules across multiple channels within a team, see [Team-level channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies).
|
||||
|
||||
From Mattermost v11.8, channel access rules can be applied to **both private and public channels**. The two channel types behave differently under ABAC:
|
||||
|
||||
- **Private channels** are hard-gated. Non-matching members are removed during synchronization, and only matching users can be added or invited.
|
||||
- **Public channels** are advisory. Non-matching members are *never* removed (anyone can still join a public channel by browsing or via a direct link). With auto-add enabled the policy still pulls matching users in; with auto-add disabled the channel surfaces under **Browse Channels \> Recommended channels** for users whose attributes match.
|
||||
|
||||
Each ABAC channel access policy has an explicit active state that determines whether the policy will automatically add users who meet the policy's criteria but are not yet channel members. For private channels, the policy's rules are always enforced to remove members who no longer meet the required attribute rules, regardless of the active state. For public channels, no member is ever removed by ABAC — the rules are advisory only.
|
||||
|
||||
With channel access rules, Channel and Team Admins can:
|
||||
|
||||
- Create channel-specific access rules using a simple interface.
|
||||
- Use rules that are **additive** to any system policies. For private channels, both must be satisfied for adds and invites. For public channels, the combined rules affect auto-add and recommendations only, and don't block joins or remove members.
|
||||
- Automatic member synchronization with immediate feedback.
|
||||
- Self-exclusion prevention to avoid locking yourself out (private channels only).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Attribute-Based Access Control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) must be enabled by a System Admin in **System Console \> System Attributes \> Attribute-Based Access**.
|
||||
- You need Channel Admin permissions and the `manage_channel_access_rules` permission.
|
||||
- Channel access rules are available for private and public channels, with behavior that varies by channel type. See [Public and private channel behavior](#public-and-private-channel-behavior). Default channels (such as Town Square and Off-Topic), shared channels, and group-synced channels remain ineligible.
|
||||
|
||||
### Access Channel Settings
|
||||
|
||||
1. In a private or public channel where you have Channel Admin permissions, select the channel name at the top of the center pane.
|
||||
2. Select **Channel Settings** from the dropdown menu.
|
||||
3. Navigate to the **Membership Policy** tab. This tab is only visible for eligible channels when you have the appropriate permissions and ABAC is enabled system-wide. The tab is hidden on default channels, shared channels, and group-synced channels.
|
||||
|
||||
<Tip>
|
||||
|
||||
You can also assign ABAC rules to a channel directly from a channel's details page in the System Console under **Channel Management** by enabling the **Enable attribute-based channel access** option. Under **Access policy**, select **Link to a policy** to select an existing policy.
|
||||
|
||||
</Tip>
|
||||
|
||||
## Configure access rules
|
||||
|
||||
Channel access rules use the same simple interface as system policies, allowing you to create attribute-based conditions without complex syntax.
|
||||
|
||||
1. In the **Membership Policy** tab, you'll see any inherited system policies at the top in a blue information banner (if applicable).
|
||||
2. Use the **Add attribute** button to create new access conditions:
|
||||
- **Select attribute**: Choose from available user attributes
|
||||
- **Choose operator**: Select how the attribute should match:
|
||||
- **Is**: Exact match with specified value
|
||||
- **Is not**: Must not match specified value
|
||||
- **In**: Must match any of multiple specified values
|
||||
- **Contains**: Attribute value must contain specified text
|
||||
- **Set values**: Enter the required attribute values
|
||||
3. Add multiple conditions as needed. All conditions are combined with logical AND (all must be satisfied).
|
||||
4. Select **Test access rules** to preview which users would be granted access based on your current rules.
|
||||
|
||||
### Auto-sync membership
|
||||
|
||||
The **Auto-add members based on access rules** toggle controls automatic membership management. The behavior differs by channel type:
|
||||
|
||||
- **Private channels (hard gate)**: Membership stays consistently aligned with the rules, similar to how LDAP group channels work.
|
||||
- **Enabled**: Users matching the rules are automatically added. If users temporarily lose attributes and later regain them, they will be automatically re-added.
|
||||
- **Disabled**: Rules act as a gate (preventing unauthorized joins) but don't automatically add qualifying users.
|
||||
- **Public channels (advisory)**: ABAC never removes members — anyone can still join a public channel.
|
||||
- **Enabled**: Matching users are automatically added (a convenience, not a gate).
|
||||
- **Disabled**: The channel appears under **Browse Channels \> Recommended channels** for users whose attributes match, surfacing the channel without adding anyone.
|
||||
|
||||
<Important>
|
||||
|
||||
- Auto-add/auto-sync is checked on a per-channel policy basis, not inherited from parent system-wide policies.
|
||||
- If a system policy has auto-sync enabled, Channel and Team Admins cannot disable it at the channel level.
|
||||
- If a system policy has auto-sync disabled, Channel and Team Admins can choose to enable it for their channel.
|
||||
- When no rules are configured, this toggle is automatically disabled.
|
||||
- On **private** channels, users who no longer meet required attribute rules are always removed during synchronization regardless of the auto-sync setting. On **public** channels, no member is ever removed by ABAC.
|
||||
|
||||
</Important>
|
||||
<Note>
|
||||
|
||||
If a policy rule references attribute values from a `shared_only` or `source_only` attribute that you don't personally hold, those values appear as `--------` and the row is read-only. Test and Delete actions are also disabled for those rows. See [Attribute value masking](/administration-guide/manage/admin/abac-system-wide-policies#attribute-value-masking) for details.
|
||||
|
||||
</Note>
|
||||
|
||||
### Validation and safety
|
||||
|
||||
Before saving changes, Mattermost validates your rules to prevent common issues:
|
||||
|
||||
- **Required fields**: All attribute selections and values must be completed.
|
||||
- **Self-exclusion prevention**: For private channels, you cannot save rules that would remove yourself from the channel. The check is skipped for public channels because they are advisory under ABAC and can't lock anyone out.
|
||||
- **Conflict detection**: Rules that create impossible conditions are identified.
|
||||
|
||||
When you save changes that affect membership, a confirmation dialog shows you:
|
||||
|
||||
- How many users will be added or removed.
|
||||
- Option to view the specific users affected.
|
||||
- Confirmation required before applying changes.
|
||||
|
||||
Once a policy is attached to a channel, the channel cannot be converted between public and private until the policy is removed. The two modes have different semantics (advisory vs. hard gate), so a silent conversion would change what an existing policy actually does to its members.
|
||||
|
||||
## Public and private channel behavior
|
||||
|
||||
Membership policies behave differently depending on the type of channel they're applied to:
|
||||
|
||||
- **Private channels**: Membership policies are enforced. Users who match the policy's rules are added, and users who don't match the rules are removed during synchronization.
|
||||
- **Public channels**: Membership policies are advisory. Matching users may be automatically added when auto-add is enabled, but non-matching members are not removed.
|
||||
- When auto-add is disabled for a public channel, matching channels are surfaced as **recommended** rather than enforcing membership.
|
||||
- Direct messages and group messages aren't eligible for membership policies.
|
||||
- Default channels such as **Town Square** and **Off-Topic** are excluded.
|
||||
|
||||
<Note>
|
||||
|
||||
Public channels with membership policies may appear in **Browse Channels** under **Recommended**, and matching users may be marked **Recommended** in the channel invite flow. See [Browse channels](/end-user-guide/collaborate/browse-channels) and [Manage channel members](/end-user-guide/collaborate/manage-channel-members) for the end-user experience.
|
||||
|
||||
</Note>
|
||||
|
||||
## Channel-level permission policies
|
||||
|
||||
From Mattermost v11.8.0, channel admins can define channel-level permission rules for file upload and file download based on user attributes and channel role. Applicable roles include **channel admin**, **channel member**, and **channel guest**.
|
||||
|
||||
For system-wide permission policies that restrict file upload and download actions, see [Permission policies](/administration-guide/manage/admin/abac-system-wide-policies#permission-policies).
|
||||
|
||||
## Simulate access
|
||||
|
||||
From Mattermost v11.8.0, admins can use **Simulate access** in Channel Settings to preview whether selected users can perform actions such as uploading files or downloading files before saving policy changes.
|
||||
|
||||
- Simulation can evaluate draft rules before they're saved, so you can confirm the intended scope without affecting live channel access.
|
||||
- Some denied results may indicate that the decision came from another policy. In that case, Mattermost shows that access was denied by another policy without exposing policy details you aren't authorized to see.
|
||||
|
||||
<Note>
|
||||
|
||||
Channel-level permission policies and **Simulate access** are gated by the `PermissionPolicies` feature flag (`MM_FEATUREFLAGS_PERMISSIONPOLICIES`) and require a Mattermost Enterprise Advanced license. See the Mattermost developer documentation for details on [enabling feature flags in a self-hosted deployment](https://developers.mattermost.com/contribute/more-info/server/feature-flags/#self-hosted-and-local-development). Mattermost Cloud customers can request this feature flag be enabled by contacting their Mattermost Account Manager or by [creating a support ticket](https://support.mattermost.com/hc/en-us/requests/new?ticket_form_id=11184911962004).
|
||||
|
||||
</Note>
|
||||
|
||||
## Manage team-scoped membership policies in Team Settings
|
||||
|
||||
From Mattermost v11.7, Team Admins can create, edit, and delete channel membership policies directly from Team Settings, scoped to channels within their team. This lets teams self-manage attribute-based membership for their own channels without requiring a System Admin to create or modify a system-wide policy.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Attribute-Based Access Control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) must be enabled by a System Admin in **System Console \> System Attributes \> Attribute-Based Access**.
|
||||
- You need Team Admin permissions for the team and the `manage_team_access_rules` permission.
|
||||
- Team-scoped membership policies can be assigned to both public and private channels within the team.
|
||||
|
||||
### Team Admin workflow
|
||||
|
||||
1. Open **Team Settings** from the team menu, and go to the **Channel Membership** tab. This tab is only visible to Team Admins with the `manage_team_access_rules` permission when ABAC is enabled system-wide.
|
||||
2. Select **Add Policy** and enter a name for the policy. Parent policy names must be unique; if you enter a name that's already in use, Mattermost displays a user-friendly error and prevents the policy from being saved.
|
||||
3. Define the attribute rules that determine which users can be members of channels assigned to this policy. Rules use the same attribute conditions available for channel-specific access rules.
|
||||
4. Assign the applicable private channels in the team to the policy.
|
||||
5. Select **Save** to create or update the policy. Team-scoped policies can be edited or deleted from the same tab at any time.
|
||||
|
||||
### Team Settings sync status footer
|
||||
|
||||
The **Channel Membership** tab includes a sync status footer that shows:
|
||||
|
||||
- **Last sync time**: The time of the most recent membership synchronization for policies in this team.
|
||||
- **Sync now**: An on-demand action that triggers an immediate synchronization for the team's policies.
|
||||
|
||||
Team-scoped sync is limited to the team admin's team scope. Triggering **Sync now** from Team Settings does not affect channels or policies outside the current team.
|
||||
|
||||
### Sync behavior by channel type
|
||||
|
||||
Sync behavior for team-scoped membership policies depends on the type of channel the policy is assigned to:
|
||||
|
||||
- **Public channels**: Sync is advisory and add-only. Users who match the policy's rules are added to the channel, but no users are removed if their attributes change.
|
||||
- **Private channels**: Sync is enforced. Users who match the policy's rules are added to the channel, and users who no longer match the rules are removed during the next synchronization.
|
||||
|
||||
### Automatic sync on policy changes
|
||||
|
||||
Mattermost automatically runs a sync job whenever a team-scoped membership policy is created, or its rules, assigned channels, or active state change. Team Admins don't need to manually trigger **Sync now** for these updates; the sync runs as part of the change.
|
||||
|
||||
## Policy inheritance
|
||||
|
||||
Channel-level (child) ABAC policies now behave independently and consistently, even when parent system-wide policies exist. Each policy maintains its own active state and configuration.
|
||||
|
||||
When both [system policies](/administration-guide/manage/admin/abac-system-wide-policies) and channel rules are configured:
|
||||
|
||||
1. **System policies** are displayed in a blue banner at the top (read-only)
|
||||
2. **Channel rules** are managed in the access rules section below
|
||||
3. **Users must satisfy BOTH** system policies and channel rules to access the channel
|
||||
4. Channel rules **add restrictions** but cannot weaken system policies
|
||||
5. **Auto-add behavior** is determined by the individual channel policy, not inherited from parent system-wide policies. System-wide policies can pass down their rules, but auto-add/auto-sync is evaluated per channel.
|
||||
|
||||
## Use cases and recommendations
|
||||
|
||||
**Ideal use cases for channel access rules:**
|
||||
|
||||
- **Project-specific channels**: Restrict access to team members working on specific projects
|
||||
- **Clearance-based discussions**: Ensure only users with appropriate security clearance can participate
|
||||
- **Department communications**: Limit channel access to specific organizational units
|
||||
- **Temporary access**: Create rules for short-term project teams or contractor access
|
||||
|
||||
**Best practices:**
|
||||
|
||||
- **Start simple**: Begin with basic attribute conditions before adding complexity
|
||||
- **Test before saving**: Always use the "Test access rules" feature to verify your intended scope
|
||||
- **Document changes**: Consider posting a message in the channel when access rules change
|
||||
- **Regular review**: Periodically review rules to ensure they remain appropriate
|
||||
- **Coordinate with IT**: Work with System Admins for complex organizational policies
|
||||
|
||||
**When to use system policies vs. channel rules:**
|
||||
|
||||
- **System policies**: Use for organization-wide standards, compliance requirements, or policies affecting multiple channels
|
||||
- **Channel rules**: Use for channel-specific restrictions, project-based access, or when you need immediate control without IT involvement
|
||||
|
||||
## End-user experience
|
||||
|
||||
When channels have attribute-based access controls applied, users will see clear indicators and experience specific behaviors designed to maintain security while providing transparency.
|
||||
|
||||
### Visual indicators
|
||||
|
||||
**Channel Members panel:**
|
||||
|
||||
- Information banner at the top explains that attribute-based access is enabled. The message differs by channel type: private channels indicate that access is restricted by user attributes, while public channels indicate that member recommendations are based on user attributes.
|
||||
- Displays required attribute values as tags (e.g., "Engineering", "Confidential").
|
||||
- Tooltip on hover shows the attribute name for each value.
|
||||
|
||||
**Add Members modal:**
|
||||
|
||||
- Similar information banner and attribute value display.
|
||||
- On **private** channels, users who don't match the access criteria won't appear in search results — only eligible users can be added.
|
||||
- On **public** channels, the full team list is shown and matching users are surfaced with a **Recommended** tag at the top of the list. Anyone can still be added because public-channel ABAC is advisory.
|
||||
|
||||
**Browse Channels:**
|
||||
|
||||
- A **Recommended channels** filter is available in the channel-type dropdown when ABAC is enabled. Selecting it lists the public channels whose policies the user matches — useful when auto-add is disabled and the channel is offered as a recommendation rather than auto-joined.
|
||||
|
||||
### Functional restrictions
|
||||
|
||||
When ABAC is enabled for a **private** channel:
|
||||
|
||||
- **Search limitations**: Users who don't match access criteria don't appear in member search results.
|
||||
- **Invitation restrictions**: Only users meeting attribute requirements can be added to the channel.
|
||||
- **Guest user exclusions**: Private channels with ABAC policies cannot have guest users invited.
|
||||
- **Automatic removal**: Users who lose required attributes are automatically removed during the next synchronization.
|
||||
|
||||
When ABAC is enabled for a **public** channel:
|
||||
|
||||
- **Search results are unfiltered**: All eligible team members appear in the Add Members modal so admins can still invite anyone; matching users carry a **Recommended** tag.
|
||||
- **Recommendations**: With auto-add disabled, the channel surfaces under **Browse Channels \> Recommended channels** for matching users.
|
||||
- **Auto-add (when enabled)**: Matching users are added automatically. **Members are never removed** by ABAC — users can always leave on their own, and joining freely is unaffected because the channel is public.
|
||||
|
||||
<Note>
|
||||
|
||||
These behaviors apply across all Mattermost clients, including web, desktop, and mobile, to ensure consistent enforcement.
|
||||
|
||||
</Note>
|
||||
|
||||
## Troubleshooting and FAQs
|
||||
|
||||
Common questions about attribute-based access control implementation and usage.
|
||||
|
||||
### Permission and access
|
||||
|
||||
#### Why can't I see the Membership Policy tab in Channel Settings?
|
||||
|
||||
The **Membership Policy** tab is only visible when all of these conditions are met:
|
||||
|
||||
- You have Channel Admin role or higher for the channel.
|
||||
- The channel is a private or public channel (not a default channel like Town Square or Off-Topic, group message, direct message, shared, or group-synced channel).
|
||||
- ABAC is enabled system-wide by a System Admin in **System Console \> System Attributes \> Attribute-Based Access**.
|
||||
- Your user role includes the `manage_channel_access_rules` permission.
|
||||
|
||||
#### Can Channel and Team Admins override system policies?
|
||||
|
||||
No. Channel rules are always **additive** to system policies. Users must satisfy both system policies AND channel rules to access the channel. Channel and Team Admins cannot weaken or override restrictions set by System Admins.
|
||||
|
||||
#### What happens if I create rules that would exclude myself?
|
||||
|
||||
For **private** channels, Mattermost prevents this with self-exclusion validation. If your rules would remove you from the channel, you'll see an error message and cannot save the changes until you adjust the rules or reset them.
|
||||
|
||||
For **public** channels, the self-exclusion check is skipped — public-channel ABAC is advisory, the policy can't kick anyone out, and you can always re-join a public channel directly. This lets you author a policy intended for a different team (for example, a Sales admin configuring an Engineering recommendation) without being blocked.
|
||||
|
||||
#### Can I convert a public channel to private (or vice versa) while a policy is attached?
|
||||
|
||||
No. The two modes have different semantics — a public-channel policy is advisory while a private-channel policy is a hard gate that removes non-matching members. A silent conversion would change what the existing policy does to its members, so Mattermost requires you to remove the policy first, convert the channel, and re-attach the policy if you still want it.
|
||||
|
||||
### Rule configuration
|
||||
|
||||
#### Can I use advanced CEL expressions in Channel Settings?
|
||||
|
||||
No. Channel Settings only supports Basic Mode with simple attribute conditions. For complex expressions with nested logic or mixed operators, System Admins need to create policies in the System Console.
|
||||
|
||||
#### How do I remove all access rules from a channel?
|
||||
|
||||
Delete all attribute conditions from the access rules table. When no rules are configured and no system policies are applied, the channel returns to standard access behavior.
|
||||
|
||||
#### Why is the auto-sync toggle disabled?
|
||||
|
||||
The auto-sync toggle is automatically disabled when:
|
||||
|
||||
- No access rules are configured
|
||||
- A system policy with auto-sync enabled is applied (Channel and Team Admins cannot disable it)
|
||||
- There are validation errors in the current rules
|
||||
- The channel's access control policy is not in an active state
|
||||
|
||||
<Note>
|
||||
|
||||
**Troubleshooting auto-sync issues**: If auto-sync functionality (automatic adding/re-adding of members) is not working as expected, verify that the channel's access control policy is in an active state. An inactive policy will prevent automatic member additions from occurring. Note that enforcement of rules (removal of members who no longer meet requirements) happens regardless of the policy's active state.
|
||||
|
||||
</Note>
|
||||
|
||||
### Synchronization and membership
|
||||
|
||||
#### How quickly are membership changes applied?
|
||||
|
||||
When you save access rules, membership sync job is created and changes are applied as soon as the job is completed. Additionally, Mattermost runs synchronization jobs on a schedule to handle attribute changes from external systems (LDAP, SAML). The interval is set by `AccessControlSettings.SyncJobIntervalSeconds` and defaults to 3600 seconds (60 minutes). User attributes used for access control evaluation are refreshed on a separate schedule controlled by `AccessControlSettings.AttributeRefreshIntervalSeconds`, which defaults to 30 seconds.
|
||||
|
||||
#### Will users be notified when they're removed from a channel?
|
||||
|
||||
Yes, users receive standard Mattermost notifications when they're removed from channels due to access rule changes, similar to manual removals.
|
||||
|
||||
#### Can I see who was added or removed during synchronization?
|
||||
|
||||
Yes, the confirmation modal before saving shows exactly which users will be affected. System Admins can also view detailed synchronization logs in the System Console.
|
||||
|
||||
### Attribute and data questions
|
||||
|
||||
#### Which user attributes can I use in access rules?
|
||||
|
||||
You can use any user attributes either synchronized via LDAP/SAML or manually configured by System Admins in **System Console \> System Attributes \> User Attributes**.
|
||||
|
||||
#### What happens if a user attribute changes?
|
||||
|
||||
During the next scheduled synchronization (every 60 minutes by default), users who no longer match the access rules will be removed from the channel, and new users who now match will be added (if auto-sync is enabled).
|
||||
|
||||
#### Do guest users work with ABAC channels?
|
||||
|
||||
No. Private channels with attribute-based access control cannot have guest users. This ensures strict adherence to access control policies based on organizational attributes.
|
||||
|
||||
#### Can group-sync channels use ABAC?
|
||||
|
||||
No. Channels configured with group synchronization cannot use attribute-based access control. Group-sync and ABAC are mutually exclusive features - you must choose one method of access control per channel.
|
||||
@@ -0,0 +1,193 @@
|
||||
---
|
||||
title: "System-wide attribute-based access policies"
|
||||
---
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
Use this guide to create and manage organization-wide attribute-based access policies in the System Console. Policies can be assigned to both channels and teams. For channel-level rules managed by Channel Admins, see [Channel-specific access rules](/administration-guide/manage/admin/abac-channel-access-rules). For team membership policies, see [Team membership access policies](/administration-guide/manage/admin/abac-team-membership).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Attribute-based access controls (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) require defined user attributes. First [configure user attributes](/administration-guide/manage/admin/user-attributes) in the System Console.
|
||||
- Then go to **System Console \> System Attributes \> Attribute-Based Access** to enable attribute-based access controls for your Mattermost instance. This functionality requires a Mattermost Enterprise Advanced license.
|
||||
|
||||
From Mattermost v10.11, user-managed attributes are excluded from attribute-based access control (ABAC) rules by default for security reasons. This prevents access control policies from being circumvented by users editing their own profile attributes. To include user-managed attributes in ABAC rules, a system admin must explicitly enable the `EnableUserManagedAttributes` configuration setting. See the [user attribute](/administration-guide/manage/admin/user-attributes#before-you-begin) documentation for details on enabling this feature. This configuration setting is available only in Enterprise Edition Advanced and is disabled by default.
|
||||
|
||||
## Define access control policies
|
||||
|
||||
You can add multiple rules to a single policy, and each rule can include multiple attribute values.
|
||||
|
||||
1. In the System Console, go to **System Attributes \> Attribute-Based Access** and select **Add Policy**.
|
||||
|
||||
2. Enter a unique policy name. Parent access control policy names must be unique; if you enter a name that's already in use, Mattermost displays a user-friendly error message and prevents the policy from being saved until you choose a different name.
|
||||
|
||||
3. Choose whether to automatically add users who match your configured attribute values as new members. Automatic synchronization is disabled by default.
|
||||
|
||||
- **True**: Automatically maintains channel membership according to the defined rules as user attributes change.
|
||||
- **False** (**Default**): Only removes members and restricts adding them to the channel if they don’t match defined rules. Users are not automatically added.
|
||||
|
||||
Regardless of whether this configuration setting, users who no longer match the configured attribute values in the future will be removed from the channel after the next channel synchronization.
|
||||
|
||||
4. Define the attribute-based access rules to restrict channel membership.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="simple-mode" label="Simple Mode">
|
||||
|
||||
Simple Mode is ideal for simple and straightforward access control scenarios. Each row is a single condition that must be met for a user to comply with the policy. Simple Mode only supports simple conditions without nested logic or mixed logical operators. All rules are combined with a logical AND operator `&&`.
|
||||
|
||||
1. Select **Add attribute** and select the attribute you want to use for access control.
|
||||
|
||||
2. Specify how you want the attribute to match the user profile. You can choose from the following options:
|
||||
|
||||
> - **Is**: The attribute must be an exact match of the value.
|
||||
> - **Is not**: The attribute must not contain specified value.
|
||||
> - **In**: The attribute must match at least one value.
|
||||
> - **Starts with**: The attribute value must start with the specified value.
|
||||
> - **Ends with**: The attribute value must end with the specified value.
|
||||
> - **Contains**: The attribute value must exist somewhere with the specified value.
|
||||
>
|
||||
> When the selected attribute is a **Ranked** attribute (an ordered list of values, such as clearance or classification levels), the match options are ordered comparisons instead. These let you match everyone at or above a threshold rather than only an exact value:
|
||||
>
|
||||
> - **Is exactly** / **Is not**: The value must exactly match, or must not match, the specified value.
|
||||
> - **Is at least**: The value must be equal to or higher than the specified value - for example, clearance *is at least* Secret matches Secret and every higher level.
|
||||
> - **Is greater than**: The value must be higher than the specified value.
|
||||
> - **Is at most**: The value must be equal to or lower than the specified value.
|
||||
> - **Is less than**: The value must be lower than the specified value.
|
||||
|
||||
3. Specify the attribute values that users must have to be granted access to the channel.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="advanced-mode" label="Advanced Mode">
|
||||
|
||||
Advanced Mode is ideal for complex access control scenarios that require CEL syntax to combine multiple conditions with logical operators that support rules like `user.<attribute> == <value>`, using `&&` / `||` (and/or) for multiple conditions, and `()` to group conditions. The CEL Expression Editor provides real-time syntax validation and feedback, as well as context-aware autocomplete for attributes, operators, and attribute values.
|
||||
|
||||
You can also start defining rules in Simple Mode and then switch to Advanced Mode to refine the rules further as needed. However, you'll be blocked from switching from Advanced back to Simple Mode if one of the following are true:
|
||||
|
||||
- Mixed logical operators are used between conditions.
|
||||
- Nested logic/grouping (parentheses) are present.
|
||||
- Unsupported operators or expressions are detected.
|
||||
|
||||
The syntax structure is `user.<attribute> <operator> <value>`.
|
||||
|
||||
As you type, autocompletes show available attributes. As you select attributes, autocomplete suggests appropriate CEL operators. After selecting an operator, when attribute values are pre-defined, autocomplete suggests values to choose from. Mattermost will explicitly indicate issues such as missing operators, incorrect syntax, or incomplete conditions.
|
||||
|
||||
Select the **Validate syntax** bar to check the syntax of your rule. If the syntax is valid, the bar will turn green and display a message indicating that the syntax is valid. If there are any issues, the bar will turn red and display an error message.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Simulate access
|
||||
|
||||
Select **Test access rule** to test the rule against your user base to return how many users would be granted access to the channel based on the current rule. Test your rules to ensure the intended scope and avoid unexpected access changes.
|
||||
|
||||
From Mattermost v11.8.0, you can use **Simulate access** to preview allowed and denied outcomes for specific users before saving policy changes:
|
||||
|
||||
1. Open the policy editor in the System Console.
|
||||
2. Select **Simulate access**.
|
||||
3. Choose the users you want to test.
|
||||
4. Review the allowed and denied outcomes by action, such as joining a channel or uploading and downloading files.
|
||||
5. Adjust the rules before saving.
|
||||
|
||||
Simulation can test draft policy changes before they affect live channel access or file permissions. Detailed rule and attribute information is shown only when the denial comes from the policy or scope you're editing; otherwise, Mattermost may show that access was denied by another policy.
|
||||
|
||||
<Note>
|
||||
|
||||
**Simulate access** and channel-level permission policies for file upload and file download are gated by the `PermissionPolicies` feature flag (`MM_FEATUREFLAGS_PERMISSIONPOLICIES`) and require a Mattermost Enterprise Advanced license. See the Mattermost developer documentation for details on [enabling feature flags in a self-hosted deployment](https://developers.mattermost.com/contribute/more-info/server/feature-flags/#self-hosted-and-local-development). Mattermost Cloud customers can request this feature flag be enabled by contacting their Mattermost Account Manager or by [creating a support ticket](https://support.mattermost.com/hc/en-us/requests/new?ticket_form_id=11184911962004).
|
||||
|
||||
</Note>
|
||||
|
||||
### Manage rules
|
||||
|
||||
You can apply changes to existing rules or remove rules at any time using either Simple Mode or Advanced Mode. Select **Save** to save your changes.
|
||||
|
||||
### Assign policies to channels
|
||||
|
||||
From Mattermost v11.8, system-wide policies can be assigned to **both private and public channels**. Select **Add channels** to search for and select the channels you want. You can assign the policy to multiple channels at once, or you can [assign it to individual channels](#define-access-controls-per-channel) later. Select **Save** to save your changes.
|
||||
|
||||
The two channel types behave differently under the same policy:
|
||||
|
||||
- **Private channels** are hard-gated. The policy adds matching users (when auto-add is enabled), removes non-matching members during synchronization, and prevents non-matching users from being added or invited.
|
||||
- **Public channels** are advisory. The policy never removes members and never blocks anyone from joining. With auto-add enabled it automatically adds matching users; with auto-add disabled the channel appears under **Browse Channels \> Recommended channels** for matching users.
|
||||
|
||||
Before saving, you'll be prompted to confirm the impact of the change so you can review how it affects each channel type.
|
||||
|
||||
Default channels (such as Town Square and Off-Topic), shared channels, and group-synced channels remain ineligible — they are excluded from the channel selector.
|
||||
|
||||
<Note>
|
||||
|
||||
Private channels with attribute-based access control policies can't have guest users invited to them. Only users who match the defined attribute criteria can be added to ABAC-controlled private channels, ensuring strict adherence to access control policies. Public channels remain joinable by anyone regardless of the policy.
|
||||
|
||||
</Note>
|
||||
|
||||
### Assign policies to teams
|
||||
|
||||
From Mattermost v11.10, system-wide policies can also be assigned to teams. Go to **System Console \> User Management \> Teams** and open the team you want to configure. In the **Team Management** section, enable **Manage membership with attribute based membership policies** — the **Membership policies** section only appears once this toggle is on. Then link an existing policy and select **Save**.
|
||||
|
||||
Group-synced teams cannot use membership policies, so the toggle is unavailable on them.
|
||||
|
||||
The policy behaves differently depending on the team's privacy mode:
|
||||
|
||||
- **Private teams** — strict enforcement: join is gated, non-qualifying members are removed at sync, and the team is hidden from non-qualifying non-members in Browse Teams.
|
||||
- **Public teams** — advisory: the policy is never a gate. Qualifying non-members see a **Recommended** chip in Browse Teams; anyone can still join freely.
|
||||
|
||||
For a full description of team assignment, custom rules, sync configuration, and end-user surfaces, see [Team membership access policies](/administration-guide/manage/admin/abac-team-membership).
|
||||
|
||||
### Delete policies
|
||||
|
||||
To delete a policy, select the **Delete** button next to the policy you want to remove. Policies that are still assigned to channels cannot be deleted — remove the policy from those channels first.
|
||||
|
||||
Team assignments are not checked before deletion, so unlink the policy from every team that uses it before deleting it. Otherwise those teams keep a reference to a policy that no longer exists.
|
||||
|
||||
## Define access controls per channel
|
||||
|
||||
You can assign an existing access control policy to a private or public channel for more granular control over channel membership. This is useful when you need to apply different rules for different channels.
|
||||
|
||||
1. In the System Console, go to **User Management \> Channels** to select the private or public channel you want to configure, and select **Edit**.
|
||||
2. In the **Channel Management** section, enable the **Enable attribute-based channel access** option.
|
||||
3. Under **Access policy**, select **Link to a policy** to select an existing policy.
|
||||
|
||||
Once a policy is attached, the channel's privacy can no longer be flipped between public and private until the policy is removed — see [Channel-specific access rules](/administration-guide/manage/admin/abac-channel-access-rules#validation-and-safety).
|
||||
|
||||
<Tip>
|
||||
|
||||
You can also assign ABAC rules to a channel directly from a channel's details page in the System Console under **Channel Management** by enabling the **Enable attribute-based channel access** option. Under **Access policy**, select **Link to a policy** to select an existing policy.
|
||||
|
||||
</Tip>
|
||||
|
||||
### Remove channel policies
|
||||
|
||||
Disable the policy for the channel by selecting **Remove Policy**. You can then link the channel to a different policy if preferred.
|
||||
|
||||
## Permission policies
|
||||
|
||||
From Mattermost v11.7, System Admins can define attribute-based **permission policies** that restrict specific user actions in addition to channel membership. Permission policies use the same attribute-based rules as access policies, but they apply to user actions rather than channel access.
|
||||
|
||||
Permission policies can be used to restrict the following actions based on user attributes:
|
||||
|
||||
- **File upload**: Prevent users who don't match the defined attribute rules from uploading file attachments.
|
||||
- **File download**: Prevent users who don't match the defined attribute rules from downloading file attachments.
|
||||
|
||||
When a permission policy applies, users who don't match the configured attribute values can't perform the restricted action. Users may see file attachments as unavailable or redacted in messages they would otherwise have access to. See [Restricted file attachments](/end-user-guide/collaborate/share-files-in-messages#restricted-file-attachments) for the end-user-facing behavior.
|
||||
|
||||
Permission policies follow the same unique-name requirement as access policies: each parent permission policy must have a unique name, and Mattermost surfaces a user-friendly error if a duplicate name is entered.
|
||||
|
||||
## Attribute value masking
|
||||
|
||||
From Mattermost v11.8, when a policy references attribute values that the editing admin doesn't personally hold, those values are hidden in the policy editor. This prevents admins from reading or copying sensitive attribute values they're not authorized to see, while still allowing the policy to enforce access control normally.
|
||||
|
||||
Masking only applies to attributes configured with a `shared_only` or `source_only` access mode. Attributes with a `public` access mode are always visible to all admins. See [Attribute access modes](/administration-guide/manage/admin/user-attributes#attribute-access-modes) for details on how each mode controls value visibility.
|
||||
|
||||
**What you'll see:**
|
||||
|
||||
- Masked values appear as `--------` in the rule editor instead of the raw value.
|
||||
- Rows containing masked values are **read-only** and cannot be modified.
|
||||
- **Test rule** and **Delete** actions are disabled for rules that contain masked values.
|
||||
|
||||
**Enforcement is unaffected:** masking applies to the editing UI only. The underlying rules continue to control channel access and permissions as configured.
|
||||
|
||||
**To edit a masked rule**, ask the policy owner or another System Admin who holds the relevant attribute values to make the change.
|
||||
|
||||
This behavior applies to both the table editor and the CEL editor, and also to Team Admin and Channel Admin policy editors in Team Settings and Channel Settings. Requires Enterprise Advanced license and the `AttributeValueMasking` feature flag.
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
title: "Team-level channel membership policies"
|
||||
sidebar_label: "Team channel policies"
|
||||
---
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
Team Admins can create and manage attribute-based membership policies for private channels within their team, directly from Team Settings, without requiring System Admin involvement. For organization-wide policies managed by System Admins, see [System-wide attribute-based access policies](/administration-guide/manage/admin/abac-system-wide-policies).
|
||||
|
||||
<Note>
|
||||
|
||||
From Mattermost v11.10, Team Settings has four tabs: **Info**, **Access**, **Team Membership**, and **Channel Membership**. This page covers the **Channel Membership** tab — policies that Team Admins configure for *channels* within their team. For team-level membership policies (controlling who can join the team itself), see [Team membership access policies](/administration-guide/manage/admin/abac-team-membership).
|
||||
|
||||
</Note>
|
||||
|
||||
With team-level channel membership policies, Team Admins can:
|
||||
|
||||
- Create policies that apply attribute-based access rules to one or more private channels within their team.
|
||||
- Control which users can join or stay in those channels based on their profile attributes.
|
||||
- Manage auto-sync membership, so channels stay up to date as user attributes change.
|
||||
|
||||
## Use cases
|
||||
|
||||
- **Team-wide project access**: Restrict all private project channels to members with a specific project attribute.
|
||||
- **Department isolation**: Ensure only users from a specific department can join the team's private channels.
|
||||
- **Clearance tiers**: Apply clearance-level requirements consistently across multiple channels in the team without System Admin involvement for each change.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Attribute-Based Access Control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) must be enabled by a System Admin in **System Console \> System Attributes \> Attribute-Based Access**.
|
||||
- You need Team Admin permissions for the team. The `manage_team_access_rules` permission is included in the Team Admin role by default.
|
||||
- Team-level membership policies apply only to private channels within the team.
|
||||
|
||||
### Access Team Settings
|
||||
|
||||
1. Select the team name in the sidebar to open the team menu.
|
||||
2. Select **Team Settings**.
|
||||
3. Navigate to the **Channel Membership** tab (the fourth tab in Team Settings). This tab is only visible when ABAC is enabled system-wide and you have Team Admin permissions.
|
||||
|
||||
<Note>
|
||||
|
||||
System Admins also have access to the **Channel Membership** tab in Team Settings and see the same policies as Team Admins.
|
||||
|
||||
</Note>
|
||||
|
||||
## Manage membership policies
|
||||
|
||||
The **Channel Membership** tab shows policies scoped to the team. Each policy displays its name and the number of private channels it applies to.
|
||||
|
||||
Team Admins only see policies whose access rules their own user attributes satisfy. If a policy has rules that exclude the Team Admin's attributes (for example, a policy requiring `Department=Engineering` and the Team Admin has `Department=Finance`), that policy will not appear in their list. This is a self-inclusion safety mechanism to prevent admins from being locked out of policies they manage.
|
||||
|
||||
### Create a policy
|
||||
|
||||
1. In the **Channel Membership** tab, select **Add policy**.
|
||||
2. Enter a unique policy name.
|
||||
3. Define access rules under **Access rules**:
|
||||
- Select **Add attribute** to add a condition.
|
||||
- For each condition, choose the user attribute, the matching operator (**Is**, **Is not**, **In**, **Contains**), and the required value.
|
||||
- Add multiple conditions as needed. All conditions are combined with a logical AND, so users must satisfy all of them.
|
||||
4. Assign channels under **Assigned channels**:
|
||||
- Select **Add channels** to search for and select private channels within the team.
|
||||
- Channels already assigned to this policy are excluded from the search results to prevent duplicates.
|
||||
- A channel can be assigned to multiple policies simultaneously; all policies are enforced independently.
|
||||
5. Optionally, toggle **Auto-add members** per channel to control whether users matching the rules are automatically added to that channel.
|
||||
6. Select **Save** to apply the policy.
|
||||
|
||||
<Important>
|
||||
|
||||
Self-exclusion prevention is enforced during save. If your defined rules would exclude your own user account, Mattermost will block the save and display an error. Adjust your rules to include your own attributes before saving.
|
||||
|
||||
</Important>
|
||||
|
||||
### Edit a policy
|
||||
|
||||
Select a policy row in the list, or use the three-dot menu and select **Edit**, to open the policy editor. You can update the policy name, access rules, and channel assignments. Select **Save** to apply changes.
|
||||
|
||||
When saving changes that affect existing channel membership, a confirmation dialog shows how many users will be added or removed. Confirm to proceed.
|
||||
|
||||
### Delete a policy
|
||||
|
||||
You can only delete a policy that has no channels assigned to it. To delete a policy:
|
||||
|
||||
1. Open the policy editor and remove all assigned channels using the **Remove** link next to each channel.
|
||||
2. Once all channels are removed, select **Delete policy** at the bottom of the editor.
|
||||
3. Confirm the deletion.
|
||||
|
||||
### Auto-add members
|
||||
|
||||
Each channel assigned to a policy has an independent **Auto-add members** toggle:
|
||||
|
||||
- **Enabled**: Users matching the policy rules are automatically added to the channel. If a user loses the required attributes and later regains them, they are automatically re-added.
|
||||
- **Disabled** (default): The policy enforces rules as a gate, removing users who no longer qualify, but does not automatically add new qualifying users.
|
||||
|
||||
Regardless of this setting, users who no longer satisfy the access rules are always removed during the next synchronization.
|
||||
|
||||
<Note>
|
||||
|
||||
If a system-wide policy has auto-sync enabled for a channel, Team Admins cannot disable it for that channel. If a system-wide policy has auto-sync disabled, Team Admins can choose to enable it.
|
||||
|
||||
</Note>
|
||||
|
||||
## Policy inheritance and combination
|
||||
|
||||
When both a system-wide policy and a team-level policy apply to the same channel, both must be satisfied. Team-level policies are **additive** and cannot relax or override restrictions set by System Admins.
|
||||
|
||||
- System-wide policies are managed in the System Console.
|
||||
- Team-level policies are managed in Team Settings.
|
||||
- Users must meet the rules of all applicable policies to access the channel.
|
||||
|
||||
### Cross-team policies
|
||||
|
||||
A policy that has private channels from more than one team is considered a cross-team policy. Cross-team policies are not visible in any team's **Channel Membership** tab — they are managed exclusively through the System Console.
|
||||
|
||||
If a System Admin adds a channel from another team to a policy that was previously scoped to one team, that policy will no longer appear in any team's **Channel Membership** tab.
|
||||
|
||||
## Synchronization
|
||||
|
||||
When you save a policy or modify channel assignments, Mattermost creates a membership synchronization job. Changes are applied as soon as the job completes. Synchronization also runs automatically on a schedule to handle attribute changes from external systems such as LDAP or SAML. The interval is set by `AccessControlSettings.SyncJobIntervalSeconds` and defaults to 3600 seconds (60 minutes). User attributes used for access control evaluation are refreshed on a separate schedule controlled by `AccessControlSettings.AttributeRefreshIntervalSeconds`, which defaults to 30 seconds.
|
||||
|
||||
## Troubleshooting and FAQs
|
||||
|
||||
### Why can't I see the Channel Membership tab in Team Settings?
|
||||
|
||||
The **Channel Membership** tab is only visible when:
|
||||
|
||||
- You have Team Admin permissions.
|
||||
- ABAC is enabled system-wide by a System Admin in **System Console \> System Attributes \> Attribute-Based Access**.
|
||||
|
||||
### Why can't I see a policy that I know exists?
|
||||
|
||||
There are two reasons a policy may not appear in your **Channel Membership** tab:
|
||||
|
||||
- **Cross-team policy**: The policy includes private channels from more than one team. Cross-team policies are not visible in Team Settings for anyone and must be managed through the System Console.
|
||||
- **Self-inclusion filter**: Your own user attributes do not satisfy the policy's access rules. For example, if a policy requires `Department=Engineering` and your profile has `Department=Finance`, you will not see that policy. A System Admin or another Team Admin whose attributes do satisfy the rules would need to manage it instead.
|
||||
|
||||
### What happens when I save rules that would exclude me?
|
||||
|
||||
Mattermost validates your access rules against your own user attributes before saving. If the rules would remove you from any assigned channel, the save is blocked and an error is shown. Adjust the rules to include your own attributes, or reset them using the **Undo** option in the save panel.
|
||||
|
||||
### Can I assign a channel to more than one team-level policy?
|
||||
|
||||
Yes. A private channel can be assigned to multiple membership policies. Each policy's rules are applied independently, and users must satisfy all of them to access the channel.
|
||||
|
||||
### Can Team Admins override system-wide policies?
|
||||
|
||||
No. Team-level policies are always additive. Users must satisfy both the system-wide policy and the team-level policy to access a channel. Team Admins cannot weaken or bypass restrictions set by System Admins.
|
||||
|
||||
### How are membership changes communicated to users?
|
||||
|
||||
Users receive standard Mattermost notifications when they are removed from or added to channels due to policy changes, consistent with other membership change notifications.
|
||||
@@ -0,0 +1,448 @@
|
||||
---
|
||||
title: "Team membership access policies"
|
||||
sidebar_label: "Team membership policies"
|
||||
---
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
From Mattermost v11.10, system admins and team admins can apply attribute-based access control (ABAC) directly to teams — controlling who can join a team based on user profile attributes. This extends the existing ABAC channel membership system to the team boundary, closing the "hallway access" gap where users who fail channel policies could still see the team, its member list, and its channel structure.
|
||||
|
||||
Team membership ABAC uses the same policies and attribute rules as channel ABAC, but behaves differently depending on whether the team is public or private:
|
||||
|
||||
- **Public teams (advisory mode)**: The policy never blocks access. Anyone can still join freely. Qualifying users who are not yet members see a **Recommended** chip in Browse Teams. Sync can auto-add qualifying users when enabled but never removes anyone.
|
||||
- **Private teams (strict mode)**: The policy gates directory visibility, join evaluation, and membership at sync. Non-qualifying users cannot find or join the team. Non-qualifying members are removed at the next sync.
|
||||
|
||||
<Note>
|
||||
|
||||
**Upgrade notice:** The Access tab in Team Settings has a new UI from Mattermost v11.10 that affects **every team on every deployment** — whether or not ABAC is licensed or enabled. The old "Allow any user to join" checkbox has been replaced by **Public Team / Private Team** selection cards. See [Access tab: Public/Private team cards](#access-tab-publicprivate-team-cards) for details.
|
||||
|
||||
</Note>
|
||||
|
||||
## Access tab: Public/Private team cards
|
||||
|
||||
<Important>
|
||||
|
||||
This change affects **all Mattermost teams on all deployments**, regardless of whether ABAC is enabled or whether your organization has an Enterprise Advanced license. Any team admin who opens **Team Settings \> Access** after upgrading will see the new UI. The exception is teams managed by LDAP/AD group sync, which show a static message in place of the cards — see [Switching modes](#switching-modes).
|
||||
|
||||
</Important>
|
||||
|
||||
**What changed:** The "Allow any user to join" checkbox has been permanently replaced by two selection cards:
|
||||
|
||||
- **Public Team** — anyone on the server can find and join.
|
||||
- **Private Team** — only invited members can join.
|
||||
|
||||
**Why the change was made:** The cards make a team's public-vs-private state explicit and unambiguous, which is what team ABAC enforcement depends on to decide between advisory and strict mode.
|
||||
|
||||
**Behavior without ABAC:** Functionally identical to the old checkbox. Public Team = "Allow any user to join" was ON. Private Team = it was OFF. No other behavior changes for teams that have no membership policy.
|
||||
|
||||
**Behavior with ABAC:** The cards drive the enforcement mode — public teams get advisory ABAC, private teams get strict ABAC. Mode changes on policy-governed teams may trigger a confirmation modal (see below).
|
||||
|
||||
**Default on new teams:** New teams are Private by default, so any policy assigned before explicitly choosing a mode activates strict enforcement. Teams are always protected by default; advisory mode requires explicitly selecting **Public Team**.
|
||||
|
||||
### Switching modes
|
||||
|
||||
**Private → Public:** Relaxes enforcement. Saves directly with no confirmation modal. If a policy is applied, the team immediately transitions to advisory mode: no existing members are removed.
|
||||
|
||||
**Public → Private:** If team ABAC is enabled (Enterprise Advanced license and **Enable Attribute-Based Access Control**) and the team has a membership policy assigned, clicking **Private Team** opens a confirmation modal before saving:
|
||||
|
||||
- Title: **"Switch to Private Team?"**
|
||||
- Body shows how many current members do not meet the policy criteria and will be removed at the next sync. If all current members meet the criteria, the modal says no one will be removed. If no count is available, a generic warning is shown instead.
|
||||
- **Cancel** — closes the modal, no changes made.
|
||||
- **Switch to Private** — saves the change and immediately creates a team sync job to enforce strict mode.
|
||||
|
||||
If the admin making the switch does not meet the policy criteria, a **"Cannot switch to Private Team"** error modal appears instead and the switch is blocked, since strict mode would remove them from the team. Update the rules to include yourself, or ask another admin to make the switch.
|
||||
|
||||
If no policy is assigned, switching Public → Private saves directly with no modal.
|
||||
|
||||
Other Access tab fields (Invite Code and Allowed Email Domain) are unaffected by this change. On teams managed by LDAP/AD group sync, the Access tab shows a static "Members of this team are added and removed by linked groups" message instead of the cards.
|
||||
|
||||
## Advisory and strict enforcement
|
||||
|
||||
Whether a policy is enforced strictly or treated as advisory depends only on whether the team is public or private. The table below summarizes how each combination behaves.
|
||||
|
||||
| Team | ABAC policy? | Join gate | Browse Teams | Sync removal | Recommended tag |
|
||||
|----|----|----|----|----|----|
|
||||
| Public | No | Open | Visible to all | N/A | No |
|
||||
| Public | Yes — **Advisory** | Open (no gate) | Visible to all | Skipped | Yes (qualifying non-members) |
|
||||
| Private | No | Invite-only | Members only | N/A | No |
|
||||
| Private | Yes — **Strict** | Denied for non-qualifying users | Hidden from non-qualifying non-members | Non-qualifiers removed | No |
|
||||
|
||||
<Note>
|
||||
|
||||
Auto-add is the only behavior that applies to **both** advisory and strict mode. When enabled, sync adds qualifying non-members regardless of whether the team is public or private.
|
||||
|
||||
</Note>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before configuring team membership policies:
|
||||
|
||||
1. [Configure user attributes](/administration-guide/manage/admin/user-attributes) in the System Console.
|
||||
2. Go to **System Console \> System Attributes \> Attribute-Based Access** and enable **Enable Attribute-Based Access Control**.
|
||||
3. For Team Admins configuring rules: the `manage_team_access_rules` permission is required. This permission is included in the Team Admin role by default.
|
||||
|
||||
Team membership ABAC is also gated by the `TeamMembershipAccessControl` feature flag, which is **enabled by default** from Mattermost v11.10. Disabling it turns off team enforcement without affecting channel ABAC. See the Mattermost developer documentation for details on [feature flags in a self-hosted deployment](https://developers.mattermost.com/contribute/more-info/server/feature-flags/#self-hosted-and-local-development).
|
||||
|
||||
**What changes when team membership ABAC is off:**
|
||||
|
||||
| Surface | Team membership ABAC ON | Team membership ABAC OFF |
|
||||
|----|----|----|
|
||||
| Join gate (private teams) | Enforced — non-qualifying users denied | Not evaluated — private teams stay invite-only, as before |
|
||||
| Browse Teams filter | Private+ABAC teams hidden from non-qualifying users | No attribute filtering — standard privacy rules apply |
|
||||
| Team Membership tab (Team Settings) | Visible to Team Admins and System Admins | Hidden — tab does not appear |
|
||||
| System Console per-team ABAC controls | Policy assignment + custom rules panel visible | Hidden |
|
||||
| Recommended tag | Shown to qualifying users on public+ABAC teams | Not shown |
|
||||
| Sync job — removal pass | Removes non-qualifiers from private+ABAC teams | No team sync jobs run |
|
||||
| Invite modal filtering | Filters on private+ABAC teams | All users shown, as before |
|
||||
| Public/Private cards (Access tab) | **Visible** — not gated | **Still visible** — rendered on every team except group-synced ones |
|
||||
| Channel ABAC | Unaffected | Unaffected |
|
||||
|
||||
## System Admin configuration
|
||||
|
||||
### Assign a membership policy to a team
|
||||
|
||||
System Admins assign existing system-wide membership policies to teams via the per-team System Console page.
|
||||
|
||||
1. Go to **System Console \> User Management \> Teams** and open the team you want to configure.
|
||||
2. In the **Team Management** section, enable **Manage membership with attribute based membership policies**. The **Membership policies** and **Team-specific membership rules** sections appear only once this toggle is on. The toggle is unavailable on group-synced teams, and becomes read-only once a policy is linked.
|
||||
3. In the **Membership policies** section, select **Link to a policy** and choose an existing policy from the picker.
|
||||
4. Select **Save**.
|
||||
|
||||
Before saving, an **Apply membership policy** confirmation modal appears. It shows only the outcomes that apply to this team:
|
||||
|
||||
- The number of current members who do not meet the policy criteria and will be removed at the next sync — private teams only, and only when that number is above zero.
|
||||
- The number of qualifying users who will be added at the next sync — only when auto-add is enabled and that number is above zero.
|
||||
- An **empty-team warning** if the team is private and no user matches the policy ("Saving may result in an empty private team").
|
||||
- A confirmation prompt: "Are you sure you want to apply the membership policy?"
|
||||
|
||||
**To remove a policy:** Select the trash icon next to the policy row and confirm in the **"Remove this team from policy"** modal, then **Save**. Existing members are retained and the team returns to its standard access mode at the next sync.
|
||||
|
||||
**Policy list team counts:** The **Membership Policies** list page shows the count of channels and teams each policy is applied to — for example, `2 channels, 1 team`. A zero side is omitted (so `1 team` not `0 channels, 1 team`).
|
||||
|
||||
### Configure team-specific membership rules
|
||||
|
||||
In addition to a system-wide parent policy, System Admins can define team-specific rules directly on the per-team System Console page.
|
||||
|
||||
1. Go to **System Console \> User Management \> Teams** and open the team.
|
||||
|
||||
2. Enable the **Manage membership with attribute based membership policies** switch.
|
||||
|
||||
3. Scroll to the **Team-specific membership rules** panel.
|
||||
|
||||
4. Select **Add attribute** to add a condition. For each condition, choose:
|
||||
|
||||
- **Attribute**: The user profile attribute to evaluate.
|
||||
- **Operator**: How the attribute must match. Options: **Is**, **Is not**, **In**, **Starts with**, **Ends with**, **Contains**. For ranked attributes: **Is exactly**, **Is at least**, **Is greater than**, **Is at most**, **Is less than**.
|
||||
- **Value**: The required attribute value.
|
||||
|
||||
All conditions are combined with a logical AND — users must satisfy all of them.
|
||||
|
||||
5. Optionally, check **Auto-add members based on access rules**. This checkbox is enabled once the team has at least one rule **or** a linked parent policy. There is only one auto-add setting per team — it is not configured per linked policy.
|
||||
|
||||
6. Select **Save**. The **Apply membership policy** modal shows the impact counts before changes are applied.
|
||||
|
||||
<Important>
|
||||
|
||||
Saving rules always triggers an immediate team sync — **even when auto-add is off**. On private teams, this immediately enforces the rules by removing members who no longer qualify. Confirm the impact in the save modal before proceeding.
|
||||
|
||||
</Important>
|
||||
|
||||
<Note>
|
||||
|
||||
Team-specific rules compose additively with any parent policy assigned to the team. A user must satisfy **both** the parent policy and the team-specific rules. Team-specific rules cannot weaken or bypass the parent.
|
||||
|
||||
</Note>
|
||||
|
||||
### Sync status footer (System Console)
|
||||
|
||||
A sync status footer is rendered at the bottom of the **Team-specific membership rules** panel — scroll down within the panel to find it.
|
||||
|
||||
- **"Never synced."** with a **Sync now** link — no sync has run for this team yet.
|
||||
- **"Last synced N minutes ago."** with a **Sync now** link — after a prior sync. Older syncs are reported in hours or days.
|
||||
- Clicking **Sync now** changes the link to **"Syncing…"** with a spinner while the job is in-flight, then updates to **"Last synced just now."** on completion.
|
||||
|
||||
### Monitor membership sync
|
||||
|
||||
System Admins can review the results of team sync jobs from the System Console.
|
||||
|
||||
1. Go to **System Console \> System Attributes \> Membership Policies** and scroll to the **Membership Sync Jobs** panel.
|
||||
2. Select a job row to open the **Sync Job Details** modal.
|
||||
3. Select the **Teams** tab.
|
||||
|
||||
The Teams tab shows per-team rows with:
|
||||
|
||||
- A `+N added / −N removed` summary for each governed team.
|
||||
- A **mass-removal warning indicator** on any team row where more than 50% of members would be removed. This is a warning only — the job is not blocked.
|
||||
- An expandable per-team user drill-down showing which users were added and removed.
|
||||
|
||||
<Note>
|
||||
|
||||
The Teams tab appears only when viewing a team sync job directly, or a channel sync job that was chained from a team sync. The system console section heading was renamed from "Channel access control sync jobs" to **"Membership Sync Jobs"** to reflect both job types.
|
||||
|
||||
</Note>
|
||||
|
||||
<Tip>
|
||||
|
||||
The **Run Channel Sync** button on the Membership Policies page runs a channel sync only, not a team sync. To trigger a team sync, use the **Sync now** link on the per-team System Console page or in Team Settings \> Team Membership tab.
|
||||
|
||||
</Tip>
|
||||
|
||||
## Team Admin configuration
|
||||
|
||||
### Team Membership tab
|
||||
|
||||
From Mattermost v11.10, Team Settings has four tabs: **Info**, **Access**, **Team Membership**, and **Channel Membership**.
|
||||
|
||||
<Note>
|
||||
|
||||
The fourth tab was previously labeled **Membership Policies**. It is now labeled **Channel Membership** and covers channel-scope policies only. The new **Team Membership** tab (the third tab) is for policies that control who can join the team itself.
|
||||
|
||||
</Note>
|
||||
|
||||
The **Team Membership** tab lets Team Admins view the system policy applied to their team and configure team-specific custom rules — without requiring System Admin involvement for every change.
|
||||
|
||||
The tab is visible only when:
|
||||
|
||||
- **Enable Attribute-Based Access Control** is on.
|
||||
- The `TeamMembershipAccessControl` feature flag is on (enabled by default).
|
||||
- The user has the `manage_team_access_rules` permission (Team Admin or System Admin).
|
||||
|
||||
To open Team Settings: select the team name in the sidebar → **Team Settings** → **Team Membership** tab.
|
||||
|
||||
### System policy indicator
|
||||
|
||||
When a system-level policy is applied to the team by a System Admin, a non-dismissible information banner appears at the top of the Team Membership tab, showing the name of the applied policy. The banner is absent when no parent policy exists.
|
||||
|
||||
### Configure custom rules
|
||||
|
||||
Team Admins can add attribute rules that apply on top of any system policy. These rules use the same Basic Mode editor as channel rules.
|
||||
|
||||
1. Select **Add attribute**.
|
||||
2. Choose the attribute, operator, and value for each condition.
|
||||
3. Add additional rules as needed. All rules are AND-combined.
|
||||
4. Select **Save** to open the save confirmation modal.
|
||||
|
||||
Clearing every rule and saving opens a **"Remove membership rules?"** modal instead. Confirming removes the team's attribute enforcement; current members keep their access.
|
||||
|
||||
Available operators: **Is**, **Is not**, **In**, **Starts with**, **Ends with**, **Contains**. For ranked attributes: **Is exactly**, **Is at least**, **Is greater than**, **Is at most**, **Is less than**.
|
||||
|
||||
<Important>
|
||||
|
||||
Saving rules always triggers an immediate team sync — **even when auto-add is off**. On private teams, this removes members who no longer satisfy the rules. Review the impact counts in the confirmation modal before saving.
|
||||
|
||||
</Important>
|
||||
|
||||
<Note>
|
||||
|
||||
Team Settings rules are Basic Mode only. Advanced CEL expressions are not available here. For complex rules with nested logic or mixed operators, a System Admin must create a system-wide parent policy in the System Console.
|
||||
|
||||
</Note>
|
||||
|
||||
### Auto-add members
|
||||
|
||||
The **Auto-add members based on access rules** checkbox controls whether the sync job automatically adds qualifying non-members to the team.
|
||||
|
||||
- This checkbox is enabled only when at least one rule exists, **or** when a system-level policy is applied.
|
||||
- Checking it and saving triggers an immediate backfill scan — qualifying non-members are added right away.
|
||||
- Subsequent syncs continue to add newly qualifying users.
|
||||
- Turning auto-add **off** does not remove any members — it is additive only. Toggling auto-add off also does **not** trigger a sync job.
|
||||
|
||||
### Test access rule
|
||||
|
||||
Select **Test access rule** to open a preview modal listing users who match the current rules, before saving. This lets you verify your intended scope without applying the rules.
|
||||
|
||||
<Note>
|
||||
|
||||
If the current rules would exclude the editing Team Admin, the **Test access rule** button is disabled with an explanatory tooltip rather than returning results.
|
||||
|
||||
</Note>
|
||||
|
||||
### Save confirmation and safety
|
||||
|
||||
Selecting **Save** opens a confirmation modal before changes are applied. What it shows depends on the team's mode:
|
||||
|
||||
**Private teams (strict):**
|
||||
|
||||
- The number of users who match the current rules and will have access.
|
||||
- The number of current members who do not match the rules and may be affected — shown only when that number is above zero.
|
||||
|
||||
**Public teams (advisory):**
|
||||
|
||||
- A note that the rules are advisory: no one is blocked or removed.
|
||||
- The number of users who match the current rules.
|
||||
|
||||
The counts are evaluated against the team's rules combined with any parent policy.
|
||||
|
||||
**Empty-team warning**: For private teams, if no user matches the rules, the modal displays a highlighted warning. Save is not blocked, but the team will be empty until sync runs.
|
||||
|
||||
**Self-exclusion hard block**: On private teams, if the rules would exclude the editing Team Admin, a separate error modal appears *before* the confirmation modal and prevents saving. Select **Back to editing** to adjust the rules. Public teams are exempt — advisory mode never removes anyone.
|
||||
|
||||
<Note>
|
||||
|
||||
By design, the self-exclusion block evaluates only the admin's own team rules. A system-level parent policy that excludes the admin is a System Admin decision and is not blocked here.
|
||||
|
||||
</Note>
|
||||
|
||||
### Sync status footer (Team Settings)
|
||||
|
||||
Below the auto-add section, a sync status footer appears whenever the team has at least one rule or a parent policy applied:
|
||||
|
||||
- **"Never synced."** + **Sync now** link.
|
||||
- **"Last synced N minutes ago."** + **Sync now** link.
|
||||
- After clicking **Sync now**: **"Syncing…"** with spinner → **"Last synced just now."** on completion.
|
||||
|
||||
The footer is not shown in the empty state (no rules and no parent policy).
|
||||
|
||||
Clicking **Sync now** creates a team sync job scoped to this team only.
|
||||
|
||||
## End-user experience
|
||||
|
||||
### Browse Teams
|
||||
|
||||
The Browse Teams directory respects team ABAC enforcement:
|
||||
|
||||
**Private + ABAC teams (strict mode):**
|
||||
|
||||
- Non-qualifying users who are not already members do not see the team in Browse Teams at all. The team is simply absent — not greyed out or locked.
|
||||
- Qualifying users and existing members see the team normally.
|
||||
|
||||
**Public + ABAC teams (advisory mode):**
|
||||
|
||||
- All users see the team.
|
||||
- Qualifying users who are not yet members see a **Recommended** chip (lightbulb outline icon) next to the team name.
|
||||
- Users who are already members, or who do not qualify for the policy, do not see the chip.
|
||||
|
||||
**Teams without a policy:**
|
||||
|
||||
- Behave exactly as before — no filtering, no chip.
|
||||
|
||||
### Invite People modal
|
||||
|
||||
The Invite People modal adapts to the team's enforcement mode:
|
||||
|
||||
**Private + ABAC team (strict mode):**
|
||||
|
||||
- Only users who qualify for the team's membership policy appear in search results. Non-qualifying users are filtered out before any results are shown.
|
||||
- A notice titled **"Team access is restricted by user attributes"** informs admins: *"Only users who meet the membership requirements can be added to this team."*
|
||||
- The notice lists the policy's attribute value tags (for example, "Department: Engineering").
|
||||
- The invite link warns: *"People who use this link must meet the membership requirements to join."*
|
||||
|
||||
**Public + ABAC team (advisory mode):**
|
||||
|
||||
- All users appear in search results — there is no filtering because advisory mode never blocks access.
|
||||
- A notice titled **"This team has membership requirements"** is still shown, explaining that users who do not meet them can still join but will not be automatically added.
|
||||
- The invite link warns: *"People who use this link can join even if they do not meet the membership requirements, but will not be automatically added."*
|
||||
|
||||
**Team without a policy:**
|
||||
|
||||
- No change from previous behavior — all users appear, no notice shown.
|
||||
|
||||
### Add Members flow (admin)
|
||||
|
||||
When a System Admin or Team Admin uses the **Add Members** admin flow on a private + ABAC team, non-qualifying users are blocked at selection time rather than at submission:
|
||||
|
||||
- Non-qualifying candidates show an inline **"Does not meet membership requirements"** indicator on their row and cannot be selected, including by keyboard.
|
||||
- Only qualifying users can be added to the selection, so the add never fails partway through.
|
||||
|
||||
On a public + ABAC team (advisory mode), all users can be added without restriction.
|
||||
|
||||
### Team Members modal
|
||||
|
||||
When a team has an active membership policy, a notice banner appears at the top of the Team Members modal:
|
||||
|
||||
- On private teams: **"Team access is restricted by user attributes"** — only people who meet the membership requirements can be members.
|
||||
- On public teams: **"This team has membership requirements"** — people who do not meet them can still join, but will not be automatically added.
|
||||
- The banner lists the policy's attribute value tags (for example, "Department: Engineering"). Values the viewer is not permitted to see are stripped server-side, so a non-holder sees only the notice.
|
||||
|
||||
### Membership notifications
|
||||
|
||||
**Removal notification:** When the sync job removes a non-qualifying member from a private team, that user receives a direct message from the System Bot identifying the team they were removed from. The message does not include policy names, attribute values, or CEL expressions.
|
||||
|
||||
**Auto-add notification:** When the sync job auto-adds a qualifying user to a team, that user receives a direct message from the System Bot identifying the team they were added to. Removal and auto-add notifications use different icons so users can distinguish them at a glance.
|
||||
|
||||
## Policy inheritance and composition
|
||||
|
||||
When a parent (system-level) policy and custom team rules both apply:
|
||||
|
||||
- The parent policy is shown in a non-dismissible info banner at the top of the Team Membership tab (read-only).
|
||||
- The user must satisfy **both** the parent policy and the custom team rules to be admitted.
|
||||
- Custom rules can only add restrictions — they cannot weaken or bypass the parent policy.
|
||||
- Deleting a parent policy does not unlink it from the team or delete the team's own rules. Unlink the policy from each team before deleting it.
|
||||
|
||||
## Sync behavior
|
||||
|
||||
A team sync batch runs in the following order:
|
||||
|
||||
1. **Evaluate team membership rules** for all teams that have a policy assigned.
|
||||
2. **Removal pass** (private + ABAC teams only): remove members who no longer qualify. Each removal triggers a channel cascade — the user is removed from all channels within the team. Each removal notifies the user by system-bot DM and is recorded in the audit log. Ordinary, non-ABAC team leaves are not recorded as policy-driven cascades.
|
||||
3. **Auto-add pass** (any mode, when auto-add is enabled): add qualifying non-members to the team. Each addition emits a system-bot DM.
|
||||
4. **Channel membership sync** (chained): evaluate and apply channel policy changes. Deduped against any already-pending or in-progress channel sync job.
|
||||
|
||||
**Mass-removal guardrail**: If a sync pass would remove more than 50% of a team's current members, the job sets a warning flag visible in the Sync Job Details \> Teams tab. The job is not blocked — all removals proceed — but the warning is surfaced for admin review.
|
||||
|
||||
Team sync also runs automatically on a schedule to handle attribute changes propagated from LDAP or SAML. The interval is set by `AccessControlSettings.SyncJobIntervalSeconds` and defaults to 3600 seconds (60 minutes). The minimum accepted value is 60 seconds, and a change requires a server restart to take effect. The same interval governs channel membership sync. User attributes used for access control evaluation are refreshed on a separate schedule controlled by `AccessControlSettings.AttributeRefreshIntervalSeconds`, which defaults to 30 seconds. Set this value to 0 to disable periodic attribute refresh.
|
||||
|
||||
## Mutual exclusivity with group sync
|
||||
|
||||
A team managed by LDAP/AD group synchronization cannot have an ABAC membership policy assigned. Attempting to assign a policy to a group-synced team returns an error.
|
||||
|
||||
You must choose one membership control mechanism per team: group sync or ABAC.
|
||||
|
||||
## Troubleshooting and FAQs
|
||||
|
||||
### Why did the Access tab change and where did the "Allow any user to join" checkbox go?
|
||||
|
||||
From Mattermost v11.10, the "Allow any user to join" checkbox has been permanently replaced by **Public Team** and **Private Team** selection cards on the Access tab. This change applies to all teams on all deployments regardless of ABAC. The cards are functionally equivalent to the old checkbox — Public Team is the same as having the checkbox enabled, Private Team is the same as having it disabled.
|
||||
|
||||
### Why is the Team Membership tab not visible in Team Settings?
|
||||
|
||||
The tab requires all of the following:
|
||||
|
||||
- **Enable Attribute-Based Access Control** is ON in System Console \> System Attributes \> Attribute-Based Access.
|
||||
- The `TeamMembershipAccessControl` feature flag is ON (enabled by default).
|
||||
- The user has the `manage_team_access_rules` permission (Team Admin or System Admin).
|
||||
|
||||
If all three conditions are met but the tab is still missing, confirm the feature flag has not been disabled by checking **System Console \> Experimental \> Feature Flags** or the server configuration.
|
||||
|
||||
### Why are private ABAC teams not appearing in Browse Teams for some users?
|
||||
|
||||
This is intended behavior. When a private team has an ABAC policy and a user does not satisfy that policy, the team is completely hidden from them in Browse Teams and search results. They will not see an error or a locked entry — the team simply does not appear. Qualifying users see the team normally.
|
||||
|
||||
### Can I use advanced CEL expressions in Team Settings?
|
||||
|
||||
No. The Team Membership tab uses Basic Mode only — the same simple attribute editor available in Channel Settings. For rules that require nested logic, mixed `&&` / `||` operators, or grouping, a System Admin must create a system-wide parent policy using the CEL editor in the System Console.
|
||||
|
||||
### Can a group-synced team use ABAC?
|
||||
|
||||
No. Group sync and ABAC are mutually exclusive on a per-team basis. If a team is group-constrained, assigning an ABAC policy returns an error. You must remove the group sync configuration before applying an ABAC policy, or vice versa.
|
||||
|
||||
### How quickly are membership changes applied?
|
||||
|
||||
Saving rules in Team Settings or the System Console triggers an immediate team sync — **including when auto-add is off**, because enforcement (removal on private teams) runs regardless of the auto-add setting. Changes are applied as soon as the sync completes. A scheduled sync also runs on the interval set by `AccessControlSettings.SyncJobIntervalSeconds` (60 minutes by default) to process attribute changes from LDAP or SAML. User attributes used for access control evaluation are refreshed on the interval set by `AccessControlSettings.AttributeRefreshIntervalSeconds` (30 seconds by default).
|
||||
|
||||
### Does System Admin role bypass team ABAC enforcement?
|
||||
|
||||
No. All roles — including System Admin — are subject to team ABAC policy evaluation. A System Admin who does not satisfy a private team's policy cannot join that team as a member through the standard UI, though they can still access the team's configuration in the System Console and make changes.
|
||||
|
||||
### What happens when I switch a team from public to private while a policy is assigned?
|
||||
|
||||
If team ABAC is enabled (Enterprise Advanced license and **Enable Attribute-Based Access Control**) and a policy is assigned to the team, clicking **Private Team** opens a confirmation modal — **"Switch to Private Team?"** — showing how many current members do not meet the policy criteria. Confirming the switch saves the change and triggers an immediate sync to enforce strict mode. Members who don't qualify are removed at that sync.
|
||||
|
||||
If the admin making the switch does not meet the criteria themselves, the switch is blocked with a **"Cannot switch to Private Team"** modal.
|
||||
|
||||
If no policy is assigned, the switch saves directly with no confirmation.
|
||||
|
||||
### What happens when I switch a team from private to public while a policy is assigned?
|
||||
|
||||
Switching from Private to Public always saves directly with no confirmation modal. The team immediately transitions to advisory mode: existing members (including non-qualifying ones) are retained, and no removals occur. The policy continues to drive the Recommended tag and optional auto-add for qualifying users.
|
||||
|
||||
### Can I add a non-qualifying user to a private ABAC team?
|
||||
|
||||
No. The enforcement gate applies to all add paths: the Invite People modal (non-qualifying users are filtered from search results entirely), the Add Members admin flow (non-qualifying users cannot be selected), and direct API calls. The error message is generic and does not expose policy names or attribute details.
|
||||
|
||||
### How does ABAC interact with email-domain restrictions?
|
||||
|
||||
Email-domain restrictions (configured on the Access tab) and ABAC rules (Team Membership tab) apply independently, and a user must satisfy both to join the team. The domain check runs first, so a user rejected on domain grounds never reaches policy evaluation. The two settings are not cross-validated at configuration time, so review them together when debugging unexpected access denials.
|
||||
|
||||
### Why does saving rules trigger a sync even when auto-add is off?
|
||||
|
||||
Auto-add controls only the **add pass** (whether sync adds qualifying non-members). The **enforcement pass** (removing non-qualifying members from private teams) runs whenever rules exist, regardless of auto-add. This ensures that newly saved or changed rules take effect immediately rather than waiting up to 60 minutes for the next scheduled sync.
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: "Attribute-Based Access Control"
|
||||
---
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
From Mattermost v10.9, system admins in large or complex organizations who require Zero Trust Security when handling with sensitive information can prevent unauthorized access through attribute-based access controls.
|
||||
|
||||
Enforcing strict access controls based on user attributes eliminates manual role adjustment processes that can lead to security risks, inefficiencies, or inappropriate access, while maintaining security and compliance by ensuring that only authorized users can access specific private Mattermost channels and teams. On public channels and teams, policies are advisory rather than a gate — see the advisory and strict behaviour described below.
|
||||
|
||||
Attribute-based access control (ABAC) can be used with the following policy types:
|
||||
|
||||
- **System-wide access policies** (managed by System Admins): Centralized policies created in the System Console that can be applied across multiple channels and teams. See [System-wide attribute-based access policies](/administration-guide/manage/admin/abac-system-wide-policies).
|
||||
- **Permission policies** (managed by System Admins): Attribute-based restrictions on user actions such as file upload and file download. See [Permission policies](/administration-guide/manage/admin/abac-system-wide-policies#permission-policies).
|
||||
- **Team membership policies** (managed by System Admins and Team Admins): Attribute-based rules that control who can join a team. On private teams, rules gate directory visibility, join evaluation, and removal at sync (strict mode). On public teams, rules drive a "Recommended" tag and optional auto-add without restricting access (advisory mode). See [Team membership access policies](/administration-guide/manage/admin/abac-team-membership).
|
||||
- **Team-scoped channel membership policies** (managed by Team Admins): Channel membership policies that Team Admins can create, edit, and delete directly from the Channel Membership tab in Team Settings for channels in their team. See [Team-level channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies).
|
||||
- **Channel-specific access rules** (managed by Channel Admins): Self-service access rules that Channel Admins can configure directly in Channel Settings for individual channels. See [Channel-specific access rules](/administration-guide/manage/admin/abac-channel-access-rules).
|
||||
|
||||
From Mattermost v11.8, ABAC policies can be applied to **both private and public channels**, with deliberately different semantics for each:
|
||||
|
||||
- **Private channels** are hard-gated by the policy. Non-matching members are removed during synchronization and only matching users can be added or invited.
|
||||
- **Public channels** are advisory. Anyone can still join freely, no member is ever removed by ABAC, and the policy is used either to **auto-add** matching users (when enabled) or to **recommend** the channel under **Browse Channels \> Recommended channels** (when auto-add is disabled).
|
||||
|
||||
Default channels (Town Square, Off-Topic), shared channels, and group-synced channels remain ineligible.
|
||||
|
||||
From Mattermost v11.10, ABAC policies can also be applied to **teams**, with the same advisory/strict model keyed on whether the team is public or private. See [Team membership access policies](/administration-guide/manage/admin/abac-team-membership) for details.
|
||||
|
||||
## Before you begin
|
||||
|
||||
Attribute-based access controls require defined user attributes that are either synchronized from an external system (such as LDAP or SAML) or manually configured and enabled on your Mattermost server. You'll need to [configure user attributes](/administration-guide/manage/admin/user-attributes) in the System Console first before creating access policies.
|
||||
|
||||
Each attribute becomes a user profile option users can populate, unless you disable the **Editable by Users** option, available from Mattermost v11. Admin-managed attributes can be used in addition to the LDAP/SAML synchronized attributes for attribute-based access control rules.
|
||||
|
||||
Once user attributes are defined, go to **System Console \> System Attributes \> Attribute-Based Access** to enable attribute-based access controls for your Mattermost instance. This functionality requires a Mattermost Enterprise Advanced license.
|
||||
|
||||
From Mattermost v10.11, user-managed attributes are excluded from attribute-based access control (ABAC) rules by default for security reasons. This prevents access control policies from being circumvented by users editing their own profile attributes. To include user-managed attributes in ABAC rules, a system admin must explicitly enable the `EnableUserManagedAttributes` configuration setting. See the [user attribute](/administration-guide/manage/admin/user-attributes#before-you-begin) documentation for details on enabling this feature. This configuration setting is available only in Enterprise Edition Advanced and is disabled by default.
|
||||
|
||||
## Configure access policies
|
||||
|
||||
Once enabled, you have multiple ways to configure access policies in Mattermost:
|
||||
|
||||
From Mattermost v11.8.0, admins can configure membership policies for both public and private channels, permission policies for file upload and file download, and simulate policy outcomes before saving.
|
||||
|
||||
**System Admins can:**
|
||||
|
||||
- Create [system-wide access policies](/administration-guide/manage/admin/abac-system-wide-policies) that can be assigned across multiple channels and teams in the System Console. Membership policies can be applied to both public and private channels, with [advisory behavior on public channels](/administration-guide/manage/admin/abac-channel-access-rules#public-and-private-channel-behavior).
|
||||
- Assign [individual channel policies](/administration-guide/manage/admin/abac-system-wide-policies#define-access-controls-per-channel) to specific channels in the System Console.
|
||||
- [Assign membership policies to teams](/administration-guide/manage/admin/abac-team-membership#assign-a-membership-policy-to-a-team) via the per-team System Console page, with advisory enforcement on public teams and strict enforcement on private teams.
|
||||
- Define [permission policies](/administration-guide/manage/admin/abac-system-wide-policies#permission-policies) that restrict actions such as file upload and file download based on user attributes.
|
||||
- [Simulate policy outcomes](/administration-guide/manage/admin/abac-system-wide-policies#simulate-access) to preview whether selected users can perform actions such as joining a channel or uploading and downloading files before saving policy changes.
|
||||
|
||||
**Team Admins can:**
|
||||
|
||||
- View the system policy applied to their team and [configure custom team membership rules](/administration-guide/manage/admin/abac-team-membership#configure-custom-rules) directly from the **Team Membership** tab in Team Settings, when granted the `manage_team_access_rules` permission.
|
||||
- Create and manage [team-level channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies) from the **Channel Membership** tab in Team Settings, scoping attribute-based rules to one or more channels within their team.
|
||||
|
||||
**Channel Admins can:**
|
||||
|
||||
- Configure [channel-specific access rules](/administration-guide/manage/admin/abac-channel-access-rules) directly in Channel Settings without requiring a system admin.
|
||||
225
docs/main/administration-guide/manage/admin/autotranslation.mdx
Normal file
225
docs/main/administration-guide/manage/admin/autotranslation.mdx
Normal file
@@ -0,0 +1,225 @@
|
||||
---
|
||||
title: "Set up auto-translation (Beta)"
|
||||
---
|
||||
<PlanAvailability slug="ent-adv" />
|
||||
|
||||
From Mattermost v11.5, auto-translation automatically translates channel messages into each user's preferred display language. This enables multilingual teams to collaborate without language barriers.
|
||||
|
||||
Auto-translation uses an asynchronous queue-based architecture. When a message is posted in a channel with auto-translation enabled, the message is queued for translation into every configured target language. Translated messages replace the original display for users whose display language matches a target language, and they can view the original text at any time by selecting the translation icon on the message. A user's translation target language is determined by their Mattermost display language (set via **Settings \> Display \> Language**); decoupling the translation target from the display language is not currently supported.
|
||||
|
||||
Two translation provider options are available:
|
||||
|
||||
- **LibreTranslate**: A self-hosted, open-source machine translation engine.
|
||||
- **Agents**: Uses the [Mattermost Agents plugin](/administration-guide/configure/agents-admin-guide) with a configured LLM backend.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- A Mattermost **Enterprise Advanced** license is required.
|
||||
- Choose a translation provider and ensure its infrastructure is available:
|
||||
- **LibreTranslate**: A running LibreTranslate server reachable from the Mattermost server.
|
||||
- **Agents**: The [Mattermost Agents plugin](/administration-guide/configure/agents-admin-guide) installed and configured with at least one LLM service.
|
||||
|
||||
## Set up Auto-translation
|
||||
|
||||
### Configure a translation provider
|
||||
|
||||
Choose one of the following translation providers and follow the setup instructions for your choice.
|
||||
|
||||
#### Set up LibreTranslate
|
||||
|
||||
[LibreTranslate](https://libretranslate.com/) is a self-hosted, open-source machine translation engine. See the [LibreTranslate installation guide](https://docs.libretranslate.com/guides/installation/) for deployment instructions.
|
||||
|
||||
Once your LibreTranslate server is running:
|
||||
|
||||
1. Go to **System Console \> Site Configuration \> Localization**.
|
||||
2. Set **Translation provider** to `libretranslate`.
|
||||
3. Enter the [LibreTranslate URL](/administration-guide/configure/site-configuration-settings#libretranslate-url) (for example, `http://libretranslate.internal:5000`).
|
||||
4. If your LibreTranslate instance requires authentication, enter the [LibreTranslate API key](/administration-guide/configure/site-configuration-settings#libretranslate-api-key).
|
||||
5. Select **Save**.
|
||||
|
||||
<Important>
|
||||
|
||||
The Mattermost server must be able to reach the LibreTranslate URL over the network. Ensure firewall rules and DNS resolution allow connectivity between the Mattermost server and the LibreTranslate instance.
|
||||
|
||||
</Important>
|
||||
|
||||
#### Set up the Agents provider
|
||||
|
||||
The Agents provider uses the Mattermost Agents plugin to translate messages via a configured LLM service.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- The [Mattermost Agents plugin](/administration-guide/configure/agents-admin-guide) is installed and enabled.
|
||||
- At least one LLM service is configured in the Agents plugin.
|
||||
|
||||
To configure:
|
||||
|
||||
1. Go to **System Console \> Site Configuration \> Localization**.
|
||||
2. Set **Translation provider** to `agents`.
|
||||
3. Enter the [Agents LLM service ID](/administration-guide/configure/site-configuration-settings#agents-llm-service-id) matching the LLM service configured in the Agents plugin.
|
||||
4. Select **Save**.
|
||||
|
||||
<Tip>
|
||||
|
||||
**Choosing between LibreTranslate and Agents**: LibreTranslate is a lightweight, self-hosted translation engine. The Agents provider uses an LLM backend and generally produces more accurate translations, especially for languages such as Japanese, Korean, and Chinese where contextual understanding improves quality. Consider your translation quality needs and existing infrastructure when choosing. LibreTranslate does not support direct translation between all language pairs; for unsupported combinations it performs a pivot translation through an intermediate language (typically English), which can reduce accuracy for those pairs.
|
||||
|
||||
**Choosing an LLM for the Agents provider**: Smaller, faster models are recommended for auto-translation. Translation is a well-defined task that doesn't benefit from the extended reasoning capabilities of larger models — larger models may actually overthink the task, adding unnecessary latency without improving quality. Choose a small, low-latency model that is currently supported by your configured LLM provider and validated in your environment.
|
||||
|
||||
</Tip>
|
||||
|
||||
### Enable auto-translation
|
||||
|
||||
1. Go to **System Console \> Site Configuration \> Localization**.
|
||||
2. Set [Enable autotranslation](/administration-guide/configure/site-configuration-settings#enable-auto-translation) to **True**.
|
||||
3. Select a [Translation provider](/administration-guide/configure/site-configuration-settings#translation-provider) (`libretranslate` or `agents`).
|
||||
4. Configure [Languages allowed](/administration-guide/configure/site-configuration-settings#languages-allowed) — every message in auto-translation-enabled channels is translated into each language in this list.
|
||||
5. Select **Save**.
|
||||
|
||||
<Note>
|
||||
|
||||
The languages available in the **Languages allowed** list are controlled by the **Available languages** setting (`AvailableLocales`) under **Site Configuration \> Localization**. If that field is blank, all supported languages are available; otherwise only listed languages appear as selectable auto-translation targets. Note that some locales (such as `zh-Hans`) are in beta — portions of the Mattermost UI may still display in English, which is a UI localization limitation and does not affect message translation.
|
||||
|
||||
</Note>
|
||||
|
||||
Use the [Restrict autotranslation in direct and group messages](/administration-guide/configure/site-configuration-settings#restrict-autotranslation-in-direct-and-group-messages) setting to control whether auto-translation can be enabled in direct and group messages.
|
||||
|
||||
See the [auto-translation configuration reference](../../configure/site-configuration-settings#auto-translation) for all available settings.
|
||||
|
||||
### Enable auto-translation in a channel
|
||||
|
||||
Auto-translation is managed on a per-channel basis and is disabled by default for all channels. System admins and channel admins can enable or disable auto-translation for individual channels.
|
||||
|
||||
- When auto-translation is enabled or disabled in a channel, a system post notifies channel members of the change.
|
||||
|
||||
<Note>
|
||||
|
||||
Enabling auto-translation in a channel only translates new messages going forward. Existing message history is not retroactively translated.
|
||||
|
||||
</Note>
|
||||
|
||||
## Tune worker performance
|
||||
|
||||
For most deployments the default worker settings are sufficient. If your deployment has a high message volume, many configured target languages, or you observe growing translation queue depth, you may need to increase the worker count. This section explains how to calculate and monitor the right values.
|
||||
|
||||
### How the translation queue works
|
||||
|
||||
When a message is posted in a channel with auto-translation enabled, it's added to a per-node translation queue. A worker picks up the post and translates it sequentially into each configured target language. Each completed language translation triggers a websocket broadcast to the channel so users see translations arrive in real time.
|
||||
|
||||
In a high availability deployment, each node runs its own pool of workers and processes its own queue independently.
|
||||
|
||||
### Calculate your worker count
|
||||
|
||||
Use the following formula to estimate how many workers each node needs:
|
||||
|
||||
``` text
|
||||
required_workers = ceil(
|
||||
(posts_per_sec × pct_autotranslated × num_languages × avg_provider_latency_ms / 1000)
|
||||
/ num_app_nodes
|
||||
× 1.2
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
- **posts_per_sec** — average message rate across the server.
|
||||
- **pct_autotranslated** — fraction of posts in auto-translation-enabled channels (0.0–1.0).
|
||||
- **num_languages** — number of configured target languages.
|
||||
- **avg_provider_latency_ms** — mean response time from the translation provider in milliseconds.
|
||||
- **num_app_nodes** — number of Mattermost application nodes.
|
||||
- **1.2** — headroom factor (20%) to absorb traffic bursts.
|
||||
|
||||
The following table shows results from load tests with 6,500 concurrent users, 2 app nodes, ~5 posts/sec, and ~2 s mean provider latency. The provider latency distribution used in testing was realistic, with buckets ranging from 500 ms to 10 s weighted toward the 500 ms–1.5 s range, producing a ~2 s mean.
|
||||
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style={{width: '30%'}} />
|
||||
<col style={{width: '30%'}} />
|
||||
<col style={{width: '40%'}} />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Target languages</th>
|
||||
<th>% autotranslated</th>
|
||||
<th>Workers per node</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>7</td>
|
||||
<td>100%</td>
|
||||
<td>38</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6</td>
|
||||
<td>100%</td>
|
||||
<td>32</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td>75%</td>
|
||||
<td>8</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<Note>
|
||||
|
||||
In the 6-language test the formula yields 33, but workers were capped at 32 due to the configured maximum. Adjust the [Translation workers](/administration-guide/configure/site-configuration-settings#translation-workers) setting to match your calculated value.
|
||||
|
||||
</Note>
|
||||
|
||||
### Scaling considerations
|
||||
|
||||
- **Target languages are the biggest multiplier.** Each additional language increases both worker time per post and the number of websocket broadcasts per post. Reducing the number of target languages is the most effective way to reduce load.
|
||||
- **Websocket traffic scales with languages.** Each target language produces one channel-wide websocket broadcast per translated post. Under high load, the main symptom of saturation is websocket disconnects caused by per-connection send queues filling up.
|
||||
- **Provider latency shapes traffic patterns.** Lower latency means translations complete in quicker bursts, concentrating websocket traffic. Higher latency spreads events over time. Monitor provider response times and factor them into your capacity planning.
|
||||
|
||||
### Monitor with Prometheus
|
||||
|
||||
Mattermost exposes the following Prometheus metrics for auto-translation:
|
||||
|
||||
- `mattermost_autotranslation_queue_depth_total` *(Gauge)* — current tasks waiting in the queue. A steadily rising value means workers can't keep up with incoming posts.
|
||||
|
||||
- `mattermost_autotranslation_provider_call_duration_seconds` *(Histogram; labels: provider, result)* — translation provider latency. This is the `avg_provider_latency_ms` value used in the formula above. Calculate the average with the following PromQL query:
|
||||
|
||||
``` promql
|
||||
rate(mattermost_autotranslation_provider_call_duration_seconds_sum{result="success"}[10m])
|
||||
/
|
||||
rate(mattermost_autotranslation_provider_call_duration_seconds_count{result="success"}[10m])
|
||||
```
|
||||
|
||||
- `mattermost_autotranslation_worker_task_duration_seconds` *(Histogram)* — total time for a worker to process one post across all target languages.
|
||||
|
||||
### Configuration reference
|
||||
|
||||
- [Translation workers](/administration-guide/configure/site-configuration-settings#translation-workers): The number of concurrent workers per node. Default is **6**. Increase this value for high-traffic deployments or decrease it to reduce resource consumption.
|
||||
- [Translation timeout](/administration-guide/configure/site-configuration-settings#translation-timeout): The maximum time in milliseconds for a single translation request. Default is **5000** ms (5 seconds). Increase this value if your translation provider is experiencing timeouts due to network latency or high load.
|
||||
|
||||
You can also update the worker count from the command line using mmctl:
|
||||
|
||||
``` shell
|
||||
mmctl config set AutoTranslationSettings.Workers <number>
|
||||
```
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
### Why aren't messages being translated?
|
||||
|
||||
- Verify auto-translation is enabled globally in **System Console \> Site Configuration \> Localization**.
|
||||
- Verify auto-translation is enabled for the specific channel.
|
||||
- Confirm a translation provider is selected and properly configured.
|
||||
- Check that the Mattermost server can reach the translation provider (LibreTranslate URL or Agents plugin).
|
||||
- Review Mattermost server logs for translation errors.
|
||||
|
||||
### What happens when the translation provider is unavailable?
|
||||
|
||||
Messages are still posted normally. Translations that fail due to provider downtime are skipped, and users see the original untranslated message. When the provider recovers, new messages are translated as expected.
|
||||
|
||||
### What languages are supported?
|
||||
|
||||
Supported languages depend on the translation provider:
|
||||
|
||||
- **LibreTranslate**: Supports the languages available in your LibreTranslate deployment. See the [LibreTranslate language list](https://libretranslate.com/languages) for details.
|
||||
- **Agents**: Language support depends on the capabilities of the configured LLM. Most modern LLMs support a wide range of languages.
|
||||
|
||||
Configure the [Languages allowed](/administration-guide/configure/site-configuration-settings#languages-allowed) setting to specify which languages all messages are translated into.
|
||||
218
docs/main/administration-guide/manage/admin/content-flagging.mdx
Normal file
218
docs/main/administration-guide/manage/admin/content-flagging.mdx
Normal file
@@ -0,0 +1,218 @@
|
||||
---
|
||||
title: "Data Spillage Handling"
|
||||
---
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
Data Spillage Handling helps prevent accidental data spillage and helps system administrators respond quickly to potential leaks without disrupting collaboration. Enabling this feature empowers Mattermost users to report messages that may contain sensitive, regulated, or inappropriate information, and enables designated content reviewers to assess and take appropriate action by removing or dismissing quarantined messages.
|
||||
|
||||
By making every team member a first line of defense against sensitive-data exposure, Data Spillage Handling strengthens mission-critical, secure deployments and supports compliance with organizational and regulatory data-handling standards.
|
||||
|
||||
## Before you begin
|
||||
|
||||
You must be a System Admin in Mattermost. You need to identify who will be content reviewers for quarantined messages, and you need to decide whether quarantined messages should be hidden from users in Mattermost while under review.
|
||||
|
||||
## Enable
|
||||
|
||||
Data Spillage Handling isn't enabled by default. To enable Data Spillage Handling:
|
||||
|
||||
1. Go to **System Console \> Site Configuration \> Data Spillage Handling**.
|
||||
2. Set **Enable Data Spillage Handling** to **True**.
|
||||
|
||||
Alternatively, you can configure Data Spillage Handling via the [config.json file or through environment variables](/administration-guide/configure/site-configuration-settings#content-flagging).
|
||||
|
||||
## Configure
|
||||
|
||||
1. Under **Content Reviewers**, define who should review quarantined content:
|
||||
|
||||
- **Same reviewers for all teams**: Set to **True** to apply one global reviewer list across all teams, or **False** to configure reviewers per team.
|
||||
- **Reviewers**: Start typing to search for users to assign as content reviewers.
|
||||
|
||||
<Important>
|
||||
|
||||
Choose reviewers carefully. Assigning reviewer roles grants access to potentially sensitive information and may expose data from private channels.
|
||||
|
||||
- A global reviewer can view quarantined messages from all teams and channels, including private channels they’re not a member of.
|
||||
- Team-specific reviewers can view quarantined messages from their assigned teams, including private channels within those teams they’re not members of.
|
||||
|
||||
</Important>
|
||||
|
||||
- **Additional reviewers**: Optionally include:
|
||||
- **System Administrators**: System admins receive quarantined messages for all teams they are part of.
|
||||
- **Team Administrators**: Team admins receive quarantined messages for their respective teams.
|
||||
|
||||
2. Under **Notification Settings**, specify who receives updates at each stage of the quarantine workflow when content is quarantined or reviewed:
|
||||
|
||||
- **Notify when content is quarantined**: Reviewer(s), Author.
|
||||
- **Notify when a reviewer is assigned**: Reviewer(s).
|
||||
- **Notify when content is removed**: Reviewer(s), Author, Reporter.
|
||||
- **Notify on dismissal**: Reviewer(s), Author, Reporter.
|
||||
|
||||
All notifications are sent via the **Data Spillage Bot** as direct messages.
|
||||
|
||||
3. Under **Additional Settings**, configure how the quarantine workflow behaves:
|
||||
|
||||
- **Reasons for quarantine**: Define the preset categories that appear in the quarantine dialog for users (for example: **Classification mismatch**, **Need-to-know violation**, **Personally identifiable information (PII) exposure**, **Operational security (OPSEC) concern**, **Controlled Unclassified Information (CUI) violation**).
|
||||
- **Require reporters to add comment**: Set to **True** to require users to add a short explanation when quarantining a message.
|
||||
- **Require reviewers to add comment**: Set to **True** to require reviewers to add a comment when resolving a quarantine.
|
||||
- **Hide message from channel while it is being reviewed**: Set to **True** to automatically hide quarantined messages from the channel until reviews are complete. If a root post is quarantined, the entire thread is hidden.
|
||||
|
||||
<Tip>
|
||||
|
||||
We recommend enabling **Hide message from channel while it is being reviewed** and require comments from both reporters and reviewers to maintain transparency, accountability, and an auditable record of actions.
|
||||
|
||||
</Tip>
|
||||
|
||||
## Monitor quarantined messages
|
||||
|
||||
When [a user quarantines a message](/end-user-guide/collaborate/flag-messages), the **Data Spillage Bot** sends a direct message to all content reviewers.
|
||||
|
||||
Direct messages from the **Data Spillage Bot** is a centralized moderation queue, where reviewers can view, assign, and act on quarantined messages without leaving Mattermost. Reviewers can use it to monitor potential data spills, coordinate response, and maintain an auditable record of review activity.
|
||||
|
||||
Each quarantined message appears as a card-formatted message that includes:
|
||||
|
||||
- **Quarantined by**: The user who reported the message.
|
||||
- **Status**: The current state of the review. All quarantined content starts in **Pending** status.
|
||||
- **Reason**: The reason selected by the reporter (for example, **Classification mismatch**, **Need-to-know violation**).
|
||||
- **Message preview**: A snippet of the quarantined message, including the author, timestamp, and original channel.
|
||||
- **Reviewer**: The user currently assigned to review the message (initially **Unassigned**).
|
||||
- **Channel**: The name of the channel where the message was originally posted.
|
||||
- **Team**: The team context for the quarantined message.
|
||||
- **Comment**: Any reporter-provided context.
|
||||
- **Post ID**: The system identifier for the original message for auditing purposes.
|
||||
|
||||
Reviewers can select **View details** to take action as follows:
|
||||
|
||||
- Assign a **Reviewer** responsible for reviewing the quarantined message.
|
||||
- **Remove message**: Permanently delete the quarantined message from its original channel for all users. The status of the quarantined message changes to **Removed**.
|
||||
- **Keep message**: Dismiss the quarantine and restore the message if it was hidden. The status of the quarantined message changes to **Retained**.
|
||||
- **Add a comment**: Record the reason for the decision when required.
|
||||
- **Generate a report**: Download a report of the quarantined message and review activity for record-keeping or incident response. See [Generate a quarantined message report](#generate-a-quarantined-message-report) for details.
|
||||
|
||||
Once an action is taken, the **Status** field updates automatically. The **Data Spillage Bot** sends follow-up notifications to the reporter, author, and other reviewers based on how Data Spillage Handling is configured.
|
||||
|
||||
### Generate a quarantined message report
|
||||
|
||||
Reviewers can generate a downloadable report that captures the full context of a quarantined message and the associated review activity. Reports are useful for record-keeping, incident response, and preserving evidence before a message is permanently removed.
|
||||
|
||||
A report can be generated from any of the following entry points:
|
||||
|
||||
- **From the quarantined message details**: Select **Download report** from the message details panel. This option is available regardless of the quarantine's status, including **Pending**, **Reviewer Assigned**, **Removed**, or **Retained**.
|
||||
- **From the Remove message flow**: When you select **Remove message**, the confirmation dialog includes a **Download quarantined message report** checkbox, selected by default. With the checkbox selected, Mattermost generates and downloads the report before you can permanently remove the message. This safeguard ensures the record is preserved on your device before the message contents are deleted.
|
||||
- **From the Keep message flow**: When you select **Keep message**, the confirmation dialog includes the same checkbox. With the checkbox selected, Mattermost generates and downloads the report in the background while the keep action completes.
|
||||
|
||||
If you choose to skip the report download from the **Remove message** or **Keep message** flow, Mattermost asks you to confirm that you're proceeding without a report. The skip decision is recorded in the audit log.
|
||||
|
||||
If report generation fails (for example, due to a network interruption or session timeout), the dialog displays an error and offers a retry option. You can also skip the report and proceed with the action, or cancel and download the report later from the message details.
|
||||
|
||||
Each time a reviewer generates a report, the **Data Spillage Bot** notifies all content reviewers so an auditable record exists whenever a copy of the potentially spilled data is obtained. If the report was generated without the message's file attachments, the bot sends an additional notification to the reviewer who requested it, explaining why. See [File attachments and download policies](#file-attachments-and-download-policies) for details.
|
||||
|
||||
<Tip>
|
||||
|
||||
We recommend generating a report before removing a message. Once a message is removed, its content, attachments, and edit history are permanently deleted and can't be recovered.
|
||||
|
||||
</Tip>
|
||||
|
||||
#### Report contents and format
|
||||
|
||||
Each report is a ZIP archive containing YAML metadata files and the original file attachments. YAML is used because it's both human-readable and machine-parseable, which makes the report suitable for manual review and for ingestion by downstream compliance or incident-response tooling.
|
||||
|
||||
The archive has the following structure:
|
||||
|
||||
``` text
|
||||
/
|
||||
├── report_metadata.yaml
|
||||
├── content_review.yaml
|
||||
├── ATTACHMENTS_OMITTED.txt # only when attachments are withheld
|
||||
├── post/
|
||||
│ ├── post.yaml
|
||||
│ └── attachments/
|
||||
│ └── <original attachment files>
|
||||
└── edit_history/
|
||||
└── <edit_post_id>/
|
||||
├── post.yaml
|
||||
└── attachments/
|
||||
└── <original attachment files>
|
||||
```
|
||||
|
||||
- **report_metadata.yaml**: Identifies the report itself, including the user ID and username of the reviewer who generated the report, the generation timestamp, and the report format version (used for forward compatibility if the report format changes in future releases).
|
||||
- **content_review.yaml**: Captures the data spillage event, including the reporter's user ID, username, selected reason, and comment; the report timestamp; whether the message was hidden during review; and, once the quarantine is resolved, the reviewer's user ID, username, comment, and action timestamp. For unresolved quarantines, reviewer fields are omitted.
|
||||
- **post/post.yaml**: Describes the quarantined message, including the post ID, author ID, author name, author email, message content, channel ID, channel display name, team ID, team display name, creation and update timestamps, pinned status, root ID, post properties, post metadata, reply count (for root posts), and the ordered list of edit history post IDs.
|
||||
- **post/attachments/**: The original files attached to the quarantined message, included verbatim. This directory is left out entirely when the reviewer isn't permitted to download attachments from the channel.
|
||||
- **edit_history/\<edit_post_id\>/**: One subdirectory per previous version of the message, each containing a `post.yaml` and an `attachments/` directory in the same format as the base post directory.
|
||||
- **ATTACHMENTS_OMITTED.txt**: Present only when attachments were withheld from the report. See [File attachments and download policies](#file-attachments-and-download-policies).
|
||||
|
||||
To avoid duplication, attachment files are deduplicated across the entire archive by their file ID. Each unique attachment appears exactly once — under the base post if it exists in the current version of the message, or under the earliest edit-history entry that referenced it.
|
||||
|
||||
#### File attachments and download policies
|
||||
|
||||
If your deployment restricts who can download file attachments using [channel-level permission policies](/administration-guide/manage/admin/abac-channel-access-rules#channel-level-permission-policies) or [system-wide permission policies](/administration-guide/manage/admin/abac-system-wide-policies#permission-policies), those policies apply to content reviewers generating a report as well. Being a content reviewer doesn't exempt someone from the channel's file download rules.
|
||||
|
||||
Before building the archive, Mattermost evaluates the requesting reviewer against the quarantined message's channel for the file download action:
|
||||
|
||||
- **When the reviewer satisfies the policy**, the report includes attachments as described above.
|
||||
- **When the reviewer doesn't satisfy the policy**, the report is still generated and downloaded, but the attachment files are withheld. The `post/attachments/` and `edit_history/<edit_post_id>/attachments/` directories are left out, and the attachment metadata is removed from `post.yaml` in each of those sections, so the archive carries no reference to the withheld files. Every other part of the report - message content, review activity, and report metadata - is unaffected.
|
||||
|
||||
Reports aren't blocked when attachments are withheld, so reviewers who can't access the files can still capture the message and its review history for record-keeping.
|
||||
|
||||
When attachments are withheld, Mattermost signals it in three places:
|
||||
|
||||
- **`ATTACHMENTS_OMITTED.txt`**: A plain-text file added at the root of the archive, in place of the attachment directories, reading *"The attachments on this message were omitted from this report because you do not comply with the channel's file download policy."* Its presence makes an incomplete report self-describing for anyone who receives the archive later.
|
||||
- **A notification to the requesting reviewer**: The **Data Spillage Bot** posts a message in that reviewer's content review thread for the quarantined message, explaining that the report didn't include the file attachments. Only the reviewer who generated the report receives it; the other reviewers see the usual report generation notification.
|
||||
- **The audit log**: The `generateFlaggedPostReport` audit entry records an `omitted_attachment_count` parameter holding the number of withheld attachments. The parameter is only present when attachments were actually withheld, so its absence indicates a complete report.
|
||||
|
||||
<Note>
|
||||
|
||||
Permission policies require a Mattermost Enterprise Advanced license and the `PermissionPolicies` feature flag. Where they aren't in use, reviewers who can generate a report always receive its attachments, and none of the behavior in this section applies.
|
||||
|
||||
</Note>
|
||||
|
||||
### Deleted messages
|
||||
|
||||
When a reviewer permanently removes a quarantined message, the message and all associated data are deleted from the database and file system and can't be recovered. The deletion covers:
|
||||
|
||||
- **Post record**: The text of the message and any associated post properties. The content is scrubbed before the post is deleted.
|
||||
- **File attachments**: The files stored in Mattermost's file storage (local, S3, etc.).
|
||||
- **File attachment records**: The file info database rows for the message, including file names, IDs, and links to storage.
|
||||
- **Edit history**: Every prior revision of the message, along with file metadata from each revision.
|
||||
- **Priority metadata**: Any message priority or importance settings.
|
||||
- **Persistent notifications**: Any recurring notifications attached to the message.
|
||||
- **Acknowledgements**: Records of users who acknowledged the message.
|
||||
- **Reminders**: Any reminders created for the message.
|
||||
- **Thread, replies, and reactions**: The thread record, replies, and reaction data, if any, associated with the message.
|
||||
|
||||
#### Post deletion report
|
||||
|
||||
When a reviewer selects **Remove message**, the **Data Spillage Bot** posts a **Post Deletion Report** into the reviewer's content review thread for that quarantined message. The report is delivered to every reviewer who received the original quarantine notification, and is localized to each reviewer's language. Each post includes a short summary rendered inline, and a full report attached as a Markdown file named `deletion_report_<post_id>.md`.
|
||||
|
||||
The report records every cleanup step performed against the message and its associated data. The steps map directly to the data scope listed in [Deleted messages](#deleted-messages):
|
||||
|
||||
- **File attachments**: Files removed from file storage.
|
||||
- **File attachment records**: File info database rows for the message.
|
||||
- **Edit history**: Every prior revision of the message. Each revision is reported as its own sub-step so that reviewers can see exactly which revisions were cleared.
|
||||
- **Priority metadata**: Message priority and importance settings.
|
||||
- **Persistent notifications**: Recurring notifications attached to the message.
|
||||
- **Acknowledgements**: Records of users who acknowledged the message.
|
||||
- **Reminders**: Reminders set on the message.
|
||||
- **Thread, replies, and reactions**: The thread record, replies, and reaction data associated with the message.
|
||||
- **Post record**: The post itself. The content is scrubbed before the post is deleted.
|
||||
|
||||
Each step is assigned one of the following statuses:
|
||||
|
||||
- **Removed** ✅: The data was successfully deleted.
|
||||
- **Not applicable** ➖: There was no data of this type to delete.
|
||||
- **Partial** ⚠️: Some items of this type were deleted, but at least one failed. This status most often appears under **Edit history** when one revision can't be deleted.
|
||||
- **Failed** ❌: The step didn't complete. The report includes an error log so reviewers and System Administrators can inspect what went wrong.
|
||||
|
||||
When every step is **Removed** or **Not applicable**, no further action is required. The report serves as the auditable record of the deletion.
|
||||
|
||||
When any step reports **Partial** or **Failed**, the report displays an *incomplete* warning. Reviewers should escalate to a System Administrator, who can use the attached `deletion_report_<postId>.md` file - including the full per-step error log - to perform manual remediation and confirm that the data is fully removed.
|
||||
|
||||
<Note>
|
||||
|
||||
The post deletion report is the single source of truth for post-removal auditing. It isn't stored elsewhere in the System Console, so the reviewer thread containing the report should be retained in line with your organization's audit retention policy.
|
||||
|
||||
</Note>
|
||||
|
||||
## Best practice recommendations
|
||||
|
||||
Before rolling out Data Spillage Handling organization-wide, we recommend communicating that the feature protects both users and the organization from accidental data spillage. Start with a pilot team to validate reviewer notifications and workflows, integrate the process with existing data-handling or incident-response playbooks, and require reporter and reviewer comments to ensure every decision is transparent and auditable.
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
title: "Customize branding"
|
||||
---
|
||||
Whether you’re customizing the appearance of your workspace, utilizing branding tools, or managing code signing for custom builds, this section of documentation has you covered and provides everything you need to customize the branding of Mattermost to align with your organization’s identity. Use the navigation below to access detailed instructions for each customization option.
|
||||
|
||||
- [Customize Mattermost](/administration-guide/configure/customize-mattermost) - Learn how to customize the Mattermost server.
|
||||
- [Custom branding tools](/administration-guide/configure/custom-branding-tools) - Learn about custom branding tools for Mattermost.
|
||||
- [Code signing custom builds](/administration-guide/manage/code-signing-custom-builds) - Learn about code signing custom builds of Mattermost.
|
||||
36
docs/main/administration-guide/manage/admin/error-codes.mdx
Normal file
36
docs/main/administration-guide/manage/admin/error-codes.mdx
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: "Mattermost error codes"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Mattermost is designed to deploy in private networks which may be disconnected or “air-gapped” from the internet. In these deployments, links to Mattermost’s online documentation may be unavailable.
|
||||
|
||||
Therefore, Mattermost error codes are provided to enable administrators to use internet connected machines to look up error messages and resolutions in online resources, including Mattermost documentation and user forums, as well as providing Mattermost support teams a concise way to identify issues.
|
||||
|
||||
Mattermost error codes are used in logs, administrative tools, as well as on-screen messages to concisely identify issues and connect them with additional resources.
|
||||
|
||||
In advanced deployments, error codes can be overwritten by administrators to reference internal documentation and guides.
|
||||
|
||||
## ERROR_SAFETY_LIMITS_EXCEEDED
|
||||
|
||||
A safety limits exceeded error (`ERROR_SAFETY_LIMITS_EXCEEDED`) displays in the [free version of Mattermost](/product-overview/editions-and-offerings#mattermost-team-edition), and certain functionality may be limited, when usage grossly exceeds the recommended limit for users in a safe deployment, including more than 250 users are registered on the server.
|
||||
|
||||
250 users represents a “high upper limit” for deployments that are approximately 5 times the recommended size, which is far beyond the intended design of the product.
|
||||
|
||||
The free version of Mattermost is intended for approximately 50 users. If your Mattermost materially exceeds this recommended size, system admins should seek to either [purchase a commercial license](https://mattermost.com/pricing/), or apply for a [non-profit subscription](/product-overview/non-profit-subscriptions) license. Alternatively, admins can [deactivate users](/administration-guide/configure/user-management-configuration-settings#deactivate-users) until the user count falls below the high upper limit.
|
||||
|
||||
## ERROR_LICENSED_USERS_LIMIT_EXCEEDED
|
||||
|
||||
A licensed user limit exceeded error (`ERROR_LICENSED_USERS_LIMIT_EXCEEDED`) displays when attempting to create or activate users on a licensed Mattermost server where the user count would exceed the maximum number of users allowed by the license.
|
||||
|
||||
This error occurs when:
|
||||
|
||||
- Creating new users would exceed the license user limit.
|
||||
- Activating deactivated users would exceed the license user limit.
|
||||
|
||||
To resolve this error, system administrators can:
|
||||
|
||||
- [Deactivate users](/administration-guide/configure/user-management-configuration-settings#deactivate-users) to reduce the active user count below the license limit.
|
||||
- Contact [Mattermost Sales](https://mattermost.com/contact-sales/) to request an updated license that increases the number of licensed users.
|
||||
|
||||
[Book a live demo](https://mattermost.com/request-demo/) or [talk to a Mattermost expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization's secure collaboration needs. Or try Mattermost yourself with a [1-hour preview](https://mattermost.com/sign-up/) for instant access to a live sandbox environment.
|
||||
145
docs/main/administration-guide/manage/admin/fips-migration.mdx
Normal file
145
docs/main/administration-guide/manage/admin/fips-migration.mdx
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
title: "Migrate an existing deployment to FIPS-compliant images"
|
||||
sidebar_label: "Migrate to FIPS-compliant images"
|
||||
---
|
||||
<PlanAvailability slug="entry-ent" />
|
||||
|
||||
From Mattermost v11, each release ships in two image variants: a standard Enterprise build (`mattermost/mattermost-enterprise-edition`) and a FIPS-compliant build (`mattermost/mattermost-enterprise-fips-edition`). Migrating an existing deployment to the FIPS image is primarily a matter of replacing the image and restarting Mattermost. No data migration is required, and rollback is symmetric.
|
||||
|
||||
This guide covers migrating an existing Mattermost Server deployment running on Docker or Kubernetes. Linux package and tarball installations have no FIPS-compliant equivalent.
|
||||
|
||||
Mattermost's FIPS offering also covers the Mattermost Operator controller and a self-hosted Push Proxy. Migrating those components to their FIPS variants is out of scope for this guide.
|
||||
|
||||
For background on what the FIPS build is and how it's constructed, see the **FIPS/STIG** tab on [Deploy Mattermost using Containers](/deployment-guide/server/deploy-containers).
|
||||
|
||||
## Before you begin
|
||||
|
||||
1. **Back up your database and configuration.** Always take a full backup before changing the image. See the [backup and disaster recovery](/deployment-guide/backup-disaster-recovery) documentation.
|
||||
|
||||
2. **Confirm your deployment type.** FIPS images are supported on Docker, Docker Compose, and Kubernetes only. If you're running Mattermost from a Linux package or tarball, you can't migrate in place.
|
||||
|
||||
3. **Check your Mattermost version.** FIPS images are available from v11.0 onward and use the same release tags as the standard Enterprise images. Plan to migrate to the matching FIPS tag for your current version.
|
||||
|
||||
4. **Plan for additional plugins.** The FIPS image includes Boards, Playbooks, and Agents prepackaged and running in FIPS mode. Any additional plugins you've installed will continue to run inside the FIPS image, but they run in non-FIPS mode. This is expected behavior, not a configuration error.
|
||||
|
||||
5. **PostgreSQL password length.** Beginning with Mattermost v11.7, the Postgres password used by the Mattermost server must be at least 14 characters when running the FIPS image. If your current password is shorter, complete these steps before swapping the image:
|
||||
|
||||
a. Rotate the password in PostgreSQL. For example, connecting as a Postgres superuser and replacing `mmuser` and `<new password>` to match your deployment:
|
||||
|
||||
```sql
|
||||
ALTER USER mmuser WITH PASSWORD '<new password>';
|
||||
```
|
||||
|
||||
b. Update the password where your deployment stores it: in the official Docker deployment, the `POSTGRES_PASSWORD` value in `.env`; in Operator-managed Kubernetes deployments, the database Secret referenced by your `Mattermost` custom resource (commonly under `spec.database.external.secret`).
|
||||
|
||||
c. Proceed to the image swap procedure for your deployment type below. Recreating the container as part of the migration applies the new credentials — no separate restart is required.
|
||||
|
||||
6. **Plan for downtime.** The migration requires pulling the new image and restarting the Mattermost container or pod.
|
||||
|
||||
## Migrate a Kubernetes deployment
|
||||
|
||||
These steps assume your deployment is managed by the Mattermost Operator using a `Mattermost` custom resource.
|
||||
|
||||
In the steps below, replace `<namespace>` with the namespace your Mattermost installation runs in. If you omit `-n <namespace>`, `kubectl` uses your current context's default namespace.
|
||||
|
||||
1. Find the name of your Mattermost custom resource:
|
||||
|
||||
```sh
|
||||
kubectl -n <namespace> get mattermost
|
||||
```
|
||||
|
||||
2. Edit the `Mattermost` custom resource to point at the FIPS image. You can edit the live resource directly:
|
||||
|
||||
```sh
|
||||
kubectl -n <namespace> edit mattermost <installation-name>
|
||||
```
|
||||
|
||||
Or update your manifest file and re-apply it.
|
||||
|
||||
3. In `spec.image`, change the value from `mattermost/mattermost-enterprise-edition` to `mattermost/mattermost-enterprise-fips-edition`. Keep `spec.version` aligned with your current release tag. For example:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
image: mattermost/mattermost-enterprise-fips-edition
|
||||
version: 11.6.1
|
||||
```
|
||||
|
||||
4. If you edited a manifest file, apply it:
|
||||
|
||||
```sh
|
||||
kubectl -n <namespace> apply -f <your-mattermost-manifest>.yaml
|
||||
```
|
||||
|
||||
5. Watch the Mattermost pods until the new ones report `Ready` and the old ones terminate. A pod showing `Running` isn't necessarily serving traffic yet — wait until its `READY` column shows all containers ready (for example, `1/1`):
|
||||
|
||||
```sh
|
||||
kubectl -n <namespace> get pods -l app=mattermost -w
|
||||
```
|
||||
|
||||
6. Verify the running pods are using the FIPS image:
|
||||
|
||||
```sh
|
||||
kubectl -n <namespace> get pods -l app=mattermost -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
|
||||
```
|
||||
|
||||
## Migrate a Docker or Docker Compose deployment
|
||||
|
||||
These steps are written for the official [Mattermost Docker deployment](https://github.com/mattermost/docker), which selects the Mattermost image and tag through `.env` variables (`MATTERMOST_IMAGE` and `MATTERMOST_IMAGE_TAG`) referenced from `docker-compose.yml` as `mattermost/${MATTERMOST_IMAGE}:${MATTERMOST_IMAGE_TAG}`. If you're using a custom Docker setup that hardcodes the image in `docker-compose.yml` or uses different variable names, adapt these steps accordingly.
|
||||
|
||||
1. Stop the Mattermost container:
|
||||
|
||||
```sh
|
||||
docker compose stop mattermost
|
||||
```
|
||||
|
||||
2. Edit your `.env` file. Change `MATTERMOST_IMAGE` from `mattermost-enterprise-edition` to `mattermost-enterprise-fips-edition`. Leave `MATTERMOST_IMAGE_TAG` set to your current release tag — FIPS images are published under the same tags as the standard Enterprise images.
|
||||
|
||||
```text
|
||||
MATTERMOST_IMAGE=mattermost-enterprise-fips-edition
|
||||
MATTERMOST_IMAGE_TAG=<tag>
|
||||
```
|
||||
|
||||
3. Pull the FIPS image:
|
||||
|
||||
```sh
|
||||
docker compose pull mattermost
|
||||
```
|
||||
|
||||
4. Recreate the Mattermost container so the new `.env` values are applied:
|
||||
|
||||
```sh
|
||||
docker compose up -d --force-recreate mattermost
|
||||
```
|
||||
|
||||
5. Verify the running container is using the FIPS image:
|
||||
|
||||
```sh
|
||||
docker inspect mattermost --format '{{.Config.Image}}'
|
||||
```
|
||||
|
||||
## Verify the migration
|
||||
|
||||
1. Confirm Mattermost starts cleanly. Tail the logs and watch for startup errors. On Kubernetes, target a specific Mattermost pod:
|
||||
|
||||
```sh
|
||||
kubectl -n <namespace> logs -f <pod-name>
|
||||
```
|
||||
|
||||
On Docker:
|
||||
|
||||
```sh
|
||||
docker compose logs -f mattermost
|
||||
```
|
||||
|
||||
2. Sign in and verify core functionality (sending messages, file uploads, search).
|
||||
|
||||
3. Confirm the prepackaged plugins (Boards, Playbooks, Agents) load successfully. In the System Console, go to **Plugins > Plugin Management** and confirm they're enabled and healthy.
|
||||
|
||||
4. If you have additional plugins installed, confirm they still load. They'll run in non-FIPS mode inside the FIPS image — this is expected.
|
||||
|
||||
## Roll back
|
||||
|
||||
If the migration doesn't go as planned, rolling back is symmetric: revert the image reference and redeploy. No data migration is involved.
|
||||
|
||||
- **Kubernetes:** Edit the `Mattermost` custom resource and change `spec.image` back to `mattermost/mattermost-enterprise-edition`. Re-apply or save, and watch the rollout.
|
||||
- **Docker / Docker Compose:** Restore the original `MATTERMOST_IMAGE` value in `.env` (`mattermost-enterprise-edition`) and run `docker compose pull mattermost` followed by `docker compose up -d --force-recreate mattermost`.
|
||||
@@ -0,0 +1,384 @@
|
||||
---
|
||||
title: "Generate a support packet"
|
||||
---
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
The Support Packet is used to help customers diagnose and troubleshoot issues. Use the System Console or the [mmctl system supportpacket](/administration-guide/manage/mmctl-command-line-tool#mmctl-system-supportpacket) command to generate a zip file that includes configuration information, logs, plugin details, and data on external dependencies across all nodes in a high-availability cluster. Confidential data, such as passwords, are automatically stripped.
|
||||
|
||||
## Generate
|
||||
|
||||
<Important>
|
||||
|
||||
- Before generating a Support Packet, go to **System Console \> Environment \> Logging** and ensure **Output logs to file** is set to **true**, and set **File Log Level** to **DEBUG**
|
||||
- From Mattermost v11.4, support packet generation is recorded in the audit log (when [audit logging is enabled and configured](/administration-guide/manage/logging#audit-logging)). The audit event includes the username, timestamp, success/failure status, whether logs were included, plugin packets requested, and the output filename. This audit trail helps track access to potentially sensitive log data for compliance purposes.
|
||||
|
||||
</Important>
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="web-desktop" label="Web/Desktop">
|
||||
|
||||
1. Go to the System Console, and select **Commercial Support** from the System Console menu.
|
||||
|
||||

|
||||
|
||||
2. Select **Download Support Packet**. A zip file is downloaded to the local machine. You'll be notified if any packet files are unavailable during packet generation. See the `warning.txt` file for details.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="mmctl" label="mmctl">
|
||||
|
||||
Run the [mmctl system supportpacket](/administration-guide/manage/mmctl-command-line-tool#mmctl-system-supportpacket) command to generate and download a Support Packet to share with Mattermost Support.
|
||||
|
||||
``` sh
|
||||
go run ./cmd/mmctl system supportpacket
|
||||
```
|
||||
|
||||
``` text
|
||||
Downloading Support Packet
|
||||
Downloaded Support Packet to mattermost_support_packet_.zip
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Sanitize confidential data
|
||||
|
||||
Please sanitize any confidential data you wish to exclude before sharing the packet with Mattermost.
|
||||
|
||||
When present, the following information is automatically sanitized during packet generation: `LdapSettings.BindPassword`, `FileSettings.PublicLinkSalt`, `FileSettings.AmazonS3SecretAccessKey`, `EmailSettings.SMTPPassword`, `GitLabSettings.Secret`, `GoogleSettings.Secret`, `Office365Settings.Secret`, `OpenIdSettings.Secret`, `SqlSettings.DataSource`, `SqlSettings.AtRestEncryptKey`, `ElasticsearchSettings.Password`, `All SqlSettings.DataSourceReplicas`, `All SqlSettings.DataSourceSearchReplicas`, `MessageExportSettings.GlobalRelaySettings.SmtpPassword`, `ServiceSettings.SplitKey`, `FileSettings.ExportAmazonS3SecretAccessKey`, `ServiceSettings.GoogleDeveloperKey`, and `ServiceSettings.GiphySdkKey` (from Mattermost v11.6.0).
|
||||
|
||||
<Important>
|
||||
|
||||
Plugins may not be sanitized during packet generation.
|
||||
|
||||
- From Mattermost v10.1, plugins can mark their configuration as hidden. If a plugin marks its configuration as hidden, the configuration is sanitized during packet generation.
|
||||
- Otherwise, ensure you sanitize any additional confidential details in the `plugin.json` file before sharing it with Mattermost. Replace details with example strings that contain the same special characters if possible, as special characters are common causes of configuration errors.
|
||||
|
||||
</Important>
|
||||
|
||||
## Share the packet with Mattermost
|
||||
|
||||
Add the generated Support Packet to a [standard support request](https://support.mattermost.com/hc/en-us/requests/new), or share with with the Mattermost team you're working with.
|
||||
|
||||
<Important>
|
||||
|
||||
Disable debug logging once you've generated the Support Packet. Debug logging can cause log files to expand substantially, and may adversely impact server performance. We recommend enabling it temporarily, or in development environments, but not production environments.
|
||||
|
||||
</Important>
|
||||
|
||||
## Contents of a Support Packet
|
||||
|
||||
The contents of a Mattermost Support Packet can differ by server version. Select the tab that corresponds to your Mattermost version to see the files included in the Support Packet.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="v11-0-and-later" label="v11.0 and later">
|
||||
|
||||
### Cluster-wide files
|
||||
|
||||
The following cluster-wide files are located in the root directory of the Support Packet:
|
||||
|
||||
- [metadata.yaml](#metadata)
|
||||
- `plugins.json` (all active and inactive plugins)
|
||||
- `sanitized_config.json` (sanitized copy of the Mattermost configuration)
|
||||
- `stats.yaml` (Mattermost usage statistics)
|
||||
- `jobs.yaml` (last runs of important jobs)
|
||||
- `diagnostics.yaml` (system and plugin diagnostics)
|
||||
- `permissions.yaml` (role and scheme information)
|
||||
- `postgres_schema_dump.sql` (PostgreSQL database schema information including tables, indexes, constraints, and other metadata to assist with database configuration diagnosis)
|
||||
- `warning.txt` (present when issues are encountered during packet generation)
|
||||
- `tsdb_dump.tar.gz` (present when the Metrics plugin is installed and the **Performance metrics** option is selected when generating the Support Packet)
|
||||
|
||||
### Node-specific files
|
||||
|
||||
The following node-specific files are located in node subdirectories:
|
||||
|
||||
- `<node-id>/mattermost.log` (Mattermost logs for each node)
|
||||
- `<node-id>/audit.log` (Mattermost audit logs for each node)
|
||||
- `<node-id>/ldap.log` (AD/LDAP logs for each node)
|
||||
- `<node-id>/notifications.log` (notifications logs for each node)
|
||||
- `<node-id>/cpu.prof` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
- `<node-id>/heap.prof` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
- `<node-id>/goroutines` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
|
||||
### Diagnostics highlights
|
||||
|
||||
The Support Packet `diagnostics.yaml` file includes system and plugin diagnostics to support troubleshooting and configuration validation.
|
||||
|
||||
### Plugin diagnostic data
|
||||
|
||||
The following additional plugin diagnostic data is available when the plugin is enabled and operational:
|
||||
|
||||
- GitHub: `/github/diagnostics.yaml`
|
||||
- GitLab: `/com.github.manland.mattermost-plugin-gitlab/diagnostics.yaml`
|
||||
- Jira: `/jira/diagnostics.yaml`
|
||||
- Calls: `/com.mattermost.calls/diagnostics.yaml`
|
||||
- Boards: `/focalboard/diagnostics.yaml`
|
||||
- Playbooks: `/playbooks/diagnostics.yaml`
|
||||
- MSCalendar: `/com.mattermost.mscalendar/diagnostics.yaml`
|
||||
- Google Calendar: `/com.mattermost.gcal/diagnostics.yaml`
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="v10-11" label="v10.11">
|
||||
|
||||
From v10.11, Support Packets include PostgreSQL database schema dump information that provides comprehensive metadata to help diagnose database configuration issues, performance problems, collation mismatches, and other database-related issues.
|
||||
|
||||
**Cluster-wide files (root directory):**
|
||||
|
||||
- [metadata.yaml](#metadata)
|
||||
- `plugins.json` (all active and inactive plugins)
|
||||
- `sanitized_config.json` (sanitized copy of the Mattermost configuration)
|
||||
- `stats.yaml` (Mattermost usage statistics)
|
||||
- `jobs.yaml` (last runs of important jobs)
|
||||
- `diagnostics.yaml` (core plugin diagnostics data)
|
||||
- `permissions.yaml` (role & scheme information)
|
||||
- `postgres_schema_dump.sql` (PostgreSQL database schema information including tables, indexes, constraints, and other database metadata to assist with database configuration diagnosis)
|
||||
- `warning.txt` (present when issues are encountered during packet generation)
|
||||
- `tsdb_dump.tar.gz` (present when the Metrics plugin is installed and the **Performance metrics** option is selected when generating the Support Packet)
|
||||
|
||||
**Cluster-specific files (in node subdirectories):**
|
||||
|
||||
- `<node-id>/mattermost.log` (Mattermost logs for each node)
|
||||
- `<node-id>/audit.log` (Mattermost audit logs for each node)
|
||||
- `<node-id>/ldap.log` (AD/LDAP logs for each node)
|
||||
- `<node-id>/notifications.log` (notifications logs for each node)
|
||||
- `<node-id>/cpu.prof` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
- `<node-id>/heap.prof` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
- `<node-id>/goroutines` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
|
||||
The following additional plugin diagnostic data is included in the generated Support Packet when the plugin is enabled and operational:
|
||||
|
||||
- GitHub: `/github/diagnostics.yaml`
|
||||
- GitLab: `/com.github.manland.mattermost-plugin-gitlab/diagnostics.yaml`
|
||||
- Jira: `/jira/diagnostics.yaml`
|
||||
- Calls: `/com.mattermost.calls/diagnostics.yaml`
|
||||
- Boards: `/focalboard/diagnostics.yaml`
|
||||
- Playbooks: `/playbooks/diagnostics.yaml`
|
||||
- MSCalendar: `/com.mattermost.mscalendar/diagnostics.yaml`
|
||||
- Google Calendar: `/com.mattermost.gcal/diagnostics.yaml`
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="v10-10" label="v10.10">
|
||||
|
||||
From Mattermost v10.10, Support Packets from [high availability](/deployment-guide/server/high-availability-cluster-based-deployment) deployments organize cluster-specific files (such as log files) in subdirectories named after each cluster node, while cluster-wide files remain in the root directory.
|
||||
|
||||
Support packet file organization has been improved to make it easier to identify cluster-wide versus cluster-specific files:
|
||||
|
||||
- **Cluster-wide files** (identical across all nodes in a [high-availability cluster](/deployment-guide/server/high-availability-cluster-based-deployment)) remain in the root directory of the support packet.
|
||||
- **Cluster-specific files** (unique per node) are now organized in subdirectories named after each cluster node.
|
||||
|
||||
**Cluster-wide files (root directory):**
|
||||
|
||||
- [metadata.yaml](#metadata)
|
||||
- `plugins.json` (all active and inactive plugins)
|
||||
- `sanitized_config.json` (sanitized copy of the Mattermost configuration)
|
||||
- `stats.yaml` (Mattermost usage statistics)
|
||||
- `jobs.yaml` (last runs of important jobs)
|
||||
- `diagnostics.yaml` (core plugin diagnostics data)
|
||||
- `permissions.yaml` (role & scheme information)
|
||||
- `warning.txt` (present when issues are encountered during packet generation)
|
||||
- `tsdb_dump.tar.gz` (present when the Metrics plugin is installed and the **Performance metrics** option is selected when generating the Support Packet)
|
||||
|
||||
**Cluster-specific files (in node subdirectories):**
|
||||
|
||||
- `<node-id>/mattermost.log` (Mattermost logs for each node)
|
||||
- `<node-id>/audit.log` (Mattermost audit logs for each node)
|
||||
- `<node-id>/ldap.log` (AD/LDAP logs for each node)
|
||||
- `<node-id>/notifications.log` (notifications logs for each node)
|
||||
- `<node-id>/cpu.prof` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
- `<node-id>/heap.prof` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
- `<node-id>/goroutines` ([Go performance metrics](#go-performance-metrics) for each node)
|
||||
|
||||
The following additional plugin diagnostic data is included in the generated support packet when the plugin is enabled and operational:
|
||||
|
||||
- GitHub: `/github/diagnostics.yaml`
|
||||
- GitLab: `/com.github.manland.mattermost-plugin-gitlab/diagnostics.yaml`
|
||||
- Jira: `/jira/diagnostics.yaml`
|
||||
- Calls: `/com.mattermost.calls/diagnostics.yaml`
|
||||
- Boards: `/focalboard/diagnostics.yaml`
|
||||
- Playbooks: `/playbooks/diagnostics.yaml`
|
||||
- MSCalendar: `/com.mattermost.mscalendar/diagnostics.yaml`
|
||||
- Google Calendar: `/com.mattermost.gcal/diagnostics.yaml`
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="v10-5-to-v10-9" label="v10.5 to v10.9">
|
||||
|
||||
Prior to v10.10, each node in the cluster of a high availability deployment has its own `mattermost.log` file and advanced logging files included directly in the Support Packet.
|
||||
|
||||
From v10.5, the following Support Packet data has changed:
|
||||
|
||||
- The `support_packet.yaml` file has been removed and split into `diagnostics.yaml` and `stats.yaml` files.
|
||||
- All fields in `diagnostics.yaml` have been moved into their own objects for improved readability.
|
||||
- Field names are normalized.
|
||||
- New data includes server statistics, logs, permissions, and extended job list details.
|
||||
- Mattermost-supported plugin diagnostic data is included where applicable.
|
||||
|
||||
The contents of a support packet include:
|
||||
|
||||
- [metadata.yaml](#metadata)
|
||||
- `mattermost.log` (Mattermost logs)
|
||||
- `audit.log` (Mattermost audit logs)
|
||||
- `ldap.log` (AD/LDAP logs)
|
||||
- `notifications.log` (notifications logs)
|
||||
- `plugins.json` (all active and inactive plugins)
|
||||
- `sanitized_config.json` (sanitized copy of the Mattermost configuration)
|
||||
- `stats.yaml` (Mattermost usage statistics)
|
||||
- `jobs.yaml` (last runs of important jobs)
|
||||
- `diagnostics.yaml` (core plugin diagnostics data)
|
||||
- `permissions.yaml` (role & scheme information)
|
||||
- [Go performance metrics](#go-performance-metrics), including: `cpu.prof`, `heap.prof`, and `goroutines`
|
||||
- `warning.txt` (present when issues are encountered during packet generation)
|
||||
- `tsdb_dump.tar.gz` (present when the Metrics plugin is installed and the **Performance metrics** option is selected when generating the Support Packet)
|
||||
|
||||
The following additional plugin diagnostic data is included in the generated support packet when the plugin is enabled and operational:
|
||||
|
||||
- GitHub: `/github/diagnostics.yaml`
|
||||
- GitLab: `/com.github.manland.mattermost-plugin-gitlab/diagnostics.yaml`
|
||||
- Jira: `/jira/diagnostics.yaml`
|
||||
- Calls: `/com.mattermost.calls/diagnostics.yaml`
|
||||
- Boards: `/focalboard/diagnostics.yaml`
|
||||
- Playbooks: `/playbooks/diagnostics.yaml`
|
||||
- MSCalendar: `/com.mattermost.mscalendar/diagnostics.yaml`
|
||||
- Google Calendar: `/com.mattermost.gcal/diagnostics.yaml`
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="prior-to-v10-5" label="Prior to v10.5">
|
||||
|
||||
From Mattermost v10.4, a new `diagnostics.yaml` file includes Mattermost Calls diagostics data, including plugin version, calls and active session counts, as well as average duration and participant counts.
|
||||
|
||||
- [metadata.yaml](#metadata)
|
||||
- `mattermost.log`
|
||||
- `plugins.json`
|
||||
- `sanitized_config.json`
|
||||
- `support_packet.yaml`
|
||||
- `diagnostics.yaml` (core plugin diagnostics data)
|
||||
- [Go performance metrics](#go-performance-metrics), including: `cpu.prof`, `heap.prof`, and `goroutines`
|
||||
- `warning.txt` (present when issues are encountered during packet generation)
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
<Note>
|
||||
|
||||
- LDAP groups are not included during Support Packet generation. Only `LDAP Version` and `LDAP Vendor` are included when present. These values are included in the `support_packet.yaml` file.
|
||||
- From Mattermost v9.11, `LDAP Vendor` errors are included in the Support Packet. If fetching the LDAP Vendor name fails, the Support Packet generation includes the error in `warning.txt`. If no LDAP Vendor name is found, the Support Packet lists them as `unknown`.
|
||||
|
||||
</Note>
|
||||
|
||||
## Metadata
|
||||
|
||||
From Mattermost v9.11, generated Support Packets include a `metadata.yaml` file that contains the following information.
|
||||
|
||||
<table style={{width: '99%'}}>
|
||||
<colgroup>
|
||||
<col style={{width: '12%'}} />
|
||||
<col style={{width: '12%'}} />
|
||||
<col style={{width: '59%'}} />
|
||||
<col style={{width: '14%'}} />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><strong>Field name</strong></th>
|
||||
<th><strong>Required/Optional</strong></th>
|
||||
<th><strong>Description</strong></th>
|
||||
<th><blockquote>
|
||||
<p><strong>Example</strong></p>
|
||||
</blockquote></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>version</td>
|
||||
<td>Required</td>
|
||||
<td>Version of the schema that the current metadata file is compatible with. Current version is 1.</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>type</td>
|
||||
<td>Required</td>
|
||||
<td>The type of the packet. Each type of Support Packet can be mapped to a specific component generating the Support Packet.</td>
|
||||
<td>mattermost</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>generated_at</td>
|
||||
<td>Required</td>
|
||||
<td>The date and time the packet was created. Value is in epoch (ms).</td>
|
||||
<td>1707473288731</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>server_version</td>
|
||||
<td>Required</td>
|
||||
<td>Version of the server that the Support Packet was generated at. Semver is expected.</td>
|
||||
<td>9.1.1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>server_id</td>
|
||||
<td>Required</td>
|
||||
<td>Unique identifier of the server. Expected to be 26 characters or longer.</td>
|
||||
<td>9qpiszyjr3g8bxda35abcd1234</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>license_id</td>
|
||||
<td>Optional</td>
|
||||
<td>Unique identifier of the current server's license. Expected to be 26 characters or longer. This field is empty when there's no license.</td>
|
||||
<td>abcdejisd67yigqhmkz4ho1234</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>customer_id</td>
|
||||
<td>Optional</td>
|
||||
<td>The id of the customer, as defined in the license file. Expected to be 26 characters or longer. Empty when there's no license.</td>
|
||||
<td>a1b2c3d4qbbr5cpkbpbmef123h</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>extras</td>
|
||||
<td>Optional</td>
|
||||
<td>Key/value of any additional information, specific to the plugin/component that generated the file. Can be useful for identifying the contents of the data. Consider adding plugin (or component) versions in order to set expectation regarding the contents of this object.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>extras.plugin_id</td>
|
||||
<td>Required for plugins</td>
|
||||
<td>The ID of the plugin.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>extras.plugin_version</td>
|
||||
<td>Required for plugins</td>
|
||||
<td>The version of the plugin.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
For example:
|
||||
|
||||
``` yaml
|
||||
version: 1
|
||||
type: support-packet
|
||||
generated_at: 1622569200
|
||||
server_version: 9.1.1
|
||||
server_id: 8fqk9rti13fmpxdd5934a3xsxh
|
||||
license_id: 3g3pqn8in3brzjkozcn1kdidgr
|
||||
customer_id: 74cmws7gf3ykpj31car7zahsny
|
||||
extras:
|
||||
plugin_version: 0.1.0
|
||||
```
|
||||
|
||||
## Go performance metrics
|
||||
|
||||
The Support Packet contains 3 go runtime profiling files:
|
||||
|
||||
- `cpu.prof` contains a 5-second CPU profile
|
||||
- `heap.prof` contains a heap profile
|
||||
- `goroutines` contains a dump of all the running go routines
|
||||
|
||||
These files can be read using [pprof](https://golang.google.cn/cmd/pprof/).
|
||||
|
||||
Use `go tool pprof -web X` to open a visualization of the profile in your browser, replacing `X` with the profile's file name.
|
||||
|
||||
## Load metric
|
||||
|
||||
From Mattermost v10.10, the **Load Metric** field under **Product Menu \> About Mattermost** displays monthly active users relative to the total number of licensed users. This value gives Mattermost support teams a contextual reference point for understanding deployment active usage for troubleshooting and guidance. It isn’t a comprehensive performance monitoring tool or health indicator, but serves as a supplementary data point when traditional diagnostic methods aren’t available.
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: "Install a license key"
|
||||
---
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
You can use the System Console or the mmctl tools to add or change a Mattermost license key.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="use-system-console" label="Use System Console">
|
||||
|
||||
1. Go to **System Console \> About \> Edition and License**.
|
||||
2. Upload your license key file.
|
||||
|
||||
Once the key is uploaded and installed, the details of your license are displayed.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="use-mmctl" label="Use mmctl">
|
||||
|
||||
Use the [mmctl license upload](/administration-guide/manage/mmctl-command-line-tool#mmctl-license-upload) command to upload a new license or replace an existing license file with a new one. When complete, restart the Mattermost server. If you're running in a [High Availability](/deployment-guide/server/high-availability-cluster-based-deployment) environment, the new license file must be updated to every node.
|
||||
|
||||
``` sh
|
||||
mmctl license upload [license] [flags]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
<Note>
|
||||
|
||||
- From Mattermost v10.11, the option to add a license is disabled when the license is set using an [environment variable](/administration-guide/configure/environment-configuration-settings#license-file-location).
|
||||
- Enterprise customers with the Premier Support add-on can request a staging license for testing.
|
||||
- Removing a Mattermost Enterprise or Professional license key won't remove the configuration for Enterprise settings; however, these features won't function until an Enterprise or Professional license key is applied.
|
||||
- When you're using [High Availability](/deployment-guide/server/high-availability-cluster-based-deployment), it's critical to ensure that all servers in the cluster have same Enterprise license properly installed to prevent multi-node clusters from failing. An Enterprise license is required for High Availability to work.
|
||||
- When you apply an Enterprise license key to a server previously licensed for Professional, Professional features retain their configuration settings in Enterprise.
|
||||
- When you apply a Professional license to a server previously licensed for Enterprise, Enterprise features retain their configuration but will no longer be accessible for use.
|
||||
|
||||
</Note>
|
||||
|
||||
## Change an existing license key
|
||||
|
||||
You don't need to wait for your current license key to expire before replacing it with a new license from Mattermost. The server only checks for seat count and license end date, not the start date, so you can apply a new license as soon as you receive it. However, ensure your new license is for a seat count that's greater than or equal to your current total number of Mattermost users.
|
||||
|
||||
<Tip>
|
||||
|
||||
To review license usage before uploading a new key, go to **System Console \> Reporting \> System Statistics**. The **Total Activated Users** field shows the primary paid seat count used for license validation. Review **Single-channel Guests** separately because guests in exactly one active channel are tracked outside the primary paid seat count, are free up to a 1:1 ratio with licensed seats, and generate warnings instead of hard enforcement when that allowance is exceeded. Only active channels count toward guest channel access for billing. Archived channels are excluded.
|
||||
|
||||
</Tip>
|
||||
|
||||
Follow these steps to change your license key:
|
||||
|
||||
1. Go to **System Console \> About \> Edition and License**.
|
||||
2. From Mattermost v6.7, simply upload your new license key file.
|
||||
|
||||
<Note>
|
||||
|
||||
If you're running a Mattermost release older than v6.7, select **Remove Enterprise License and Downgrade Server** to clear the license from the server and refresh the System Console first before uploading the new key.
|
||||
|
||||
</Note>
|
||||
|
||||
## License key storage
|
||||
|
||||
Once you've uploaded your license key to your Mattermost server, it's stored in your SQL database at `mattermost.Licenses`. You can check what keys are on your server by running `select * from mattermost.Licenses;`.
|
||||
|
||||
[Book a live demo](https://mattermost.com/request-demo/) or [talk to a Mattermost expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization's secure collaboration needs. Or try Mattermost yourself with a [1-hour preview](https://mattermost.com/sign-up/) for instant access to a live sandbox environment.
|
||||
@@ -0,0 +1,802 @@
|
||||
---
|
||||
title: "Manually migrate from MySQL to PostgreSQL"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Migrating a MySQL database to PostgreSQL manually involves the following steps:
|
||||
|
||||
- [install recommended tools](#tool-recommendations)
|
||||
- [familiarize yourself with system requirements and configurations](#system-requirements-and-configurations-for-manual-migrations)
|
||||
- [ensure migration prerequisites are met](#before-a-manual-migration)
|
||||
- [review schema differences](#schema-diffs)
|
||||
- [prepare a target database](#prepare-target-database)
|
||||
- [migrate the data](#migrate-the-data)
|
||||
- [complete post-migration wrap-up activities](#after-the-migration)
|
||||
|
||||
<Tip>
|
||||
|
||||
See the [plugin migrations](#plugin-migrations) section for details on migrating collaborative playbooks and Boards.
|
||||
|
||||
</Tip>
|
||||
|
||||
Not sure upgrading manually is the right path forward? Mattermost customers looking for tailored guidance based on their Mattermost deployment can contact a [Mattermost Expert](https://mattermost.com/contact-sales/).
|
||||
|
||||
## Tool recommendations
|
||||
|
||||
If you prefer to migrate to Postgres manually, we recommend the following tools for the migration process:
|
||||
|
||||
- [pgloader](#pgloader)
|
||||
- [morph](#morph)
|
||||
- [dbcmp (optional)](#dbcmp-optional)
|
||||
|
||||
This page includes instructions on how to install each of these tools, and then proceed with the database migration.
|
||||
|
||||
Once you've installed the necessary tools, review the [system requirements and configurations](#system-requirements-and-configurations-for-manual-migrations) documentation, and know what's required [before starting your migration](#before-a-manual-migration) to prepare for your migration.
|
||||
|
||||
Start your migration by [preparing your target database](#prepare-target-database), then [migrate the data](#migrate-the-data), and complete all [post-migration steps](#after-the-migration).
|
||||
|
||||
See the [plugin migrations](#plugin-migrations) documentation for details on migrating collaborative playbooks and boards.
|
||||
|
||||
### pgloader
|
||||
|
||||
Use the `pgloader` tool to migrate your data from MySQL to PostgreSQL.
|
||||
|
||||
#### Install pgloader
|
||||
|
||||
To install `pgloader`, see the official [installation guide](https://pgloader.readthedocs.io/en/latest/install.html).
|
||||
|
||||
<Note>
|
||||
|
||||
If you are using MySQL v8: Due to a [known bug](https://github.com/dimitri/pgloader/issues/1183) in pgloader-compiled binaries, you need to compile pgloader from the source. Please follow the steps [here](https://pgloader.readthedocs.io/en/latest/install.html#build-from-sources) to build from the source.
|
||||
|
||||
</Note>
|
||||
|
||||
Alternatively, you may want to use our `mattermost-pgloader` Docker image to avoid installing or building `pgloader`. See the documentation below for details.
|
||||
|
||||
#### Use pgloader
|
||||
|
||||
##### Pull the Docker image and verify pgloader
|
||||
|
||||
For a manual migration, run the following command to pull the `mattermost-pgloader` image and verify that pgloader is working correctly:
|
||||
|
||||
``` sh
|
||||
docker run -it --rm -v $(pwd):/home/migration mattermost/mattermost-pgloader:latest pgloader --version
|
||||
```
|
||||
|
||||
This command pulls the `mattermost/mattermost-pgloader:latest` image and runs `pgloader` to check its version and ensure it works as expected.
|
||||
|
||||
##### Map local directory
|
||||
|
||||
Use the `-v $(pwd):/home/migration` flag to map your current working directory to the Docker container. This allows you to use your local directory for storing logs and other files.
|
||||
|
||||
##### Set network configuration
|
||||
|
||||
Depending on your network requirements, set the `--network` flag accordingly. For example, to access localhost, you need to set the network to `host`.
|
||||
|
||||
### morph
|
||||
|
||||
The `morph` tool creates the PostgreSQL schema.
|
||||
|
||||
<Note>
|
||||
|
||||
Both `morph` and `dbcmp` requires Go toolchain. To install Go compiler, follow the [Go documentation](https://go.dev/doc/install).
|
||||
|
||||
</Note>
|
||||
|
||||
#### Install morph
|
||||
|
||||
You can install morph CLI by running the following command:
|
||||
|
||||
``` sh
|
||||
go install github.com/mattermost/morph/cmd/morph@v1
|
||||
```
|
||||
|
||||
### dbcmp (Optional)
|
||||
|
||||
The `dbcmp` tool enables you to compare the data following the migration by comparing every table and reporting whether there is a diversion between two schemas.
|
||||
|
||||
#### Install dbcmp
|
||||
|
||||
You can install [dbcmp](https://github.com/mattermost/dbcmp) by running the following command:
|
||||
|
||||
``` sh
|
||||
go install github.com/mattermost/dbcmp/cmd/dbcmp@latest
|
||||
```
|
||||
|
||||
## System requirements and configurations for manual migrations
|
||||
|
||||
Before starting a manual migration process, it's essential to ensure that your system meets the necessary requirements for a smooth and efficient migration. We strongly recommend the following system specifications and adjustments:
|
||||
|
||||
- Ensure you have enough system memory resources. 16GB of RAM is recommended as a default. In scenarios where system memory is insufficient, users can fine-tune pgloader settings, such as the `number of workers`, `prefetch rows`, and especially `rows per range` if `concurrency` is set above `1`. These adjustments can help optimize resource utilization based on available system resources. For further detail see [pgloader documentation](https://pgloader.readthedocs.io/en/latest/batches.html).
|
||||
- A multi-core processor with sufficient processing power is recommended for the migration process, especially when dealing with large datasets.
|
||||
- Ensure that there is enough disk space available for storing both the MySQL and PostgreSQL databases, as well as any temporary files generated during the migration process. The amount of required disk space depends on the size of the databases being migrated.
|
||||
- To reduce migration time further, users may choose to manually drop indexes on the target PostgreSQL database before initiating the migration process. This approach can potentially accelerate the migration by reducing overhead with index builds during data insertion.
|
||||
|
||||
### Before a manual migration
|
||||
|
||||
<Important>
|
||||
|
||||
This guide requires a schema of v7.1 ESR or later. So, if you have an earlier version and planning to migrate, please update your Mattermost Server to v7.1 at a minimum. See the [extended support releases](/product-overview/release-policy#extended-support-releases) documentation for details.
|
||||
|
||||
- Back up your MySQL data.
|
||||
- Confirm your Mattermost version. See the **About** modal for details.
|
||||
- Schedule the migration window. This process requires you to stop the Mattermost Server during the migration.
|
||||
- See the [schema-diffs](#schema-diffs) section to ensure data compatibility between schemas.
|
||||
- Prepare your PostgreSQL environment by creating a database and user. See the [database](/deployment-guide/server/prepare-database) documentation for details.
|
||||
- On [newer versions](https://www.postgresql.org/docs/release/15.0/) of PostgreSQL, newly created users do not have access to `public` schema. The access should be explicitly granted by running `GRANT ALL ON SCHEMA public to mmuser`.
|
||||
|
||||
</Important>
|
||||
|
||||
### Schema diffs
|
||||
|
||||
Before the manual migration, due to differences between the two schemas, some manual steps may be required for an error-free migration.
|
||||
|
||||
#### Text to character varying
|
||||
|
||||
We encourage you to check if the sizes are consistent within the PostgreSQL schema limits since the Mattermost MySQL schema uses the `text` column type in the various tables instead of `varchar` representation in the PostgreSQL schema.
|
||||
|
||||
You can check if there are any required deletions or updates. For example, to do so in the `Audits` table/`Action` column; run:
|
||||
|
||||
``` sql
|
||||
SELECT FROM mattermost.Audits where LENGTH(Action) > 512;
|
||||
```
|
||||
|
||||
The following table shows the deletions or updates you can proceed with that don't incur further consequences.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Table</th>
|
||||
<th>Column</th>
|
||||
<th>Data type casting</th>
|
||||
<th>Consequence on deletion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Audits</td>
|
||||
<td>Action</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>No side effect on how the application works (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Audits</td>
|
||||
<td>ExtraInfo</td>
|
||||
<td>text -> varchar(1024)</td>
|
||||
<td>No side effect on how the application works (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ClusterDiscovery</td>
|
||||
<td>HostName</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>No side effect on how the application works (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Commands</td>
|
||||
<td>IconURL</td>
|
||||
<td>text -> varchar(1024)</td>
|
||||
<td>The field can be deleted or updated with a new URL.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Commands</td>
|
||||
<td>AutoCompleteDesc</td>
|
||||
<td>text -> varchar(1024)</td>
|
||||
<td>The field can be deleted or rewritten.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Commands</td>
|
||||
<td>AutoCompleteHint</td>
|
||||
<td>text -> varchar(1024)</td>
|
||||
<td>The field can be deleted or rewritten.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RemoteClusters</td>
|
||||
<td>Topics</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>The field can be removed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Systems</td>
|
||||
<td>Value</td>
|
||||
<td>text -> varchar(1024)</td>
|
||||
<td>Edge case, ideally should never happen.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
The following table shows several occurrences where the schema can differ and data size constraints within the PostgreSQL schema can result in errors. Each table/row requires individual inspection hence we added the possible consequence of deletion.
|
||||
|
||||
<Tip>
|
||||
|
||||
Several reports have been received from our community that the `LinkMetadata` and `FileInfo` tables had some overflows, so we recommend checking these tables in particular. Please check if your data in the MySQL schema exceeds these limitations.
|
||||
|
||||
</Tip>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Table</th>
|
||||
<th>Column</th>
|
||||
<th>Data type casting</th>
|
||||
<th>Consequence on deletion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Compliances</td>
|
||||
<td>Keywords</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>The filter for compliance needs to be updated.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Compliances</td>
|
||||
<td>Emails</td>
|
||||
<td>text -> varchar(1024)</td>
|
||||
<td>The filter for compliance needs to be updated.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FileInfo</td>
|
||||
<td>Path</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>Previous links to this file won't work (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FileInfo</td>
|
||||
<td>ThumbnailPath</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>Previous links to this file won't work (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FileInfo</td>
|
||||
<td>PreviewPath</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>Previous links to this file won't work (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FileInfo</td>
|
||||
<td>Name</td>
|
||||
<td>text -> varchar(256)</td>
|
||||
<td>Previous links to this file won't work (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FileInfo</td>
|
||||
<td>MimeType</td>
|
||||
<td>text -> varchar(256)</td>
|
||||
<td>Previous links to this file won't work (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LinkMetadata</td>
|
||||
<td>URL</td>
|
||||
<td>text -> varchar(2048)</td>
|
||||
<td>Previous links to this file won't work (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RemoteClusters</td>
|
||||
<td>SiteURL</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>Previous remote cluster will be removed (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sessions</td>
|
||||
<td>DeviceId</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>Users will be logged out on these devices (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UploadSessions</td>
|
||||
<td>FileName</td>
|
||||
<td>text -> varchar(256)</td>
|
||||
<td>The upload session will be lost (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UploadSessions</td>
|
||||
<td>Path</td>
|
||||
<td>text -> varchar(512)</td>
|
||||
<td>The upload session will be lost (The affected row needs to be deleted).</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
#### Full-text indexes
|
||||
|
||||
It's possible that some words in the `Posts` and `FileInfo` tables can exceed the [limits of the maximum token length](https://www.postgresql.org/docs/11/textsearch-limitations.html) for full-text search indexing. In these cases, we are dropping the `idx_posts_message_txt` and `idx_fileinfo_content_txt` indexes from the PostgreSQL schema, and creating these indexes after the migration by running the following queries:
|
||||
|
||||
To prevent errors during the migration, we have included following queries:
|
||||
|
||||
``` text
|
||||
DROP INDEX IF EXISTS {{ .source_db }}.idx_posts_message_txt;
|
||||
DROP INDEX IF EXISTS {{ .source_db }}.idx_fileinfo_content_txt;
|
||||
```
|
||||
|
||||
#### Unsupported unicode sequences
|
||||
|
||||
There is a specific unicode sequence that is [disallowed](https://www.postgresql.org/docs/16/datatype-json.html#DATATYPE-JSON) in PostgreSQL which is `\u0000`. There is a chance that this sequence may appear in several rows across a bunch of tables in your MySQL database. If it is the case, during the migration you will likely receive an error as following: `unsupported Unicode escape sequence: \u0000 cannot be converted to text.`. To prevent this from happening, we advise to sanitize your data before starting to the migration. You can use the following query to replace `\u0000` sequence with empty string.
|
||||
|
||||
<Note>
|
||||
|
||||
You can use this query as-is in a script, or you may need to set the delimiter to something else (e.g., `DELIMITER //`) when defining it in the MySQL console. Once you are done defining the procedure, please set the delimiter back to the original (i.e., `DELIMITER ;`).
|
||||
|
||||
</Note>
|
||||
|
||||
``` text
|
||||
CREATE PROCEDURE SanitizeUnsupportedUnicode()
|
||||
BEGIN
|
||||
DECLARE done INT DEFAULT FALSE;
|
||||
DECLARE curTableName text;
|
||||
DECLARE curColumnName text;
|
||||
DECLARE cursors CURSOR FOR
|
||||
SELECT table_name, column_name
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE data_type = 'json'
|
||||
AND table_schema = DATABASE();
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
||||
|
||||
OPEN cursors;
|
||||
|
||||
WHILE NOT DONE DO
|
||||
FETCH cursors INTO curTableName, curColumnName;
|
||||
SET @query_string = CONCAT('UPDATE ', curTableName, ' SET ', curColumnName, ' = REPLACE(', curColumnName, ', \'\\\\u0000\', \'\') WHERE ', curColumnName, ' LIKE \'%\\u0000%\';');
|
||||
|
||||
PREPARE dynamic_query FROM @query_string;
|
||||
EXECUTE dynamic_query;
|
||||
DEALLOCATE PREPARE dynamic_query;
|
||||
END WHILE;
|
||||
|
||||
CLOSE cursors;
|
||||
END;
|
||||
|
||||
CALL SanitizeUnsupportedUnicode();
|
||||
|
||||
DROP PROCEDURE IF EXISTS SanitizeUnsupportedUnicode;
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
There is also a specific byte sequence value that is not allowed and will cause an `invalid byte sequence for encoding 'UTF8': 0x00"` error during the migration. To prevent this error, you can add the `remove-null-characters` clause to the text casting rules. However, since pgloader will modify the data on the fly, there may be differences between the tables (if any are affected) during the comparison phase.
|
||||
|
||||
</Note>
|
||||
|
||||
#### Artifacts may remain from previous configurations/versions
|
||||
|
||||
Prior to `v6.4`, Mattermost was using [golang-migrate](https://github.com/golang-migrate/migrate) to handle the schema migrations. Since we don't use it anymore, we exclude the table `schema_migrations`. If you were using Mattermost before `v6.4` consider dropping this table and excluding it from comparison as well.
|
||||
|
||||
``` sql
|
||||
DROP TABLE mattermost.schema_migrations;
|
||||
```
|
||||
|
||||
Some community members have reported that they had `description` and `nextsyncat` columns in their `SharedChannelRemotes` table. These columns should be removed from the table. Consider running the following DDL to drop the columns. (This migration will be added to future versions of Mattermost).
|
||||
|
||||
``` sql
|
||||
ALTER TABLE SharedChannelRemotes DROP COLUMN description, DROP COLUMN nextsyncat;
|
||||
```
|
||||
|
||||
An error has been identified in the 96th migration that was previously released. Before proceeding with the migration, it is necessary to remove a specific column. To ensure the Threads table reaches the expected state, execute the following prepared statement:
|
||||
|
||||
``` sql
|
||||
SET @preparedStatement = (SELECT IF(
|
||||
(
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Threads'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'TeamId'
|
||||
) > 0,
|
||||
'ALTER TABLE Threads DROP COLUMN TeamId;',
|
||||
'SELECT 1'
|
||||
));
|
||||
|
||||
PREPARE alterIfExists FROM @preparedStatement;
|
||||
EXECUTE alterIfExists;
|
||||
DEALLOCATE PREPARE alterIfExists;
|
||||
```
|
||||
|
||||
#### Configuration in database
|
||||
|
||||
If you were previously utilizing a database for handling the [Mattermost configuration](/administration-guide/configure/configuration-in-your-database), those tables will not be migrated from your MySQL database with the migration [script](#migrate-the-data).
|
||||
|
||||
Two migrations are necessary:
|
||||
|
||||
- migrate database configuration to the file system
|
||||
- migrate file system configuration back to the database
|
||||
|
||||
##### Migrate database configuration to the file system
|
||||
|
||||
Use the `mmctl config migrate` command to [migrate your config](/administration-guide/manage/mmctl-command-line-tool#mmctl-config-migrate) to the file system, as follows:
|
||||
|
||||
``` sh
|
||||
mmctl config migrate "<DB_USER>:<DB_PASS>@tcp(<DB_HOST>:3306)/<DB_NAME>?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s&multiStatements=true" /opt/mattermost/config/config.json --local
|
||||
```
|
||||
|
||||
Where `<DB_USER>`, `<DB_PASS>`, `<DB_HOST>`, and `<DB_NAME>` are replaced with your environment values. Ensure you use `--local` when running this command. The first parameters (`<DB_USER>`, `<DB_PASS>`) is the database the configuration is stored in, the second parameter (`<DB_HOST>`, `<DB_NAME>`) is the file we are saving the configuration to.
|
||||
|
||||
In the configuration file, update the `SqlSettings.DataSource` and `SqlSettings.DriverName` fields to reflect new changes. To do so, open the `json` file and change the respective fields.
|
||||
|
||||
##### Migrate file system configuration back to the database
|
||||
|
||||
To save configuration back to the database, Use the `mmctl config migrate` command again and reverse the parameters. Ensure you use the new database credentials moving it back to the target database.
|
||||
|
||||
``` sql
|
||||
SELECT * FROM Configurations WHERE Active = 't';
|
||||
```
|
||||
|
||||
You should update the `SqlSettings.DataSource` and `SqlSettings.DriverName` fields accordingly. Also, note that the `MM_CONFIG` environment variable should point to the new DSN after the migration is completed.
|
||||
|
||||
## Prepare target database
|
||||
|
||||
It is essential to create tables and indexes to ensure that the PostgreSQL database schema is properly structured according to the required specifications. Since Mattermost repository contains all of the required SQL queries to achieve that, we can leverage this by running the following steps:
|
||||
|
||||
- Clone the `mattermost` repository for your specific version:
|
||||
|
||||
``` sh
|
||||
git clone -b <your current version (eg. release-7.8)> git@github.com:mattermost/mattermost.git --depth=1
|
||||
```
|
||||
|
||||
- Run all schema migrations\* on your PostgreSQL database using morph CLI with the following command:
|
||||
|
||||
``` sh
|
||||
morph apply up --driver postgres --dsn "postgres://user:pass@localhost:5432/<target_db_mame>?sslmode=disable" --path ./mattermost/db/migrations/postgres --number -1
|
||||
```
|
||||
|
||||
\* After `v8`, due to project re-organization, the migrations directory has been changed to `./mattermost/server/channels/db/migrations/postgres/` relative to where you cloned Mattermost repository. Please set `--path` flag accordingly.
|
||||
|
||||
## Migrate the data
|
||||
|
||||
Once we set the schema to a desired state, we can start migrating the **data** by running `pgloader`
|
||||
|
||||
<Note>
|
||||
|
||||
In the example below, the hosts for both databases are assumed to be in the same instance. Please update addresses accordingly if they are on different machines. Also you can test the `.load` file by simply running `pgloader` with `--dry-run` flag. For instance `pgloader --dry-run migration.load` command.
|
||||
|
||||
</Note>
|
||||
|
||||
Use the following configuration for the baseline of the data migration:
|
||||
|
||||
``` text
|
||||
LOAD DATABASE
|
||||
FROM mysql://{{ .mysql_user }}:{{ .mysql_password }}@{{ .mysql_address }}/{{ .source_db }}
|
||||
INTO pgsql://{{ .pg_user }}:{{ .pg_password }}@{{ .postgres_address }}/{{ .target_db }}
|
||||
|
||||
WITH data only,
|
||||
workers = 8, concurrency = 1,
|
||||
multiple readers per thread, rows per range = 10000,
|
||||
prefetch rows = 10000, batch rows = 2500,
|
||||
create no tables, create no indexes,
|
||||
preserve index names
|
||||
|
||||
SET PostgreSQL PARAMETERS
|
||||
maintenance_work_mem to '128MB',
|
||||
work_mem to '12MB'
|
||||
|
||||
SET MySQL PARAMETERS
|
||||
net_read_timeout = '120',
|
||||
net_write_timeout = '120'
|
||||
|
||||
CAST column Channels.Type to "channel_type" drop typemod,
|
||||
column Teams.Type to "team_type" drop typemod,
|
||||
column UploadSessions.Type to "upload_session_type" drop typemod,
|
||||
column ChannelBookmarks.Type to "channel_bookmark_type" drop typemod,
|
||||
column Drafts.Priority to text,
|
||||
type int when (= precision 11) to integer drop typemod,
|
||||
type bigint when (= precision 20) to bigint drop typemod,
|
||||
type text to varchar drop typemod using remove-null-characters,
|
||||
type tinyint when (<= precision 4) to boolean using tinyint-to-boolean,
|
||||
type json to jsonb drop typemod using remove-null-characters
|
||||
|
||||
EXCLUDING TABLE NAMES MATCHING ~<IR_>, ~<focalboard>, 'schema_migrations', 'db_migrations', 'db_lock',
|
||||
'Configurations', 'ConfigurationFiles', 'db_config_migrations', 'calls'
|
||||
|
||||
BEFORE LOAD DO
|
||||
$$ ALTER SCHEMA public RENAME TO {{ .source_db }}; $$,
|
||||
$$ TRUNCATE TABLE {{ .source_db }}.systems; $$,
|
||||
$$ DROP INDEX IF EXISTS {{ .source_db }}.idx_posts_message_txt; $$,
|
||||
$$ DROP INDEX IF EXISTS {{ .source_db }}.idx_fileinfo_content_txt; $$
|
||||
|
||||
AFTER LOAD DO
|
||||
$$ UPDATE {{ .source_db }}.db_migrations set name='add_createat_to_teamembers' where version=92; $$,
|
||||
$$ ALTER SCHEMA {{ .source_db }} RENAME TO public; $$,
|
||||
$$ SELECT pg_catalog.set_config('search_path', '"$user", public', false); $$,
|
||||
$$ ALTER USER {{ .pg_user }} SET SEARCH_PATH TO 'public'; $$;
|
||||
```
|
||||
|
||||
Once you save this configuration file, e.g. `migration.load`, you can run the `pgloader` with the following command:
|
||||
|
||||
``` sh
|
||||
pgloader migration.load > migration.log
|
||||
```
|
||||
|
||||
Feel free to contribute to and/or report your findings through your migration to us.
|
||||
|
||||
## After the migration
|
||||
|
||||
### Restore full-text indexes
|
||||
|
||||
To avoid performance regression on `Posts` and `FileInfo` table access, following queries should be executed once the migration finishes:
|
||||
|
||||
``` sql
|
||||
CREATE INDEX IF NOT EXISTS idx_posts_message_txt ON public.posts USING gin(to_tsvector('english', message));
|
||||
CREATE INDEX IF NOT EXISTS idx_fileinfo_content_txt ON public.fileinfo USING gin(to_tsvector('english', content));
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
If any of the entries in your `Posts` and `FileInfo` tables exceed the limit mentioned above, index creation query will warn with the `ERROR: string is too long for tsvector` log while trying to create these indexes. This means the content that didn't fit into a `tsvector` was ignored. If you still want to index the truncated content, you can use `substring()` function on the content while creating the indexes.
|
||||
|
||||
Start with a substring length of 1000000 and gradually decrease if the error persists:
|
||||
|
||||
</Note>
|
||||
|
||||
``` sql
|
||||
-- Start with 1000000
|
||||
CREATE INDEX IF NOT EXISTS idx_fileinfo_content_txt ON public.fileinfo USING gin(to_tsvector('english', substring(content,0,1000000)));
|
||||
|
||||
-- If that fails, try 800000
|
||||
CREATE INDEX IF NOT EXISTS idx_fileinfo_content_txt ON public.fileinfo USING gin(to_tsvector('english', substring(content,0,800000)));
|
||||
|
||||
-- Continue decreasing as needed (e.g., 600000, 500000) until the index creates successfully
|
||||
```
|
||||
|
||||
### Compare the data
|
||||
|
||||
We developed an internal tool called `dbcmp` to simplify database comparison. It checks every table in two databases and reports any differences in their schemas. However, `dbcmp` does not compare individual rows. Instead, it calculates checksum values based on a specified page-size and compares them. This means it cannot generate row-level diffs.
|
||||
|
||||
We recommend using `dbcmp` as an additional check to verify data integrity, especially if custom casting rules (beyond the defaults or those provided by us) were used during migration. Otherwise, running this tool is not necessary.
|
||||
|
||||
The tool includes a few flags to run a comparison:
|
||||
|
||||
``` sh
|
||||
Usage:
|
||||
dbcmp [flags]
|
||||
|
||||
Flags:
|
||||
--exclude strings exclude tables from comparison, takes comma-separated values.
|
||||
--include strings include only matching tables for comparison, takes comma-separated values.
|
||||
-h, --help help for dbcmp
|
||||
--source string source database dsn
|
||||
--target string target database dsn
|
||||
-v, --version version for dbcmp
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
`--exclude` and `--include` flags are mutually exclusive and they can't be used together.
|
||||
|
||||
</Note>
|
||||
|
||||
For our case, we can simply run the following command:
|
||||
|
||||
``` sh
|
||||
dbcmp --source "${MYSQL_DSN}" --target "${POSTGRES_DSN} " --include="posts,users"
|
||||
```
|
||||
|
||||
An example command would look like: `dbcmp --source "user:password@tcp(address:3306)/db_name --target "postgres://user:password@address:5432/db_name`
|
||||
|
||||
<Note>
|
||||
|
||||
`POSTGRES_DSN` should start with a `postgres://` prefix. This way `dbcmp` decides which driver to use while connecting to a database.
|
||||
|
||||
</Note>
|
||||
|
||||
Another exclusion we are making is in the `db_migrations` table which has a small difference (a typo in a single migration name) and creates a diff. Since we created the PostgreSQL schema with morph, and the official `mattermost` source, we can skip it safely without concerns. On the other hand, `systems` table may contain additional diffs if there were extra keys added during some of the migrations. Consider excluding the `systems` table if you run into issues, and perform a manual comparison as the data in the `systems` table is relatively smaller in size.
|
||||
|
||||
<Note>
|
||||
|
||||
If the `remove-null-characters` transform function is utilized during the migration and there were `0x00` byte sequences in the MySQL database, those tables will have differences during the comparison phase.
|
||||
|
||||
</Note>
|
||||
|
||||
### Restore the search path
|
||||
|
||||
If you closely examine the `pgloader` configuration file (e.g., `migration.load`), you will notice that the `search_path` of the database user is set to `public`. This is the only requirement for the Mattermost application. However, if you need to include other schemas in the search path, you should modify the `search_path` accordingly to meet your specific requirements.
|
||||
|
||||
## Plugin migrations
|
||||
|
||||
On the plugin side, we are going to take a different approach from what we have done above. We are not going to use `morph` tool to create tables and indexes this time. We are going to utilize `pgloader` to create the tables on behalf of us. The reason for doing so is that collaborative playbooks and boards leverage application logic to facilitate SQL queries. But we don't want to use any level of application at this point.
|
||||
|
||||
### Collaborative playbooks
|
||||
|
||||
The `pgloader` configuration provided for playbooks is based on `v1.38.1` and the plugin should be at least `v1.36.0` to perform the migration.
|
||||
|
||||
Once we are ready to migrate, we can start migrating the **schema** and the **data** by running `pgloader`
|
||||
|
||||
Use the following configuration for the baseline of the data migration:
|
||||
|
||||
``` text
|
||||
LOAD DATABASE
|
||||
FROM mysql://{{ .mysql_user }}:{{ .mysql_password }}@{{ .mysql_address }}/{{ .source_db }}
|
||||
INTO pgsql://{{ .pg_user }}:{{ .pg_password }}@{{ .postgres_address }}/{{ .target_db }}
|
||||
|
||||
WITH include drop, create tables, create indexes, no foreign keys,
|
||||
workers = 8, concurrency = 1,
|
||||
multiple readers per thread, rows per range = 50000,
|
||||
preserve index names
|
||||
|
||||
SET PostgreSQL PARAMETERS
|
||||
maintenance_work_mem to '128MB',
|
||||
work_mem to '12MB'
|
||||
|
||||
SET MySQL PARAMETERS
|
||||
net_read_timeout = '120',
|
||||
net_write_timeout = '120'
|
||||
|
||||
CAST column IR_ChannelAction.ActionType to text drop typemod,
|
||||
column IR_ChannelAction.TriggerType to text drop typemod,
|
||||
column IR_Incident.ChecklistsJSON to "json" drop typemod
|
||||
|
||||
INCLUDING ONLY TABLE NAMES MATCHING
|
||||
~/IR_/
|
||||
|
||||
BEFORE LOAD DO
|
||||
$$ ALTER SCHEMA public RENAME TO {{ .source_db }}; $$
|
||||
|
||||
AFTER LOAD DO
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_ChannelAction ALTER COLUMN ActionType TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_ChannelAction ALTER COLUMN TriggerType TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ReminderMessageTemplate TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ReminderMessageTemplate SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedInvitedUserIDs TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedInvitedUserIDs SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedWebhookOnCreationURLs TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedWebhookOnCreationURLs SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedInvitedGroupIDs TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedInvitedGroupIDs SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN Retrospective TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN Retrospective SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN MessageOnJoin TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN MessageOnJoin SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedWebhookOnStatusUpdateURLs TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedWebhookOnStatusUpdateURLs SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN CategoryName TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN CategoryName SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedBroadcastChannelIds TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ConcatenatedBroadcastChannelIds SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ChannelIDToRootID TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Incident ALTER COLUMN ChannelIDToRootID SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ReminderMessageTemplate TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ReminderMessageTemplate SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedInvitedUserIDs TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedInvitedUserIDs SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedWebhookOnCreationURLs TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedWebhookOnCreationURLs SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedInvitedGroupIDs TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedInvitedGroupIDs SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN MessageOnJoin TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN MessageOnJoin SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN RetrospectiveTemplate TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN RetrospectiveTemplate SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedWebhookOnStatusUpdateURLs TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedWebhookOnStatusUpdateURLs SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedSignalAnyKeywords TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedSignalAnyKeywords SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN CategoryName TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN CategoryName SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ChecklistsJSON TYPE JSON USING ChecklistsJSON::JSON; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedBroadcastChannelIds TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ConcatenatedBroadcastChannelIds SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN RunSummaryTemplate TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN RunSummaryTemplate SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ChannelNameTemplate TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Playbook ALTER COLUMN ChannelNameTemplate SET DEFAULT ''::text; $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_PlaybookMember ALTER COLUMN Roles TYPE varchar(65536); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Category_Item ADD CONSTRAINT ir_category_item_categoryid FOREIGN KEY (CategoryId) REFERENCES {{ .source_db }}.IR_Category(Id); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Metric ADD CONSTRAINT ir_metric_metricconfigid FOREIGN KEY (MetricConfigId) REFERENCES {{ .source_db }}.IR_MetricConfig(Id); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Metric ADD CONSTRAINT ir_metric_incidentid FOREIGN KEY (IncidentId) REFERENCES {{ .source_db }}.IR_Incident(Id); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_MetricConfig ADD CONSTRAINT ir_metricconfig_playbookid FOREIGN KEY (PlaybookId) REFERENCES {{ .source_db }}.IR_Playbook(Id); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_PlaybookAutoFollow ADD CONSTRAINT ir_playbookautofollow_playbookid FOREIGN KEY (PlaybookId) REFERENCES {{ .source_db }}.IR_Playbook(Id); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_PlaybookMember ADD CONSTRAINT ir_playbookmember_playbookid FOREIGN KEY (PlaybookId) REFERENCES {{ .source_db }}.IR_Playbook(Id); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_Run_Participants ADD CONSTRAINT ir_run_participants_incidentid FOREIGN KEY (IncidentId) REFERENCES {{ .source_db }}.IR_Incident(Id); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_StatusPosts ADD CONSTRAINT ir_statusposts_incidentid FOREIGN KEY (IncidentId) REFERENCES {{ .source_db }}.IR_Incident(Id); $$,
|
||||
$$ ALTER TABLE {{ .source_db }}.IR_TimelineEvent ADD CONSTRAINT ir_timelineevent_incidentid FOREIGN KEY (IncidentId) REFERENCES {{ .source_db }}.IR_Incident(Id); $$,
|
||||
$$ CREATE UNIQUE INDEX IF NOT EXISTS ir_playbookmember_playbookid_memberid_key on {{ .source_db }}.IR_PlaybookMember(PlaybookId,MemberId); $$,
|
||||
$$ CREATE INDEX IF NOT EXISTS ir_statusposts_incidentid_postid_key on {{ .source_db }}.IR_StatusPosts(IncidentId,PostId); $$,
|
||||
$$ CREATE INDEX IF NOT EXISTS ir_playbookmember_playbookid on {{ .source_db }}.IR_PlaybookMember(PlaybookId); $$,
|
||||
$$ ALTER SCHEMA {{ .source_db }} RENAME TO public; $$,
|
||||
$$ SELECT pg_catalog.set_config('search_path', '"$user", public', false); $$,
|
||||
$$ ALTER USER {{ .pg_user }} SET SEARCH_PATH TO 'public'; $$;
|
||||
```
|
||||
|
||||
``` sh
|
||||
pgloader playbooks.load > playbooks_migration.log
|
||||
```
|
||||
|
||||
### Focalboard
|
||||
|
||||
As of `v9.0` Boards will transition to being fully community supported as the Focalboard plugin. Hence this guide covers only version `v7.10.x` of the schema. [Official announcement](/product-overview/deprecated-features#mattermost-server-v900).
|
||||
|
||||
Once we are ready to migrate, we can start migrating the **schema** and the **data** by running `pgloader`
|
||||
|
||||
Use the following configuration for the baseline of the data migration:
|
||||
|
||||
``` text
|
||||
LOAD DATABASE
|
||||
FROM mysql://{{ .mysql_user }}:{{ .mysql_password }}@{{ .mysql_address }}/{{ .source_db }}
|
||||
INTO pgsql://{{ .pg_user }}:{{ .pg_password }}@{{ .postgres_address }}/{{ .target_db }}
|
||||
|
||||
WITH include drop, create tables, create indexes, reset sequences,
|
||||
workers = 8, concurrency = 1,
|
||||
multiple readers per thread, rows per range = 50000,
|
||||
preserve index names
|
||||
|
||||
SET PostgreSQL PARAMETERS
|
||||
maintenance_work_mem to '128MB',
|
||||
work_mem to '12MB'
|
||||
|
||||
SET MySQL PARAMETERS
|
||||
net_read_timeout = '120',
|
||||
net_write_timeout = '120'
|
||||
|
||||
CAST column focalboard_blocks.fields to "json" drop typemod,
|
||||
column focalboard_blocks_history.fields to "json" drop typemod,
|
||||
column focalboard_schema_migrations.name to "varchar" drop typemod,
|
||||
column focalboard_sessions.props to "json" drop typemod,
|
||||
column focalboard_teams.settings to "json" drop typemod,
|
||||
column focalboard_users.props to "json" drop typemod,
|
||||
type int when (= precision 11) to int4 drop typemod,
|
||||
type json to jsonb drop typemod
|
||||
|
||||
INCLUDING ONLY TABLE NAMES MATCHING
|
||||
~/focalboard/
|
||||
|
||||
BEFORE LOAD DO
|
||||
$$ ALTER SCHEMA public RENAME TO {{ .source_db }}; $$
|
||||
|
||||
AFTER LOAD DO
|
||||
$$ UPDATE {{ .source_db }}.focalboard_blocks SET "fields" = '{}'::json WHERE "fields"::text = ''; $$,
|
||||
$$ UPDATE {{ .source_db }}.focalboard_blocks_history SET "fields" = '{}'::json WHERE "fields"::text = ''; $$,
|
||||
$$ UPDATE {{ .source_db }}.focalboard_sessions SET "props" = '{}'::json WHERE "props"::text = ''; $$,
|
||||
$$ UPDATE {{ .source_db }}.focalboard_teams SET "settings" = '{}'::json WHERE "settings"::text = ''; $$,
|
||||
$$ UPDATE {{ .source_db }}.focalboard_users SET "props" = '{}'::json WHERE "props"::text = ''; $$,
|
||||
$$ ALTER SCHEMA {{ .source_db }} RENAME TO public; $$,
|
||||
$$ SELECT pg_catalog.set_config('search_path', '"$user", public', false); $$,
|
||||
$$ ALTER USER {{ .pg_user }} SET SEARCH_PATH TO 'public'; $$;
|
||||
```
|
||||
|
||||
``` sh
|
||||
pgloader focalboard.load > focalboard_migration.log
|
||||
```
|
||||
|
||||
### Calls
|
||||
|
||||
If you are running a version of Mattermost that is greater than `v9.9` or the Calls plugin above `v0.27`, you can opt to migrate the data for the plugin. We are going to take a similar approach with Boards and Playbooks migration and let pgloader create the tables.
|
||||
|
||||
Once we are ready to migrate, we can start migrating the **schema** and the **data** by running `pgloader`
|
||||
|
||||
Use the following configuration for the baseline of the data migration:
|
||||
|
||||
``` text
|
||||
LOAD DATABASE
|
||||
FROM mysql://{{ .mysql_user }}:{{ .mysql_password }}@{{ .mysql_address }}/{{ .source_db }}
|
||||
INTO pgsql://{{ .pg_user }}:{{ .pg_password }}@{{ .postgres_address }}/{{ .target_db }}
|
||||
|
||||
WITH include drop, create tables, create indexes, reset sequences,
|
||||
workers = 8, concurrency = 1,
|
||||
multiple readers per thread, rows per range = 50000,
|
||||
preserve index names
|
||||
|
||||
SET PostgreSQL PARAMETERS
|
||||
maintenance_work_mem to '128MB',
|
||||
work_mem to '12MB'
|
||||
|
||||
SET MySQL PARAMETERS
|
||||
net_read_timeout = '120',
|
||||
net_write_timeout = '120'
|
||||
|
||||
CAST type json to jsonb drop typemod
|
||||
|
||||
INCLUDING ONLY TABLE NAMES MATCHING
|
||||
~/calls/
|
||||
|
||||
BEFORE LOAD DO
|
||||
$$ ALTER SCHEMA public RENAME TO {{ .source_db }}; $$
|
||||
|
||||
AFTER LOAD DO
|
||||
$$ ALTER SCHEMA {{ .source_db }} RENAME TO public; $$,
|
||||
$$ SELECT pg_catalog.set_config('search_path', '"$user", public', false); $$,
|
||||
$$ ALTER USER {{ .pg_user }} SET SEARCH_PATH TO 'public'; $$;
|
||||
```
|
||||
|
||||
``` sh
|
||||
pgloader calls.load > calls_migration.log
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See [troubleshooting errors during migration from MySQL to PostgreSQL](/administration-guide/manage/admin/postgres-migration#troubleshooting)
|
||||
12
docs/main/administration-guide/manage/admin/migration.mdx
Normal file
12
docs/main/administration-guide/manage/admin/migration.mdx
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: "Migrate"
|
||||
---
|
||||
Getting data in and out of a Mattermost deployment, moving onto Mattermost from another platform, and moving an existing deployment onto different infrastructure.
|
||||
|
||||
- [Bulk import data](/administration-guide/onboard/bulk-loading-data) - Import users, teams, channels, and posts from a JSONL file.
|
||||
- [Bulk export data](/administration-guide/manage/bulk-export-tool) - Export users, teams, channels, and posts to a JSONL file.
|
||||
- [Migrate from MySQL to PostgreSQL](/administration-guide/manage/admin/postgres-migration) - Move your database, using the migration assist tool or by hand.
|
||||
- [Migrate to FIPS-compliant images](/administration-guide/manage/admin/fips-migration) - Switch an existing Docker or Kubernetes deployment to the FIPS-compliant Mattermost images.
|
||||
- [Migrate from another platform](/administration-guide/onboard/migrating-to-mattermost) - Move from Slack, Rocket.Chat, or GitLab Omnibus, with the [migration announcement email template](/administration-guide/onboard/migration-announcement-email) for telling your users.
|
||||
|
||||
Import and export share the same JSONL format, so the [bulk import data](/administration-guide/onboard/bulk-loading-data) page is also the format reference for export files.
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: "Monitoring and performance"
|
||||
---
|
||||
Keeping a running deployment healthy: what to measure, where to send it, and what to collect when something goes wrong.
|
||||
|
||||
## Metrics and dashboards
|
||||
|
||||
- [Collect performance metrics](/administration-guide/scale/collect-performance-metrics) - Turn on the metrics endpoint and decide what to scrape.
|
||||
- [Deploy Prometheus and Grafana for performance monitoring](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring) - Stand up the monitoring stack.
|
||||
- [Performance monitoring metrics](/administration-guide/scale/performance-monitoring-metrics) - What each metric means.
|
||||
- [Performance alerting](/administration-guide/scale/performance-alerting) - Alert thresholds worth setting, and why.
|
||||
- [Push notification health targets](/administration-guide/scale/push-notification-health-targets) - Healthy delivery latency and failure rates.
|
||||
|
||||
## Logging
|
||||
|
||||
- [Mattermost logging](/administration-guide/manage/logging) - Configure what the server logs and where.
|
||||
- [Deploy Grafana Loki for centralized logging](/administration-guide/scale/deploy-grafana-loki-for-centralized-logging) - Aggregate logs across servers.
|
||||
|
||||
## Health and diagnostics
|
||||
|
||||
- [Optimize your Mattermost workspace](/administration-guide/configure/optimize-your-workspace) - Run the System Console health check and act on what it finds.
|
||||
- [Statistics](/administration-guide/manage/statistics) - Site and team usage statistics.
|
||||
- [Configure server health check probes](/administration-guide/manage/configure-health-check-probes) - Liveness and readiness endpoints for your orchestrator.
|
||||
- [Request a server health check](/administration-guide/manage/request-server-health-check) - Have Mattermost review your deployment.
|
||||
- [Generate a support packet](/administration-guide/manage/admin/generating-support-packet) - Collect logs and configuration for a support ticket.
|
||||
- [Mattermost error codes](/administration-guide/manage/admin/error-codes) - Look up an error a user reported.
|
||||
|
||||
## Telemetry
|
||||
|
||||
- [Telemetry](/administration-guide/manage/telemetry) - What Mattermost collects, and how to turn it off.
|
||||
- [Ensure releases perform at scale](/administration-guide/scale/ensuring-releases-perform-at-scale) - How Mattermost load-tests each release.
|
||||
@@ -0,0 +1,206 @@
|
||||
---
|
||||
title: "Automated PostgreSQL migration"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Migrating databases can be a daunting task, and it can be easy to overlook or misinterpret some of the required steps if you haven't performed a migration before. Our `migration-assist` tool provides an efficient, error-free migration experience that automates the [tasks to be executed](/administration-guide/manage/admin/manual-postgres-migration), even in air-gapped deployment environments.
|
||||
|
||||
Not sure this tool is right for your Mattermost deployment? Mattermost customers looking for tailored guidance based on their Mattermost deployment can contact a [Mattermost Expert](https://mattermost.com/contact-sales/).
|
||||
|
||||
## Install
|
||||
|
||||
Download the Mattermost `migration-assist` tool from the GitHub repository [releases page](https://github.com/mattermost/migration-assist/releases).
|
||||
|
||||
While you can run the `migration-assist` tool on the same server as your Mattermost deployment, we recommend running the tool in a virtual machine on the same network as your Mattermost server instead. The tool itself is lightweight and does not require a large server. A server with 2 CPU cores and 16 GB of RAM should be sufficient. If preferred, you can download and [compile](#compile-the-migration-assist-tool) the `migration-assist` tool yourself.
|
||||
|
||||
You'll also need to install the `pgloader` tool to migrate your data from MySQL to PostgreSQL. We recommend running `pgloader` in a virtual machine on the same network as your Mattermost server. You can use our official Mattermost Docker image for pgloader (`mattermost/pgloader:latest`); please note that it does **not** currently support MySQL’s `caching_sha2_password` authentication plugin. If you require `caching_sha2_password` support, you’ll need to build your own image and include the [qitab/qmynd](https://github.com/qitab/qmynd) library. See the [pgloader](/administration-guide/manage/admin/manual-postgres-migration#install-pgloader) installation documentation for details.
|
||||
|
||||
## Usage
|
||||
|
||||
<Important>
|
||||
|
||||
- If you encounter heap exhaustion errors in `pgloader`, edit your generated `migration.load` and under the `WITH` block set: `prefetch rows = 1000` and consider reducing it if the issue persists.
|
||||
- Please make sure you have the necessary environment to perform the migration. Ensure that the MySQL and PostgreSQL databases are running and accessible. To set up a PostgreSQL instance, see the [prepare your Mattermost database](/deployment-guide/server/prepare-database) documentation for details.
|
||||
- If you were previously utilizing a database for handling the [Mattermost configuration](/administration-guide/configure/configuration-in-your-database), those tables will not be migrated from your MySQL database with the migration [script](#migrate-the-data). You will need to manually migrate those configuration settings to your PostgreSQL database after completing the migration process. See the [configuration in database](/administration-guide/manage/admin/manual-postgres-migration#configuration-in-database) documentation for details.
|
||||
|
||||
</Important>
|
||||
|
||||
### Step 1 - Check the MySQL database schema
|
||||
|
||||
Run the following command to check the MySQL database schema:
|
||||
|
||||
``` sh
|
||||
migration-assist mysql "<MYSQL_DSN>" # example DSN: "user:password@tcp(address:3306)/db_name"
|
||||
```
|
||||
|
||||
This command outputs the readiness status and prints required fixes for common issues. The flags for fixes are as follows (you can combine all of them):
|
||||
|
||||
``` text
|
||||
--fix-artifacts Removes the artifacts from older versions of Mattermost
|
||||
--fix-unicode Strips unsupported Unicode characters from MySQL tables
|
||||
--fix-varchar Removes rows exceeding column lengths
|
||||
```
|
||||
|
||||
### Step 2 - Create the PostgreSQL database schema
|
||||
|
||||
Before running migrations, ensure the `public` schema is owned by your migration user:
|
||||
|
||||
``` sql
|
||||
sudo -u postgres psql -d mattermost -c "ALTER SCHEMA public OWNER TO mmuser; GRANT ALL ON SCHEMA public TO mmuser;"
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
``` sh
|
||||
migration-assist postgres "<POSTGRES_DSN>" \
|
||||
--run-migrations \
|
||||
--mattermost-version="<MATTERMOST_VERSION>"
|
||||
```
|
||||
|
||||
- `<POSTGRES_DSN>` example: `postgres://user:password@address:5432/db_name`
|
||||
- `<MATTERMOST_VERSION>` example: `10.5.4`
|
||||
|
||||
By default, two pre-checks run before migration:
|
||||
|
||||
- `--check-schema-owner=true`
|
||||
- `--check-tables-empty=true`
|
||||
|
||||
To disable them:
|
||||
|
||||
``` sh
|
||||
--check-schema-owner=false \
|
||||
--check-tables-empty=false
|
||||
```
|
||||
|
||||
### Step 3 - Generate a pgloader configuration
|
||||
|
||||
Run the following command to emit a pgloader configuration file:
|
||||
|
||||
``` sh
|
||||
migration-assist pgloader \
|
||||
--mysql="<MYSQL_DSN>" \
|
||||
--postgres="<POSTGRES_DSN>" \
|
||||
--remove-null-chars \
|
||||
> migration.load
|
||||
```
|
||||
|
||||
- By default, null characters in text columns are stripped. Disable with `--remove-null-chars=false`.
|
||||
|
||||
- If you run out of heap, edit `migration.load` and under the `WITH` block set:
|
||||
|
||||
``` text
|
||||
prefetch rows = 1000
|
||||
```
|
||||
|
||||
### Step 4 - Run pgloader
|
||||
|
||||
[Run pgloader](/administration-guide/manage/admin/manual-postgres-migration#pgloader) with the generated configuration file:
|
||||
|
||||
``` sh
|
||||
pgloader migration.load > migration.log
|
||||
```
|
||||
|
||||
Carefully review <code>migration.log</code> for errors (e.g., duplicate-key or missing-table warnings). Use the `mattermost/pgloader:latest` Docker image to avoid build/auth issues.
|
||||
|
||||
### Step 5 - Restore full-text indexes & create all indexes
|
||||
|
||||
Run:
|
||||
|
||||
``` sh
|
||||
migration-assist postgres post-migrate --create-indexes "<POSTGRES_DSN>"
|
||||
```
|
||||
|
||||
- The `--create-indexes` flag rebuilds full-text indexes on `Posts` and `FileInfo`, plus all other Mattermost indexes.
|
||||
- Omitting that flag only restores full-text indexes for `Posts` and `FileInfo`.
|
||||
|
||||
See the [Restore full-text indexes](/administration-guide/manage/admin/manual-postgres-migration#restore-full-text-indexes) documentation for details.
|
||||
|
||||
### Step 6 - Complete plugin migrations
|
||||
|
||||
Generate pgloader configs for Playbooks, Boards, and Calls:
|
||||
|
||||
``` sh
|
||||
migration-assist pgloader boards \
|
||||
--mysql="<MYSQL_DSN>" \
|
||||
--postgres="<POSTGRES_DSN>" > boards.load
|
||||
migration-assist pgloader playbooks \
|
||||
--mysql="<MYSQL_DSN>" \
|
||||
--postgres="<POSTGRES_DSN>" > playbooks.load
|
||||
migration-assist pgloader calls \
|
||||
--mysql="<MYSQL_DSN>" \
|
||||
--postgres="<POSTGRES_DSN>" > calls.load
|
||||
```
|
||||
|
||||
Run each:
|
||||
|
||||
``` sh
|
||||
pgloader boards.load > boards_migration.log
|
||||
pgloader playbooks.load > playbooks_migration.log
|
||||
pgloader calls.load > calls_migration.log
|
||||
```
|
||||
|
||||
Skip any plugin you don't use; check logs for JSON or missing-table errors. See the [Plugin migrations](/administration-guide/manage/admin/manual-postgres-migration#plugin-migrations) guide for more.
|
||||
|
||||
### Step 7 - Configure Mattermost to use PostgreSQL
|
||||
|
||||
In your `config.json` or via environment variables, update:
|
||||
|
||||
``` json
|
||||
"SqlSettings": {
|
||||
"DriverName": "postgres",
|
||||
"DataSource": "postgres://mmuser:pass@db:5432/mattermost?sslmode=disable"
|
||||
}
|
||||
```
|
||||
|
||||
If your config was stored in the database, update `MM_CONFIG` accordingly. See the [environment configuration settings](/administration-guide/configure/environment-configuration-settings#database) documentation for details.
|
||||
|
||||
<Note>
|
||||
|
||||
If your Mattermost deployment was initially configured with MySQL, there's a good chance your systemd service file has a `BindsTo=mysql.service` directive in it. This will cause the Mattermost server to be shut down if you deactivate your MySQL service. To fix this, update all references to `mysql.service` in your service file to use `postgresql.service` instead. This is only an issue if your Database and Mattermost are running on the same system.
|
||||
|
||||
</Note>
|
||||
|
||||
## Air-gapped environments
|
||||
|
||||
Follow these steps to migrate within an air-gapped environment:
|
||||
|
||||
1. **Verify** that the <code>migration-assist</code> binary is the latest version available to benefit from improvements and fixes.
|
||||
|
||||
2. **Transfer** the latest <code>migration-assist</code> binary into the air-gapped environment (e.g., via secure media).
|
||||
|
||||
3. **Generate** the MySQL schema+data output using fix flags. This produces `mysql.output`:
|
||||
|
||||
``` sh
|
||||
migration-assist mysql "user:pass@tcp(localhost:3306)/mattermost" \
|
||||
--fix-artifacts --fix-unicode --fix-varchar > mysql.output
|
||||
```
|
||||
|
||||
4. **Apply** migrations using the generated output:
|
||||
|
||||
``` sh
|
||||
migration-assist postgres \
|
||||
"postgres://mmuser:pass@localhost:5432/imported?sslmode=disable" \
|
||||
--run-migrations --applied-migrations="./mysql.output"
|
||||
```
|
||||
|
||||
5. **Continue** from **Step 3** through **Step 7** above to complete data transfer and configuration.
|
||||
|
||||
## Tool commands
|
||||
|
||||
The `migration-assist` tool offers 3 core commands:
|
||||
|
||||
1. `migration-assist mysql` — Checks MySQL schema readiness and offers fixes.
|
||||
2. `migration-assist postgres` — Builds the PostgreSQL schema and applies migrations.
|
||||
3. `migration-assist pgloader` — Generates a pgloader config for data transfer.
|
||||
|
||||
## Compile the migration-assist tool
|
||||
|
||||
Requires Go ≥ v1.22. Install with:
|
||||
|
||||
``` shell
|
||||
go install github.com/mattermost/migration-assist/cmd/migration-assist@latest
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See [troubleshooting errors during migration from MySQL to PostgreSQL](/administration-guide/manage/admin/postgres-migration#troubleshooting).
|
||||
@@ -0,0 +1,234 @@
|
||||
---
|
||||
title: "Migration guidelines from MySQL to PostgreSQL"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
From Mattermost v8.0, [PostgreSQL](/deployment-guide/software-hardware-requirements#database-software) is our database of choice for Mattermost to enhance the platform’s performance and capabilities. Recognizing the importance of supporting the community members who are interested in migrating from a MySQL database, we have taken proactive measures to provide guidance and best practices.
|
||||
|
||||
- [Automated migration from MySQL to PostgreSQL](/administration-guide/manage/admin/postgres-migration-assist-tool) - A comprehensive set of guidelines and a `migration-assist` tool to streamline the migration process, alleviate potential challenges, and faciliate a smooth transition.
|
||||
- [Manually migrate from MySQL to PostgreSQL](/administration-guide/manage/admin/manual-postgres-migration) - A good option if your organization has database administrators to own the migration process, or if you want to learn what the `migration-assist` tool automates for you.
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
### Why is Mattermost dropping support for MySQL?
|
||||
|
||||
Mattermost has decided to drop support for MySQL databases to streamline development and focus on delivering more efficient and optimized features. By supporting only PostgreSQL, which is generally considered more advanced and better-suited for enterprise environments, Mattermost can reduce complexity, improve performance, and better allocate resources to enhance the product. This change helps ensure more consistent, robust, and scalable database interactions for all Mattermost deployments.
|
||||
|
||||
### Is migrating to PostgreSQL before upgrading Mattermost recommended?
|
||||
|
||||
Yes. We also recommend upgrading to Mattermost server v8.x or later before migrating to PostgreSQL.
|
||||
|
||||
### Can the migration-assist be run on the Mattermost server?
|
||||
|
||||
Technically, yes. The `migration-assist` tool can be run on the Mattermost server. However, it is recommended to run the tool on a separate server to avoid any performance issues. We advise running the migration against a copy of the MySQL database to ensure that the migration process does not impact the production environment.
|
||||
|
||||
### How large should the PostgreSQL server be?
|
||||
|
||||
The size of the PostgreSQL server should match that of the MySQL server initially. We recommend monitoring the performance of the PostgreSQL server and adjusting the resources as needed.
|
||||
|
||||
### How large should the server running `migration-assist` server be?
|
||||
|
||||
The tool itself is lightweight and does not require a large server. A server with 2 CPU cores and 16 GB of RAM should be sufficient for default configurations. However, you may need to adjust the resources based on the size of the MySQL database, your downtime limitations, and the configuration of `pgloader`.
|
||||
|
||||
### Do we/will Mattermost bundle pgloader or is that a separate install?
|
||||
|
||||
Mattermost doesn't bundle pgloader with the Mattermost server. You will need to install pgloader separately. For more information, see the [install pgloader](/administration-guide/manage/admin/manual-postgres-migration#install-pgloader) documentation.
|
||||
|
||||
### Are there any other migrations available for plugins, or just Boards, Playbooks, and Calls?
|
||||
|
||||
We're developing migrations for other plugins, such as NPS-plugin. Please stay tuned for updates.
|
||||
|
||||
### Do these processes support AWS RDS databases?
|
||||
|
||||
Yes, the processes support AWS RDS databases. However, you may need to adjust the security group settings to allow the migration process to access the databases.
|
||||
|
||||
### Does Mattermost support MariaDB? If not, why not?
|
||||
|
||||
Mattermost does not support MariaDB. The primary reason for this decision is to streamline development and maintenance by focusing on a single database technology. By standardizing on PostgreSQL, Mattermost can deliver optimized features, improved performance, and a more focused engineering effort. PostgreSQL is well-regarded for its robustness, advanced features, and suitability for enterprise use, making it the chosen database for Mattermost.
|
||||
|
||||
MariaDB, while compatible with MySQL to a large extent, introduces additional complexity and potential inconsistency, which the Mattermost development team aims to avoid by limiting database support.
|
||||
|
||||
Because of these reasons we also don't support migrations directly from MariaDB to PostgreSQL. Oracle provides documentation on \[how to migrate from MariaDB to MySQL\]([https://blogs.oracle.com/mysql/post/how-to-migrate-from-mariadb-to-mysql-80](https://blogs.oracle.com/mysql/post/how-to-migrate-from-mariadb-to-mysql-80)) which can be used as a starting point for the migration to PostgreSQL.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Unsupported authentication for MySQL
|
||||
|
||||
If you are facing an error due to authentication with MySQL v8, it may be related to a [known issue](https://github.com/dimitri/pgloader/issues/782) with pgloader. The fix is to set the default authentication method to `mysql_native_password` in your MySQL configuration. To do so, add the `default-authentication-plugin=mysql_native_password` value to your `mysql.cnf` file. Also, do not forget to update your user to use this authentication method.
|
||||
|
||||
``` sql
|
||||
ALTER USER '<mysql_user>'@'%' IDENTIFIED WITH mysql_native_password BY '<mysql_password>';
|
||||
```
|
||||
|
||||
### Errors during the pgloader command execution
|
||||
|
||||
If you encounter errors during the execution of the `pgloader` command, ensure that both of the databases are accessible and that the users have the necessary permissions to access the database. Do not continue with the migration if there are errors during the execution of the `pgloader` command.
|
||||
|
||||
<Note>
|
||||
|
||||
For experienced users, it is recoverable to run the `pgloader` without requiring a restart of the migration from scratch. In this case, you will need to manually fix the issues with the table, and run the `pgloader` command with a tailored configuration specifically for those tables. Also ensure that the schema name is reverted back to `public`, and the `search_path` is restored (or remove necessary clauses from the configuration).
|
||||
|
||||
</Note>
|
||||
|
||||
The following sections detail how to resolve some common errors you may encounter during the execution of the `pgloader` command:
|
||||
|
||||
#### Invalid input syntax for type JSON
|
||||
|
||||
If you receive an error message similar to the following:
|
||||
|
||||
``` text
|
||||
ERROR Database error 22P02: invalid input syntax for type json
|
||||
```
|
||||
|
||||
The data in the MySQL database is not in a valid JSON format. You can fix this issue by updating the data in the MySQL database to be in a valid JSON format. To find out which row is causing the issue, run the following query (where `<table_name>` and `<column_name>` should be replaced with the actual table and column names indicated in the `pgloader` output):
|
||||
|
||||
``` sql
|
||||
SELECT * FROM <table_name> WHERE JSON_VALID(<column_name>) = 0;
|
||||
```
|
||||
|
||||
You can find and update the data in the MySQL database to be in a valid JSON format with the query above. After updating the data, you can run the `pgloader` command again.
|
||||
|
||||
#### Failed to find column or table
|
||||
|
||||
If you receive an error message similar to the following:
|
||||
|
||||
``` text
|
||||
pgloader failed to find column
|
||||
```
|
||||
|
||||
The column or table is missing in the PostgreSQL database. You can fix this issue by checking whether you have created the correct version of Postgres schema. After re-creating the schema, you can run the `pgloader` command again.
|
||||
|
||||
#### Fell through ECASE expression
|
||||
|
||||
If you receive an error message similar to the following:
|
||||
|
||||
``` text
|
||||
ERROR mysql: 76 fell through ECASE expression.
|
||||
```
|
||||
|
||||
It is a [known issue](https://github.com/dimitri/pgloader/issues/1183) with pgloader. You can fix this issue by either compiling `pgloader` from source or simply avoid this by running `pgloader` with our docker image. See: [install pgloader](/administration-guide/manage/admin/manual-postgres-migration#install-pgloader) for more information.
|
||||
|
||||
<Note>
|
||||
|
||||
Also, there may be cases where pgloader continues to migrate remaining tables and skip one or more tables during migration. In such cases, we recommend identifying issues with the table and fixing them before running the `pgloader` command again with a clean database. It is possible to run the `pgloader` command with the `--debug` flag to get more information about the errors.
|
||||
|
||||
</Note>
|
||||
|
||||
### Mattermost can't connect to the PostgreSQL database
|
||||
|
||||
If you are facing an issue where Mattermost can't connect to the PostgreSQL database, ensure that the PostgreSQL server is running and that the database is accessible. If there were errors during the execution of the `pgloader` command, it can fail to revert the schema name back to `public`, or potentially fail to restore the `search_path`. You can manually revert the schema name back to `public` and restore the `search_path` by running the following commands:
|
||||
|
||||
1. Connect to PostgreSQL using `sudo -u postgres psql`.
|
||||
2. Select the `mattermost` database using `\c mattermost`. Verify you are using the right database by running `SELECT current_database();`. The command should output `mattermost`.
|
||||
3. Revert the schema name change (optional)
|
||||
|
||||
``` sql
|
||||
ALTER SCHEMA <schema_name> RENAME TO public;
|
||||
```
|
||||
|
||||
Also ensure that the database user has the necessary settings to have default access to the `public` schema. You can do this by running the following commands:
|
||||
|
||||
4. Set the search_path for the mmuser:
|
||||
|
||||
``` sql
|
||||
ALTER USER mmuser SET search_path TO "$user", public;
|
||||
```
|
||||
|
||||
5. Terminate the connection and connect again to your psql server.
|
||||
|
||||
6. Verify the search_path is set correctly:
|
||||
|
||||
``` sh
|
||||
SHOW search_path;
|
||||
```
|
||||
|
||||
This should return `"$user", public`.
|
||||
|
||||
7. If the issue persists, also run:
|
||||
|
||||
``` sql
|
||||
SELECT pg_catalog.set_config('search_path', '"$user", public', false);
|
||||
```
|
||||
|
||||
### Permission issues when accessing the schema in PostgreSQL
|
||||
|
||||
If you run into a permission issue during step 2 where the command reports a permission issue similar to the following:
|
||||
|
||||
``` text
|
||||
An Error Occurred: could not check schema owner: the user “mmuser” is not owner of the “public” schema
|
||||
```
|
||||
|
||||
Ensure that the `mmuser` user in PostgreSQL is the owner of the schema.
|
||||
|
||||
1. Connect to PostgreSQL using `sudo -u postgres psql`.
|
||||
|
||||
2. Select the `mattermost` database using `\c mattermost`. Verify you are using the right database by running `SELECT current_database();`. The command should output `mattermost`.
|
||||
|
||||
3. Run the following commands:
|
||||
|
||||
``` sql
|
||||
ALTER SCHEMA public OWNER TO mmuser;
|
||||
GRANT USAGE, CREATE ON SCHEMA public TO mmuser;
|
||||
```
|
||||
|
||||
Then, re-run the command from step 2.
|
||||
|
||||
### Incoming webhook channel names become case-sensitive after migration
|
||||
|
||||
After migrating from MySQL to PostgreSQL, incoming webhooks that previously worked with mixed-case channel names (e.g., `"Tech-Talk"`) will fail with the following error:
|
||||
|
||||
``` text
|
||||
GetChannelByName: Channel does not exist.
|
||||
```
|
||||
|
||||
This occurs because Mattermost doesn't allow the creation of channels with uppercase characters. All new channels names must only contain lowercase characters. Additionally, MySQL is case-insensitive when matching channel names, while PostgreSQL is case-sensitive. This means that webhook payloads that worked with MySQL's forgiving case-insensitive matching will fail with PostgreSQL's strict case-sensitive matching. In rare cases, older channels may still exist with mixed-case names in your database. These channels are considered invalid and may cause issues when performing operations like updating channel headers.
|
||||
|
||||
**Solution:**
|
||||
|
||||
Update all webhook payloads to use only lowercase channel names.
|
||||
|
||||
**Prevention:**
|
||||
|
||||
Before migrating to PostgreSQL:
|
||||
|
||||
1. Audit your incoming webhooks and update any that use mixed-case channel names in their payloads.
|
||||
2. Check for any legacy channels with mixed-case names that may have been created in earlier versions.
|
||||
3. Consider renaming any mixed-case channels to lowercase to prevent issues.
|
||||
|
||||
This is expected behavior with PostgreSQL and reflects Mattermost's channel naming requirements.
|
||||
|
||||
### Legacy Boards tables causing migration errors
|
||||
|
||||
During database migration from MySQL to PostgreSQL, while using schema comparison tools (such as dbcmp) you may encounter the following error:
|
||||
|
||||
``` text
|
||||
error during comparison: no pk defined for table: focalboard_file_info
|
||||
```
|
||||
|
||||
This typically relates to legacy tables from older versions of Boards that are no longer in use. If you're using Boards version 8.0.0 or later, these tables are no longer required and can be ignored in the migration process.
|
||||
|
||||
**Applies To:**
|
||||
|
||||
- Boards version 8.0.0 and above
|
||||
- All staging, UAT, QA, or production environments
|
||||
|
||||
<Note>
|
||||
|
||||
Does not apply to standalone Boards versions prior to v8.0.0
|
||||
|
||||
</Note>
|
||||
|
||||
**Solution:**
|
||||
|
||||
If you're using Boards version 8.0.0 or higher, the following legacy tables which were used only in the standalone version and can be safely ignored:
|
||||
|
||||
- `focalboard_file_info` - Used in standalone version; no longer relevant in plugin and later versions. Stores uploaded files and attachments for boards.
|
||||
- `focalboard_sessions` - Used in standalone version. Tracks user login sessions for boards.
|
||||
- `focalboard_teams` - Used in standalone version. Legacy team mapping not used in later versions. Stores team board settings and permissions.
|
||||
- `focalboard_users` - Used in standalone version. Stores user preferences and settings for boards.
|
||||
|
||||
These tables may be empty or unused in your current environment. If so, they do not need to be migrated to PostgreSQL.
|
||||
|
||||
## Contact Support
|
||||
|
||||
Mattermost customers looking for guidance tailored to their Mattermost deployment can contact a [Mattermost Expert](https://mattermost.com/contact-sales/) for guidance.
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: "Self-hosted billing"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Mattermost commercial plans are offered as an annual subscription service. With your purchase you're provided with a license key. Depending on which version of Mattermost you're on, you may have to download and apply this license manually via the System Console.
|
||||
|
||||
When you upgrade to commercial plan, the number of user seats you need has to be equal to or greater than your current number of activated users (formerly called active users).
|
||||
|
||||
You can add new users to your deployment at any time. Every quarter, during the true-up review (section 3.5 License True-up Review of Software License Agreement, also referenced in docs), we check the license license seat count relative to number of activated users. If there's a difference, we'll provide you with a new invoice which is payable immediately.
|
||||
|
||||
Please see the [self-hosted subscriptions documentation](/product-overview/self-hosted-subscriptions#buy-a-subscription) for more detailed information.
|
||||
|
||||
[Book a live demo](https://mattermost.com/request-demo/) or [talk to a Mattermost expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization's secure collaboration needs. Or try Mattermost yourself with a [1-hour preview](https://mattermost.com/sign-up/) for instant access to a live sandbox environment.
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: "Manage Mattermost"
|
||||
---
|
||||
Running Mattermost day to day: who has access to what, the tools you operate the server with, your license and billing, the notices your users see, and getting your data out.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Access control](/administration-guide/manage/admin/user-management) - Permissions, roles, user attributes, team and channel membership, and attribute-based access control.
|
||||
|
||||
## Server operations
|
||||
|
||||
- [mmctl command line tool](/administration-guide/manage/mmctl-command-line-tool) - Administer the server from the command line.
|
||||
- [Command line tools](/administration-guide/manage/command-line-tools) - The `mattermost` binary's own commands.
|
||||
- [Mattermost logging](/administration-guide/manage/logging) - Customize logging options based on your business practices and needs.
|
||||
|
||||
## Licensing and billing
|
||||
|
||||
- [Self-hosted billing](/administration-guide/manage/admin/self-hosted-billing) - Billing and payment options for self-hosted deployments.
|
||||
- [Install a license key](/administration-guide/manage/admin/installing-license-key) - Apply a license to a self-hosted deployment.
|
||||
|
||||
## Cloud, notices, and data
|
||||
|
||||
- [Cloud workspace management](/administration-guide/manage/cloud-workspace-management) - Data residency, IP filtering, encryption keys, and workspace export.
|
||||
- [Data import, export, and migration](/administration-guide/manage/admin/migration) - Bulk import and export, database migration, and FIPS-compliant images.
|
||||
- [Product limits](/administration-guide/manage/product-limits) and [feature labels](/administration-guide/manage/feature-labels) - What each plan includes, and what a feature label means.
|
||||
|
||||
## Related
|
||||
|
||||
- [Backup and disaster recovery](/deployment-guide/backup-disaster-recovery) - Back up and restore a Mattermost deployment.
|
||||
- [Upgrade Mattermost Server](/administration-guide/upgrade/upgrade-index) - Upgrade, downgrade, and post-upgrade rollout.
|
||||
- [Secure Mattermost](/security-guide/secure-mattermost) - Harden your deployment.
|
||||
- [Monitor and troubleshoot](/administration-guide/manage/admin/monitoring-and-performance) - Metrics, health checks, support packets, and error codes.
|
||||
180
docs/main/administration-guide/manage/admin/user-attributes.mdx
Normal file
180
docs/main/administration-guide/manage/admin/user-attributes.mdx
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
title: "User attributes"
|
||||
---
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<PlanAvailability slug="ent-plus" />
|
||||
|
||||
From Mattermost v10.8, ensure your teams always have the critical information they need to collaborate effectively by defining and managing organization-specific user profile attributes as system attributes that you can synchronize with your AD/LDAP or SAML identity provider.
|
||||
|
||||
System attributes enable you to customize user profile attributes to match your organization's unique needs and streamline collaboration while keeping user data centralized and consistent.
|
||||
|
||||
From Mattermost v11, you have enhanced control over these user attributes through admin-managed vs user-editable settings. By default, attributes are admin-managed for security, but you can explicitly allow user editing for specific attributes that don't impact access control or sensitive organizational data. These user attributes supplement existing user details visible from the user's profile picture.
|
||||
|
||||

|
||||
|
||||
## Before you begin
|
||||
|
||||
If you plan to synchronize system properties with your AD/LDAP or SAML identity provider, ensure AD/LDAP or SAML synchronization is already enabled and configured. See the [AD/LDAP groups](/administration-guide/onboard/ad-ldap-groups-synchronization) product documentation or [SAML 2.0](/administration-guide/configure/authentication-configuration-settings#saml-20) configuration settings documentation for details.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="mattermost-v11-or-later" label="Mattermost v11 or later">
|
||||
|
||||
From Mattermost v11, user attributes have enhanced admin controls with a security-first approach. All attributes are admin-managed by default, providing better security and governance. System administrators can explicitly enable user editing for specific attributes through the System Console interface.
|
||||
|
||||
If your organization uses [attribute-based access control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control), which requires an Enterprise Edition Advanced license, attributes used in access control policies should remain admin-managed for security reasons. You can enable user-managed attributes for ABAC by setting `EnableUserManagedAttributes` in `config.json`, or via an environment variable as noted below, but this should be done with caution:
|
||||
|
||||
- `config.json` setting: `".AccessControlSettings.EnableUserManagedAttributes: false",` with options `true` and `false`.
|
||||
- Environment variable: `MM_ACCESSCONTROLSETTINGS_ENABLEUSERMANAGEDATTRIBUTES`
|
||||
|
||||
This configuration setting isn't managed using the System Console, and is disabled by default to ensure that access control policies remain secure and can't be circumvented by users modifying their own profile attributes. Learn more about [admin-managed versus user-editable attributes](#admin-managed-vs-user-editable-attributes).
|
||||
|
||||
Additionally, from mobile app v2.31.0, user attributes are fully supported on mobile devices. Mobile users can both view and manage profile attributes (if allowed by admin settings) directly from the mobile app. Mobile attribute support requires the same server-side configuration, and no additional mobile-specific setup is required.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="mattermost-v10-11-or-later" label="Mattermost v10.11 or later">
|
||||
|
||||
From Mattermost v10.11, user-managed attributes are excluded from ABAC rules for security reasons. If your organization uses ABAC (which requires Enterprise Edition Advanced), a system admin can explicitly enable user-managed attributes for ABAC by setting `EnableUserManagedAttributes` in `config.json` or via an environment variable as noted below. This configuration setting isn't managed using the System Console, and is disabled by default to ensure that access control policies remain secure and can't be circumvented by users modifying their own profile attributes.
|
||||
|
||||
- `config.json` setting: `".AccessControlSettings.EnableUserManagedAttributes: false",` with options `true` and `false`.
|
||||
- Environment variable: `MM_ACCESSCONTROLSETTINGS_ENABLEUSERMANAGEDATTRIBUTES`
|
||||
|
||||
Additionally, from mobile app v2.31.0, user attributes are fully supported on mobile devices. Mobile users can both view and manage profile attributes directly from the mobile app. Mobile attribute support requires the same server-side configuration, and no additional mobile-specific setup is required.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="mattermost-v10-9-or-later" label="Mattermost v10.9 or later">
|
||||
|
||||
From Mattermost Enterprise v10.9, the ability to create and manage system properties as a Mattermost system admin requires no manual setup.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="mattermost-v10-8" label="Mattermost v10.8">
|
||||
|
||||
You'll need Mattermost Enterprise v10.8 or later, and be a Mattermost system admin to enable the system properties feature flag, `MM_FEATUREFLAGS_CUSTOMPROFILEATTRIBUTES` to create and manage system properties. See the Mattermost developer documentation for details on [enabling feature flags in a self-hosted deployment](https://developers.mattermost.com/contribute/more-info/server/feature-flags/#self-hosted-and-local-development). Mattermost Cloud customers can request this feature flag be enabled by contacting their Mattermost Account Manager or by [creating a support ticket](https://support.mattermost.com/hc/en-us/requests/new?ticket_form_id=11184911962004) request.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Admin-managed vs user-editable attributes
|
||||
|
||||
From Mattermost v11, system administrators have enhanced control over user attributes through admin-managed vs user-editable settings. This distinction provides better security and governance for organizational profile data.
|
||||
|
||||
**Admin-managed attributes** (default behavior):
|
||||
|
||||
- Controlled exclusively by system administrators
|
||||
- Users cannot edit these values in their profiles
|
||||
- Recommended for security-sensitive information like roles, clearance levels, or organizational identifiers
|
||||
- Ideal for attributes used in ABAC (Attribute-Based Access Control) policies
|
||||
- Values can only be updated by admins or through identity provider synchronization
|
||||
|
||||
**User-editable attributes**:
|
||||
|
||||
- Users can update these values in their own profiles
|
||||
- System administrators can still modify these attributes
|
||||
- Appropriate for non-sensitive information like personal preferences, skills, or contact details
|
||||
- Should not be used for attributes that impact security access controls
|
||||
|
||||
<Note>
|
||||
|
||||
For security reasons, attributes used in ABAC policies are admin-managed by default and cannot be edited by users unless explicitly enabled by a system administrator through the **Allow user editing** option.
|
||||
|
||||
</Note>
|
||||
|
||||
**Best practices:**
|
||||
|
||||
- Keep attributes that affect access control or contain sensitive organizational data as admin-managed
|
||||
- Only enable user editing for attributes that don't impact security policies
|
||||
- Regularly review user-editable attributes to ensure they remain appropriate for user management
|
||||
- Consider your organization's data governance requirements when determining attribute editability
|
||||
|
||||
## Add attributes
|
||||
|
||||
You can define and manage up to 20 system attributes using the System Console. Each attribute becomes a user profile option users can populate, unless you disable the **Editable by Users** option, available from Mattermost v11. Once you reach the maximum of 20 attributes, you can't create new attributes until you [delete attributes](#manage-attributes) you no longer need.
|
||||
|
||||
From Mattermost v11.8, user attributes include both a **Display Name** and a **Name**. The Display Name is the label shown to users and admins in Mattermost. The Name is the internal attribute identifier used in API references and [attribute-based access control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) policy expressions. When you create a new user attribute, Mattermost can generate the Name from the Display Name, formatted as a CEL-safe identifier. Saved ABAC policies continue to reference the internal name using `user.attributes.<name>`.
|
||||
|
||||
<Note>
|
||||
|
||||
When you disable the **Editable by Users** option for an attribute, only admins can set its value using [mmctl cpa](/administration-guide/manage/mmctl-command-line-tool#mmctl-cpa) commands.
|
||||
|
||||
</Note>
|
||||
|
||||
1. In the System Console, go to **Site Configuration \> System Attributes \> User Attributes** and select **Add Attribute**.
|
||||
|
||||
2. Enter the following details:
|
||||
|
||||
> - **Display Name**: Enter a display name for the attribute that will be shown in any user facing UI.
|
||||
> - **Attribute name**: Attribute name will be automatically generated from the provided Display Name. It can be overriden and with a preferred unique name for the attribute. Attribute names can be up to 40 characters long. The attribute name is used as the Common Expression Language (CEL) identifier in access control policies. It must start with a letter or underscore, and can contain only letters, numbers, and underscores. Reserved CEL words aren't allowed, including `true`, `false`, `null`, `in`, `as`, `break`, `const`, `continue`, `else`, `for`, `function`, `if`, `import`, `let`, `loop`, `package`, `namespace`, `return`, `var`, `void`, and `while`.
|
||||
> - **Type**: Specify the type of attribute as one of the following:
|
||||
> - **Text** for text-based profile attributes.
|
||||
> - **Phone** for phone number-based profile attributes.
|
||||
> - **URL** for web site address-based profile attributes.
|
||||
> - **Select** for a list of profile attribute values users can choose from. Specify each value followed by pressing **TAB** or **ENTER**. Values can be up to 64 characters long, and users can choose a single value.
|
||||
> - **Multi-select** for a list of profile attribute values users can select from. Specify each value followed by pressing **TAB** or **ENTER**. Values can be up to 64 characters long, and users can choose multiple values.
|
||||
> - **Ranked** for an ordered list of values, where each value ranks higher or lower than the others - for example, clearance or classification levels such as *Public*, *Secret*, and *Top Secret*. Specify each value, then order the values from lowest to highest rank. Users can choose a single value. Because the values are ordered, [access control policies](/administration-guide/manage/admin/abac-system-wide-policies) can compare a ranked attribute against a threshold - for example, clearance *is at least* Secret - rather than only checking for an exact match.
|
||||
|
||||
3. Specify the attribute's visibility as one of the following:
|
||||
|
||||
> - **Always show**: The attribute is always visible in user profiles.
|
||||
> - **Hide when empty**: The attribute is only visible in user profiles when it has a value.
|
||||
> - **Always hide**: The attribute is never visible in user profiles.
|
||||
|
||||
<Note>
|
||||
|
||||
If an attribute is created or updated without explicit visibility or sort order (for example via API or automation), Mattermost returns default values in responses even if those attributes weren't stored. Visibility defaults to the server's default visibility, and sort order defaults to `0`.
|
||||
|
||||
</Note>
|
||||
|
||||
4. Configure user editing permissions (Mattermost v11 or later) by enabling or disabling the **Editable by users** option.
|
||||
5. Save your changes.
|
||||
|
||||
<Tip>
|
||||
|
||||
Duplicate existing attributes by selecting **More** <img src={useBaseUrl('/img/ui/dots-horizontal_F01D8.svg')} alt="Use the More icon to access additional message options." className="theme-icon" /> and selecting **Duplicate attribute**. This creates a new attribute with the same name and type as the original attribute. You can then edit the new attribute to change its name, type, and visibility as needed.
|
||||
|
||||
</Tip>
|
||||
|
||||
## Manage attributes
|
||||
|
||||
- **Modify**: Select the attribute fields to make inline changes to the attribute's name, type, or values. Select **More** <img src={useBaseUrl('/img/ui/dots-horizontal_F01D8.svg')} alt="Use the More icon to access additional message options." className="theme-icon" /> to change a attribute's visibility.
|
||||
|
||||
<Note>
|
||||
|
||||
From Mattermost v11.8, existing user attributes are backfilled so the Display Name initially matches the Name. If the Display Name is empty or unavailable, Mattermost falls back to showing the Name. Duplicate display names are permitted, but internal names remain unique.
|
||||
|
||||
</Note>
|
||||
|
||||
- **Order**: Control the order you want attributes to appear in user profiles by dragging and dropping them in the list.
|
||||
- **Delete**: Delete attributes you no longer need or want by selecting **More** <img src={useBaseUrl('/img/ui/dots-horizontal_F01D8.svg')} alt="Use the More icon to access additional message options." className="theme-icon" /> and selecting **Delete property**.
|
||||
|
||||
<Note>
|
||||
|
||||
When updating user attributes via API or automation, the `attrs` object replaces existing attribute settings rather than merging. If you send only visibility, the sort order resets to `0` unless you include `sort_order` in the same request. If a patch fails, the API may return the error string "Unable to patch User Attribute field".
|
||||
|
||||
</Note>
|
||||
|
||||
- **User Edit Permissions**: From Mattermost v11, all user attributes are admin-managed by default for enhanced security. To allow user editing for specific attributes, administrators can enable this through the **More** <img src={useBaseUrl('/img/ui/dots-horizontal_F01D8.svg')} alt="Use the More icon to access additional message options." className="theme-icon" /> menu and selecting **Allow user editing**. This should only be enabled for attributes that do not impact security access controls or organizational policies. Attributes used in ABAC policies should remain admin-managed unless there's a specific business need and the security implications are fully understood.
|
||||
- **Edit User Attribute Values**: From Mattermost v11.1, you can view and update user attribute values for individual users through the System Console. See the [Manage user attributes](/administration-guide/configure/user-management-configuration-settings#manage-user-attributes) documentation for details.
|
||||
|
||||
In cases where multiple system admins manage system attributes, refresh your web browser instance to see real-time updates to system attributes made by other admins.
|
||||
|
||||
## Attribute access modes
|
||||
|
||||
Each user attribute has an **access mode** that controls who can see its values when those values appear in access control policies. The access mode is set per attribute and determines whether an admin editing a policy can see the raw attribute values referenced in its rules.
|
||||
|
||||
Access modes are not configurable through the System Console. They can only be set programmatically by a Mattermost plugin using the [Property Fields API](https://api.mattermost.com/#tag/properties). Attributes created by system admins through the System Console always use the `public` access mode. A plugin that needs to restrict attribute visibility must create the field with `protected: true` and set the desired `access_mode` — this is typically done by plugins that sync sensitive attributes from an external identity source and need to control which admins can read those values.
|
||||
|
||||
- **Public** (default): The attribute value is visible to all admins editing policies that reference it. No masking is applied.
|
||||
- **Shared only**: The attribute value is only visible to admins who personally hold that same value. Admins who don't hold the value see it masked (`--------`) in the policy editor.
|
||||
- **Source only**: The attribute value is only visible to the system source that set it (for example, the identity provider). All admins see it masked in the policy editor regardless of their own attribute values.
|
||||
|
||||
Masking in the policy editor only applies to attributes with `shared_only` or `source_only` access mode. See [Attribute value masking](/administration-guide/manage/admin/abac-system-wide-policies#attribute-value-masking) for the editor behavior when masked values are present.
|
||||
|
||||
## Sync attributes with your identity provider
|
||||
|
||||
1. Synchronize a attribute with AD/LDAP or SAML by selecting **More** <img src={useBaseUrl('/img/ui/dots-horizontal_F01D8.svg')} alt="Use the More icon to access additional message options." className="theme-icon" /> and selecting **Link attribute to AD/LDAP** or **Link attribute to SAML**. Mattermost takes you directly to the **AD/LDAP** or **SAML 2.0** configuration settings page in the System Console where you can map the attributes you want to synchronize.
|
||||
2. Scroll to the **User attributes sync** section to specify the attribute used to populate the attribute in user profiles.
|
||||
3. Specify the attribute mapping for the attribute by entering the attribute name in the system attribute's **Attribute** field. The attribute name must match the attribute name in your identity provider.
|
||||
4. Save your changes.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "Access control"
|
||||
---
|
||||
Who can do what in a workspace that's already running: the roles and permissions you grant, the attributes you record about people, and the policies that decide which teams and channels they can reach.
|
||||
|
||||
- [Manage team and channel members](/administration-guide/manage/team-channel-members) - Add, remove, and change the roles of members.
|
||||
- [Advanced permissions](/administration-guide/onboard/advanced-permissions) - Customize what each role is allowed to do.
|
||||
- [Advanced permissions: backend infrastructure](/administration-guide/onboard/advanced-permissions-backend-infrastructure) - How the permissions system is structured.
|
||||
- [Delegated granular administration](/administration-guide/onboard/delegated-granular-administration) - Grant admin access to part of the System Console.
|
||||
- [Attribute-based access control](/administration-guide/manage/admin/attribute-based-access-control) - Grant access based on user attributes rather than membership lists.
|
||||
- [User attributes](/administration-guide/manage/admin/user-attributes) - Define the custom attributes that access rules are written against.
|
||||
- [System-wide attribute-based access policies](/administration-guide/manage/admin/abac-system-wide-policies) - Organization-wide policies System Admins assign to teams and channels.
|
||||
- [Team membership policies](/administration-guide/manage/admin/abac-team-membership) - Control who can join a team.
|
||||
- [Team channel policies](/administration-guide/manage/admin/abac-team-channel-policies) - Channel membership policies Team Admins manage from Team Settings.
|
||||
- [Channel-specific access rules](/administration-guide/manage/admin/abac-channel-access-rules) - Access rules Channel Admins manage from Channel Settings.
|
||||
|
||||
Setting up authentication and creating accounts in the first place is covered in [onboard users](/administration-guide/onboard/onboard-index), including [guest accounts](/administration-guide/onboard/guest-accounts).
|
||||
677
docs/main/administration-guide/manage/bulk-export-tool.mdx
Normal file
677
docs/main/administration-guide/manage/bulk-export-tool.mdx
Normal file
@@ -0,0 +1,677 @@
|
||||
---
|
||||
title: "Bulk export data"
|
||||
---
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Moving data from one Mattermost instance into another begins with exporting data to a [JSONL](https://jsonlines.org) file, in the same format used to [bulk import data](/administration-guide/onboard/bulk-loading-data). This is useful if you have created a server for a proof of concept, have created another server for production use, and now want to retain the history from the proof of concept instance.
|
||||
|
||||
You can export the following data types:
|
||||
|
||||
- Teams
|
||||
- Channels (public, private, and direct)
|
||||
- Messages (regular, non-reply, and direct messages)
|
||||
- Threaded discussions and message replies
|
||||
- Message reactions
|
||||
- Users
|
||||
- Users' preferences, including pinned and saved messages
|
||||
- Users' team memberships
|
||||
- Users' channel memberships
|
||||
- Users' notification preferences
|
||||
- Custom emoji
|
||||
- Direct message and group message channels, including read/unread status
|
||||
- Roles
|
||||
- Permissions schemes
|
||||
- Bot users
|
||||
|
||||
<Note>
|
||||
|
||||
Configuration for data types such as exporting specific areas of the server, exporting additional types of posts, file attachments, webhooks, and bot messages is not yet supported. Deleted objects are also not yet supported.
|
||||
|
||||
For requests to add additional attributes or objects to our exporter, please add a feature request on our [feature idea forum](https://portal.productboard.com/mattermost/33-what-matters-to-you).
|
||||
|
||||
</Note>
|
||||
|
||||
## Bulk export data
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="use-mmctl" label="Use mmctl">
|
||||
|
||||
1. Create a full export file including attachments by running the [mmctl export create -- attachments](/administration-guide/manage/mmctl-command-line-tool#mmctl-export-create) command. See the [Mattermost data migration](/administration-guide/manage/cloud-data-export#create-the-export) documentation for details.
|
||||
2. While the job is running, you can check its status by running the [mmctl export job show](/administration-guide/manage/mmctl-command-line-tool#mmctl-export-job-show) command.
|
||||
3. When the export job status is successful:
|
||||
|
||||
> 1. Identify the name of the completed export file by running the [mmctl export list](/administration-guide/manage/mmctl-command-line-tool#mmctl-export-list) command.
|
||||
> 2. Download the export file to your local machine by running the [mmctl export download](/administration-guide/manage/mmctl-command-line-tool#mmctl-export-download) command.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="use-cli" label="Use CLI">
|
||||
|
||||
<Note>
|
||||
|
||||
From Mattermost v6.0, this command has been deprecated in favor of [mmctl export commands](/administration-guide/manage/mmctl-command-line-tool#mmctl-export) as the supported way to export data out of Mattermost.
|
||||
|
||||
</Note>
|
||||
|
||||
The export command runs in the [CLI](/administration-guide/manage/command-line-tools). It has permissions to access all information in the Mattermost database.
|
||||
|
||||
To run the export command:
|
||||
|
||||
1. Navigate to the directory where the Mattermost server is installed. On a default install of Mattermost, the directory is `/opt/mattermost`.
|
||||
|
||||
2. Run the following command to extract data from all teams on the server. Note that you can change the file name and specify an absolute or relative path to dictate where the file is exported:
|
||||
|
||||
`sudo -u mattermost bin/mattermost export bulk file.json --all-teams`
|
||||
|
||||
`sudo -u mattermost bin/mattermost export bulk /home/user/bulk_data.json --all-teams`
|
||||
|
||||
3. Retrieve your file from the location you specified.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
All Mattermost bulk export data files will begin with a `Version` object as the first line of the file. This indicates the version of the Mattermost bulk import file format with which the exported data is compatible.
|
||||
|
||||
## Version object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">type</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The string "version"</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">version</td>
|
||||
<td valign="middle">number</td>
|
||||
<td>The number 1.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">info</td>
|
||||
<td valign="middle">object</td>
|
||||
<td>Optional VersionInfo object</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## VersionInfo object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">generator</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the tool this export was generated with. Well known tools are:<br /> <kbd>"mattermost-server"</kbd> for the Mattermost Server.<br /> <kbd>"mmetl"</kbd> for the Slack export converter "mmetl".</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">version</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The version of the tool this export was generated with. This may contain multiple pieces of version info, separated by spaces. The first one should be a semantic version.<br /> <kbd>"7.6.0 (29bb1e53ef5a439c73065f47de2972f9bbcb09a4, enterprise: true)"</kbd> is an example of such a version string.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">created</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The timestamp of the file creation. This should be formatted as an RFC 3339 timestamp. The nanosecond part is optional.<br /> <kbd>"2022-11-22T16:40:51.019582328+01:00"</kbd></td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">additional</td>
|
||||
<td valign="middle">any</td>
|
||||
<td>Any additional information the generator wants to include into the file header. May be omitted. Be aware that the size of each line is limited to a few MiB.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Team object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The team name.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">display_name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The display name for the team.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">type</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The type of team. Will have one of the following values:<br /> <kbd>"O"</kbd> for an open team<br /> <kbd>"I"</kbd> for an invite-only team.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">description</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The team description.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">allow_open_invite</td>
|
||||
<td valign="middle">bool</td>
|
||||
<td>Whether to allow open invitations. Will have one of the following values:<br /> <kbd>"true"</kbd><br /> <kbd>"false"</kbd></td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">scheme</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the permissions scheme that applies to this team.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Channel object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">team</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the team this channel belongs to.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the channel.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">display_name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The display name for the channel.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">type</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The type of channel. Will have one the following values:<br /> <kbd>"O"</kbd> for a public channel.<br /> <kbd>"P"</kbd> for a private channel.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">header</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The channel header.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">purpose</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The channel purpose.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">scheme</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the permissions scheme that applies to this team.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## User object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">username</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s username. This is the unique identifier for the user.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">email</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s email address.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">auth_service</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The authentication service used for this user account. This field will be absent for user/password authentication.<br /> <kbd>"gitlab"</kbd> - GitLab authentication.<br /> <kbd>"ldap"</kbd> - LDAP authentication (Enterprise and Professional)<br /> <kbd>"saml"</kbd> - Generic SAML based authentication (Enterprise)<br /> <kbd>"google"</kbd> - Google OAuth authentication (Enterprise)<br /> <kbd>"entra id"</kbd> - Microsoft Entra ID OAuth Authentication (Enterprise)</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">auth_data</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The authentication data if <kbd>auth_service</kbd> is used. The value depends on the <kbd>auth_service</kbd> that is specified.<br /> The data comes from the following fields for the respective auth_services:<br /> <kbd>"gitlab"</kbd> - The value of the Id attribute provided in the GitLab auth data.<br /> <kbd>"ldap"</kbd> - The value of the LDAP attribute specified as the "ID Attribute" in the Mattermost LDAP configuration.<br /> <kbd>"saml"</kbd> - The value of the SAML email address attribute.<br /> <kbd>"google"</kbd> - The value of the OAuth Id attribute.<br /> <kbd>"office365"</kbd> - The value of the OAuth Id attribute.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">nickname</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s nickname.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">first_name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s first name.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">last_name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s last name.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">position</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s position.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">roles</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s roles. </td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">locale</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s localization configuration.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">use_markdown_preview</td>
|
||||
<td valign="middle">bool</td>
|
||||
<td><kbd>"true"</kbd> if the user has enabled markdown preview in the message input box.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">use_formatting</td>
|
||||
<td valign="middle">bool</td>
|
||||
<td><kbd>"true"</kbd> if the user has enabled post formatting for links, emoji, text styles, and line breaks.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">show_unread_section</td>
|
||||
<td valign="middle">string</td>
|
||||
<td><kbd>"true"</kbd> if the user has enabled showing unread messages at top of channel sidebar.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">theme</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s theme. Formatted as a Mattermost theme string.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">military_time</td>
|
||||
<td valign="middle">string</td>
|
||||
<td><kbd>"true"</kbd> if the user has enabled a 24-hour clock. <kbd>"false"</kbd> if using a 12-hour clock.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">collapse_previews</td>
|
||||
<td valign="middle">string</td>
|
||||
<td><kbd>"true"</kbd> if user collapses link preview by default. <kbd>"false"</kbd> if user expands link previews by default.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">message_display</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The style the user prefers for displayed messages. Options are <kbd>"clean"</kbd> if the user uses the standard style or <kbd>"compact"</kbd> if the user uses compact style.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">channel_display_mode</td>
|
||||
<td valign="middle">string</td>
|
||||
<td><kbd>"full"</kbd> if the users displays channel messages at the full width of the screen or <kbd>"centered"</kbd> if the user uses a fixed width, centered block.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">tutorial_step</td>
|
||||
<td valign="middle">string</td>
|
||||
<td><kbd>"1"</kbd>, <kbd>"2"</kbd>, or <kbd>"3"</kbd> indicates which specified tutorial step to start with for the user. <kbd>"999"</kbd> skips the tutorial.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">email_interval</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Email batching interval to use during bulk import. </td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">delete_at</td>
|
||||
<td valign="middle">int64</td>
|
||||
<td>Timestamp of when the user was deactivated.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">teams</td>
|
||||
<td valign="middle">array</td>
|
||||
<td>The teams which the user is member of. Is an array of <b>UserTeamMembership</b> objects.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">notify_props</td>
|
||||
<td valign="middle">object</td>
|
||||
<td>The user’s notify preferences, as defined by the <b>UserNotifyProps</b> object.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## UserNotifyProps object
|
||||
|
||||
This object is a member of the User object.
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">desktop</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for sending desktop notifications. Will be one of the following values:<br /> <kbd>"all"</kbd> - For all activity.<br /> <kbd>"mention"</kbd> - Only for mentions.<br /> <kbd>"none"</kbd> - Never.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">desktop_sound</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for whether desktop notification sound is played. Will be one of the following values:<br /> <kbd>"true"</kbd> - Sound is played.<br /> <kbd>"false"</kbd> - Sound is not played.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">email</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for email notifications. Will be one of the following values:<br /> <kbd>"true"</kbd> - Email notifications are sent immediately.<br /> <kbd>"false"</kbd> - Email notifications are not sent.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">mobile</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for sending mobile push notifications. Will be one of the following values:<br /> <kbd>"all"</kbd> - For all activity.<br /> <kbd>"mention"</kbd> - Only for mentions.<br /> <kbd>"none"</kbd> - Never.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">mobile_push_status</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for when push notifications are triggered. Will be one of the following values:<br /> <kbd>"online"</kbd> - When online, away or offline.<br /> <kbd>"away"</kbd> - When away or offline.<br /> <kbd>"offline"</kbd> - When offline.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">channel</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for whether @all, @channel, and @here trigger mentions. Will be one of the following values:<br /> <kbd>"true"</kbd> - Mentions are triggered.<br /> <kbd>"false"</kbd> - Mentions are not triggered.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">comments</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for reply mention notifications. Will be one of the following values:<br /> <kbd>"any"</kbd> - Trigger notifications on messages in reply threads that the user starts or participates in.<br /> <kbd>"root"</kbd> - Trigger notifications on messages in threads that the user starts.<br /> <kbd>"never"</kbd> - Do not trigger notifications on messages in reply threads unless the user is mentioned.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">mention_keys</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for custom non-case sensitive words that trigger mentions. Words are separated by commas.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## UserTeamMembership object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the team this user is a member of.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">roles</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The roles the user has within this team. </td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">theme</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The user’s theme for this team. Formatted as a Mattermost theme string.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">channels</td>
|
||||
<td valign="middle">array</td>
|
||||
<td>The channels within this team that the user is a member of. Listed as an array of <b>UserChannelMembership</b> objects.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## UserChannelMembership object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the channel in the parent team that this user is a member of.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">roles</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The roles the user has within this channel. </td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">notify_props</td>
|
||||
<td valign="middle">object</td>
|
||||
<td>The notify preferences for this user in this channel as defined by the <b>ChannelNotifyProps</b> object.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">favorite</td>
|
||||
<td valign="middle">boolean</td>
|
||||
<td>Whether the channel is marked as a favorite for this user. Will be one of the following values:<br /> <kbd>"true"</kbd> - Yes.<br /> <kbd>"false"</kbd> - No.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">mention_count</td>
|
||||
<td valign="middle">int64</td>
|
||||
<td>The mention preferences for this user in this channel as defined by the <b>ChannelMentionCount</b> object.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">mention_count_root</td>
|
||||
<td valign="middle">int64</td>
|
||||
<td>The mention preferences for this user in this channel as defined by the <b>ChannelMentionCountRoot</b> object.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">urgent_mention_count</td>
|
||||
<td valign="middle">int64</td>
|
||||
<td>The mention preferences for this user in this channel as defined by the <b>UrgendMentionCount</b> object.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">msg_count</td>
|
||||
<td valign="middle">int64</td>
|
||||
<td>The mention preferences for this user in this channel as defined by the <b>MsgCount</b> object.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">msg_count_root</td>
|
||||
<td valign="middle">int64</td>
|
||||
<td>The mention preferences for this user in this channel as defined by the <b>MsgCountRoot</b> object.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">last_viewed_at</td>
|
||||
<td valign="middle">int64</td>
|
||||
<td>The mention preferences for this user in this channel as defined by the <b>LastViewedAt</b> object.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### ChannelNotifyProps object
|
||||
|
||||
This object is a member of the ChannelMembership object.
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">desktop</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for sending desktop notifications. Will be one of the following values:<br /> <kbd>"default"</kbd> - Global default.<br /> <kbd>"all"</kbd> - For all activity.<br /> <kbd>"mention"</kbd> - Only for mentions.<br /> <kbd>"none"</kbd> - Never.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">mobile</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for sending mobile notifications. Will be one of the following values:<br /> <kbd>"default"</kbd> - Global default.<br /> <kbd>"all"</kbd> - For all activity.<br /> <kbd>"mention"</kbd> - Only for mentions.<br /> <kbd>"none"</kbd> - Never.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">mark_unread</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>Preference for marking channel as unread. Will be one of the following values:<br /> <kbd>"all"</kbd> - For all unread messages.<br /> <kbd>"mention"</kbd> - Only for mentions.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Post object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">team</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the team that this post is in.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">channel</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The name of the channel that this post is in.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">user</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The username of the user for this post.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">message</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The message that the post contains.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">props</td>
|
||||
<td valign="middle">object</td>
|
||||
<td>The props for a post. Contains additional formatting information used by integrations and bot posts. For a more detailed explanation see the <a href="https://docs.mattermost.com/developer/message-attachments.html">message attachments documentation</a>.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">create_at</td>
|
||||
<td valign="middle">int</td>
|
||||
<td>The timestamp for the post, in milliseconds since the Unix epoch.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">reactions</td>
|
||||
<td valign="middle">array</td>
|
||||
<td>The emoji reactions to this post. Will be an array of Reaction objects.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Reply object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">user</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The username of the user for this reply.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">message</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The message that the reply contains.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">create_at</td>
|
||||
<td valign="middle">int</td>
|
||||
<td>The timestamp for the reply, in milliseconds since the Unix epoch.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Reaction object
|
||||
|
||||
This object is a member of the Post object.
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">user</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The username of the user for this reply.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">emoji_name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The emoji of the reaction.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">create_at</td>
|
||||
<td valign="middle">int</td>
|
||||
<td>The timestamp for the reply, in milliseconds since the Unix epoch.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Emoji object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">name</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The emoji name.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">image</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The path (either absolute or relative to the current working directory) to the image file for this emoji.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## DirectChannel object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">members</td>
|
||||
<td valign="middle">array</td>
|
||||
<td>List of channel members.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">favorited_by</td>
|
||||
<td valign="middle">array</td>
|
||||
<td>List of channel members who have favorited the direct channel.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">header</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The channel header.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## DirectPost object
|
||||
|
||||
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}>
|
||||
<tr class="row-odd">
|
||||
<th class="head">Field name</th>
|
||||
<th class="head">Type</th>
|
||||
<th class="head">Description</th>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">user</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The username of the user for this post.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">message</td>
|
||||
<td valign="middle">string</td>
|
||||
<td>The message that the post contains.</td>
|
||||
</tr>
|
||||
<tr class="row-odd">
|
||||
<td valign="middle">create_at</td>
|
||||
<td valign="middle">int</td>
|
||||
<td>The timestamp for the post, in milliseconds since the Unix epoch.</td>
|
||||
</tr>
|
||||
</table>
|
||||
76
docs/main/administration-guide/manage/cloud-byok.mdx
Normal file
76
docs/main/administration-guide/manage/cloud-byok.mdx
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: "Cloud Dedicated Bring Your Own Key"
|
||||
---
|
||||
Bring Your Own Key (BYOK) provides Enterprise Cloud customers with autonomy over their encryption key life cycle. BYOK supports encryption at rest with custom KMS keys that the enterprise provides and maintains.
|
||||
|
||||
**BYOK requires a subscription to Mattermost Cloud Enterprise Dedicated**, which offers enhanced data security and compliance by ensuring that enterprises have full control over their data encryption processes.
|
||||
|
||||
In Mattermost Cloud Enterprise Dedicated, you can use KMS keys in 2 ways:
|
||||
|
||||
- One KMS key for all services; or,
|
||||
|
||||
- Per-service KMS keys (EBS, RDS, S3)
|
||||
- Keys do not need to be unique to each service.
|
||||
- All services must be encrypted at rest.
|
||||
- Selective enablement of this feature can be supported.
|
||||
- In cases where a global database is needed, we recommend providing 2 KMS keys (1 per region).
|
||||
|
||||
## Configure BYOK
|
||||
|
||||
1. Enterprise customer provides their AWS KMS ARN to the Mattermost Infrastructure SRE team.
|
||||
2. Enterprise customer adds the following blocks to their KMS Policy for the AWS KMS ARN provided:
|
||||
|
||||
``` json
|
||||
{
|
||||
"Sid": "Allow use of the key",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::<MATTERMOST_AWS_ACCOUNT_ID>:user/mattermost-cloud-<environment>-provisioning-<VPC_ID>"
|
||||
},
|
||||
"Action": [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:DescribeKey"
|
||||
],
|
||||
"Resource": "<CUSTOM_CUSTOMER_KMS_ID>"
|
||||
},
|
||||
{
|
||||
"Sid": "Allow use of the key role nodes",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::<MATTERMOST_AWS_ACCOUNT_ID>:role/nodes.<CLUSTER_ID>-kops.k8s.local"
|
||||
},
|
||||
"Action": [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:DescribeKey"
|
||||
],
|
||||
"Resource": "<CUSTOM_CUSTOMER_KMS_ID>"
|
||||
},
|
||||
```
|
||||
|
||||
3. The Mattermost Infrastructure SRE team updates the kops cluster and S3, RDS resources after the KMS policy is updated on the customer's end.
|
||||
|
||||
Alternatively, the Enterprise customer can provide an external key (non-KMS) to the Mattermost Infrastructure SRE team that Mattermost maintains on behalf of the customer. This path offers less control to customers but simplifies the setup process.
|
||||
|
||||
### Requirements
|
||||
|
||||
- Customers must own their AWS Account. (In the alternative path mentioned above this is delegated to Mattermost.)
|
||||
- Customers oversee the maintenance life cycle of their custom KMS key.
|
||||
- A valid AWS KMS ARN for encrypting storage and databases should be provided to the Infrastructure SRE team.
|
||||
- The customer should incorporate the provided policy blocks from the Infrastructure SRE team into their KMS key policy.
|
||||
|
||||
### Considerations
|
||||
|
||||
- Changing the AWS KMS key in the database necessitates downtime due to AWS Aurora's encryption [limitations.](https://repost.aws/knowledge-center/update-encryption-key-rds)
|
||||
- Proper communication is essential for setting expectations and scheduling changes.
|
||||
|
||||
## Conclusion
|
||||
|
||||
If you are a large enterprise with compliance requirements, or are working in highly-regulated industries, using Mattermost Cloud Dedicated with BYOK ensures full data control.
|
||||
|
||||
For any further assistance or queries, talk to a [Mattermost Expert](https://mattermost.com/contact-sales/)
|
||||
377
docs/main/administration-guide/manage/cloud-data-export.mdx
Normal file
377
docs/main/administration-guide/manage/cloud-data-export.mdx
Normal file
@@ -0,0 +1,377 @@
|
||||
---
|
||||
title: "Migrate between self-hosted and Cloud"
|
||||
---
|
||||
This document outlines the process for migrating an existing Mattermost instance [from self-hosted to Cloud](#migrate-from-self-hosted-to-cloud), and [from Cloud to self-hosted](#migrate-from-cloud-to-self-hosted).
|
||||
|
||||
<Note>
|
||||
|
||||
Migrating an existing Mattermost instance to another using the same deployment method follows the same process that's documented below, regardless as to whether the source or destination of the migration is in the Cloud or self-hosted. **These steps will work for both Cloud and self-hosted Mattermost instances**.
|
||||
|
||||
</Note>
|
||||
|
||||
## Migrate from self-hosted to Cloud
|
||||
|
||||
When you migrate from self-hosted to Cloud, you'll need to open a ticket with the Mattermost Support team so they can assist you with the process. The information below describes the migration process. Before you get started, visit our [Support site](https://support.mattermost.com/hc/en-us/requests/new) to open a ticket.
|
||||
|
||||
<Important>
|
||||
|
||||
- This migration process is only available to customers using paid Mattermost editions.
|
||||
- We recommend reviewing the knowledge base article on [migrating from self-hosted to Cloud](https://support.mattermost.com/hc/en-us/articles/4412503667604-Migrating-from-Self-hosted-Mattermost-Instance-to-Cloud-Mattermost-Instance) before starting a migration to familiarize yourself with key considerations, required prerequisites, and our guidance on testing your export.
|
||||
|
||||
</Important>
|
||||
|
||||
Before you begin your migration, take note of the following information before you begin:
|
||||
|
||||
**User Authentication**
|
||||
|
||||
If you are using the email login method, users will need to reset their passwords after the migration has been completed. Other authentication methods, such as LDAP and GitLab SSO, required changes to your infrastructure allowing the specific authentication method to function in Mattermost cloud.
|
||||
|
||||
**Plugins**
|
||||
|
||||
If you’re using plugins that aren’t listed on the Marketplace, they won’t be included in the export and you won’t have access to them going forward. See the list of supported plugins by visiting the [integrations overview](/integrations-guide/integrations-guide-index#plugins) documentation.
|
||||
|
||||
**Data**
|
||||
|
||||
The migration only includes data from Channels. No Playbooks data is exported.
|
||||
|
||||
### Migration process
|
||||
|
||||
**Export from your self-hosted instance**
|
||||
|
||||
Use your administrator credentials to log into your self-hosted Mattermost server. Once you're logged in, run:
|
||||
|
||||
```
|
||||
mmctl export create --attachments
|
||||
```
|
||||
|
||||
This creates a full export of the server, and includes attached files. If you don’t want to export attached files, leave out `--attachments`.
|
||||
|
||||
This process can take some time, so `mmctl` will return immediately, and the job will run in the background until the export is fully created. If successful, the command will immediately output a job ID, like this:
|
||||
|
||||
```
|
||||
Export process job successfully created, ID: yfrr9ku5i7fjubeshs1ksrknzc
|
||||
```
|
||||
|
||||
While the job is running, its status can be checked using the ID that was provided when it was created, and when it's done the output will look similar to this:
|
||||
|
||||
```
|
||||
mmctl export job show yfrr9ku5i7fjubeshs1ksrknzc
|
||||
ID: yfrr9ku5i7fjubeshs1ksrknzc
|
||||
Status: success
|
||||
Created: 2021-11-03 10:44:13 -0500 CDT
|
||||
Started: 2021-11-03 10:44:23 -0500 CDT
|
||||
```
|
||||
|
||||
The completed file will be downloaded to your desktop as a `.zip` file.
|
||||
|
||||
<Note>
|
||||
|
||||
Do not rename the file as the file name is referenced in log files, which are used by the Support team to validate the exported file.
|
||||
|
||||
</Note>
|
||||
|
||||
The Support team will provide you with S3 credentials so you can upload the exported file. Once you’ve uploaded the file, please contact the Support team and let them know.
|
||||
|
||||
### Create a new workspace on the Mattermost Cloud
|
||||
|
||||
In the meantime, you can log into Mattermost Cloud with your Mattermost credentials and create a Cloud workspace.
|
||||
|
||||
<Note>
|
||||
|
||||
Do not create any users in your Mattermost Cloud instance as the migration process performs this task for you.
|
||||
|
||||
</Note>
|
||||
|
||||
### Importing your data into your Mattermost Cloud instance
|
||||
|
||||
Once the export upload to the provided S3 bucket is complete and you’ve shared your Mattermost Cloud instance name/URL, Support can begin the import step.
|
||||
|
||||
Depending on the size of the export this process can take some time. Support will contact you as soon as the import is complete. During this time it is highly recommended you do not use your Mattermost Cloud instance.
|
||||
|
||||
### Start using your Mattermost Cloud instance
|
||||
|
||||
When the export is complete, you can log into your Cloud instance and can invite your users to log in.
|
||||
|
||||
<Note>
|
||||
|
||||
We recommend that you keep your self-hosted Mattermost server until you’ve been using your Cloud instance for a while and all is verified as is as expected.
|
||||
|
||||
</Note>
|
||||
|
||||
## Migrate from Cloud to self-hosted
|
||||
|
||||
You can migrate your Cloud workspace data to a self-hosted deployment at any time.
|
||||
|
||||
### How does the process work?
|
||||
|
||||
Before you export and migrate your data, you must [install Mattermost](/deployment-guide/deployment-guide-index) on the server you’ll be using to run Mattermost. The migration is done using the mmctl CLI tool, which is a remote CLI tool for Mattermost that's installed locally and uses the Mattermost API. `mmctl` is pre-installed.
|
||||
|
||||
The [mmctl usage notes](/administration-guide/manage/mmctl-command-line-tool#mmctl-usage-notes) provide some additional context and information which you can reference before and during the process.
|
||||
|
||||
You'll be using the [mmctl export](/administration-guide/manage/mmctl-command-line-tool#mmctl-export) commands to export your Cloud data for channels, messages, users, etc. The export file is downloaded to a location specified in the export commands. Once the export is complete, you'll import the data into your self-hosted instance.
|
||||
|
||||
Alternatively, you can export the data to an Amazon S3 cloud storage location in cases where an export is quite large and challenging to download from the Mattermost server. See the [create the export](#create-the-export) section below for details.
|
||||
|
||||
<Note>
|
||||
|
||||
Prior to migrating your data from Cloud, please ensure you have the appropriate permissions within your organization to carry out the data export which may contain sensitive information. Mattermost is not liable for any actions taken after the data export.
|
||||
|
||||
Moreover, the export process doesn’t include integrations or any custom data. Other aspects of your instance, such as specific security settings and requirements, are also not included. For assistance with migrating additional data and settings, see our support options: [https://mattermost.com/support/](https://mattermost.com/support/).
|
||||
|
||||
</Note>
|
||||
|
||||
Once `mmctl` is authenticated, you can generate the export from the source instance.
|
||||
|
||||
## Authenticate
|
||||
|
||||
Authentication is done with either Mattermost login credentials or an authentication token. First, use your administrator credentials to log into the instance with mmctl, replacing <code>example-source-domain.com</code> with the network address of the source instance:
|
||||
|
||||
```
|
||||
mmctl auth login https://yourdomain.cloud.mattermost.com
|
||||
```
|
||||
|
||||
You'll be prompted for a username (use your admin user), password, and for a connection name. The connection name can be anything you want, and it's used to identify this set of credentials in the future, for your convenience. Then you will be able to start the export process.
|
||||
|
||||
## Create the export
|
||||
|
||||
<Important>
|
||||
|
||||
If your Mattermost Cloud deployment includes plugins that aren't listed on the Cloud Marketplace, those plugins won't be included in the export, and you won't have access to those plugins going forward. See the [integrations](/integrations-guide/integrations-guide-index#plugins) documentation for a list of Cloud-supported integrations.
|
||||
|
||||
</Important>
|
||||
|
||||
Once you're logged in, run the following `mmctl` command:
|
||||
|
||||
```
|
||||
mmctl export create
|
||||
```
|
||||
|
||||
Running this command creates a full export of the server, including attached files. Append `--no-attachments` if you do not wish to export attached files from your instance, and append `--with-archived-channels` to include archived channels in the export file. This process can take some time, so `mmctl` will return immediately, and the job will run in the background on the Mattermost instance until the export is fully created. If successful, the command will immediately output a job ID, like this:
|
||||
|
||||
```
|
||||
Export process job successfully created, ID: yfrr9ku5i7fjubeshs1ksrknzc
|
||||
```
|
||||
|
||||
While the job is running, its status can be checked using the ID that was provided when it was created, and when it's done the output will look similar to this:
|
||||
|
||||
```
|
||||
mmctl export job show yfrr9ku5i7fjubeshs1ksrknzc
|
||||
ID: yfrr9ku5i7fjubeshs1ksrknzc
|
||||
Status: success
|
||||
Created: 2021-11-03 10:44:13 -0500 CDT
|
||||
Started: 2021-11-03 10:44:23 -0500 CDT
|
||||
```
|
||||
|
||||
Once the status is `success`, download the export onto your local machine. First, discover the name of the completed export file with `mmctl export list`:
|
||||
|
||||
```
|
||||
mmctl export list
|
||||
r3kcj8yuwbramdt714doafi3oo_export.zip
|
||||
```
|
||||
|
||||
This will show all of the exports on the server, so be sure to download the latest one and to delete it when you're done to save storage. Generate a link to download the file with a command like the following, but with the filename of the export on your server:
|
||||
|
||||
```
|
||||
mmctl export generate-presigned-url r3kcj8yuwbramdt714doafi3oo_export.zip
|
||||
```
|
||||
|
||||
<Tip>
|
||||
|
||||
- As an alternative to this last step, from your Mattermost Cloud web instance, you can retrieve the file download link to the export by using the Mattermost slash command `/exportlink [job-id|zip file|latest]`. Use the `latest` option to automatically pull the latest export available, or specify the download link by `job-id` or `zip file`.
|
||||
- Mattermost v8.1.0-RC1 is required to use the `mmctl export generate-presigned-url` command on a self-hosted Mattermost instance. Access the [Mattermost Enterprise v8.1.0-RC1 binary](https://releases.mattermost.com/8.1.0-rc1/mattermost-enterprise-8.1.0-rc1-linux-amd64.tar.gz) or the [Mattermost Team Edition v8.1.0-RC1 binary](https://releases.mattermost.com/8.1.0-rc1/mattermost-team-8.1.0-rc1-linux-amd64.tar.gz).
|
||||
|
||||
</Tip>
|
||||
|
||||
## Upload the export to the new server
|
||||
|
||||
Finally, it's time to take our export from the source server and use it as an import into the destination server. Before proceeding, review and modify the following self-hosted Mattermost configuration settings, where applicable, to ensure a smooth and successful import.
|
||||
|
||||
<table style={{width: '100%'}}>
|
||||
<colgroup>
|
||||
<col style={{width: '39%'}} />
|
||||
<col style={{width: '51%'}} />
|
||||
<col style={{width: '8%'}} />
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>Mattermost configuration setting</strong></td>
|
||||
<td><strong>Large file import recommendation</strong></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><a href="/administration-guide/configure/site-configuration-settings#max-users-per-team">Maximum Users Per Team | Increase this value to a number that **exceeds** the maximum number of users, per team, in the import file. |</a> |</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><a href="/administration-guide/configure/environment-configuration-settings#maximum-file-size">Maximum File Size | Temporarily increase this value to be **larger** than the size of the import file. |</a> | Following a successful import, we strongly recommend reverting this value to a reasonable limit for daily expected usage. |</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><dl>
|
||||
<dt><a href="/administration-guide/configure/environment-configuration-settings#write-timeout">Write Timeout | Temporarily adjust this value based on import file speed and network path to enable the file to upload without timeouts. |</a> | Start with a value of <strong>3600</strong> and adjust if needed. |</dt>
|
||||
<dd>
|
||||
<div class="line-block">Following a successful import, we strongly recommend reverting this setting to its initial or previous value. |</div>
|
||||
</dd>
|
||||
</dl></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><dl>
|
||||
<dt><a href="/administration-guide/configure/environment-configuration-settings#read-timeout">Read Timeout | Temporarily adjust this value based on import file speed and network path to enable the file to upload without timeouts. |</a> | Start with a value of <strong>3600</strong> and adjust if needed. |</dt>
|
||||
<dd>
|
||||
<div class="line-block">Following a successful import, we strongly recommend reverting this setting to its initial or previous value. |</div>
|
||||
</dd>
|
||||
</dl></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><a href="/administration-guide/configure/environment-configuration-settings#amazon-s3-request-timeout">Amazon S3 Request Timeout | If using cloud-based file storage, adjust this value to ensure your storage requests don't time out too soon. |</a> |</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Next, log into the destination server using `mmctl` the same way you logged into the source server:
|
||||
|
||||
```
|
||||
mmctl auth login https://localinstance.company.com
|
||||
```
|
||||
|
||||
Use the following command to upload the export to the destination server. The speed of the upload may vary based on connection speed. When the upload is complete the command will return with the ID of the import:
|
||||
|
||||
```
|
||||
mmctl import upload r3kcj8yuwbramdt714doafi3oo_export.zip
|
||||
Upload session successfully created, ID: cfuq6q9kkjrqfgnph1pew3db4e
|
||||
Import file successfully uploaded, name: xrzs9wrzufntbfcxpy39mdq9hy
|
||||
```
|
||||
|
||||
## Complete the import into the new server
|
||||
|
||||
```
|
||||
mmctl import list available
|
||||
cfuq6q9kkjrqfgnph1pew3db4e_r3kcj8yuwbramdt714doafi3oo_export.zip
|
||||
```
|
||||
|
||||
Run the import job to process to import the export file into the server. The speed of this process may vary based on connection speed. First, start the import process:
|
||||
|
||||
```
|
||||
mmctl import process cfuq6q9kkjrqfgnph1pew3db4e_r3kcj8yuwbramdt714doafi3oo_export.zip
|
||||
```
|
||||
|
||||
Once you've marked the file for processing, you can check the status of the job using `mmctl import job list`:
|
||||
|
||||
```
|
||||
mmctl --local import job list
|
||||
ID: f93jxu1hzty79enwa1xy6f1tbr
|
||||
Status: pending
|
||||
Created: 2021-10-28 13:32:55 +0200 CEST
|
||||
```
|
||||
|
||||
When the job is complete, the `success` status is displayed:
|
||||
|
||||
```
|
||||
mmctl --local import job list
|
||||
ID: f93jxu1hzty79enwa1xy6f1tbr
|
||||
Status: success
|
||||
Created: 2021-10-28 13:32:55 +0200 CEST
|
||||
Started: 2021-10-28 13:33:05 +0200 CEST
|
||||
```
|
||||
|
||||
Then extract the export file to use it by running the following mmctl command:
|
||||
|
||||
```
|
||||
mmctl extract run [flags].
|
||||
```
|
||||
|
||||
Once your migration is complete and you’ve imported your data into your self-hosted instance we recommend that you take a few days to validate your data and ensure everything is working as expected before taking down your Cloud instance.
|
||||
|
||||
<Note>
|
||||
|
||||
If you are using email/password authentication, your users must reset their passwords.
|
||||
|
||||
</Note>
|
||||
|
||||
If you encounter any issues or problems, [contact our support team](https://mattermost.com/support/), or visit the [Mattermost Help Center](https://support.mattermost.com/).
|
||||
|
||||
## Migrate from self-hosted to Cloud
|
||||
|
||||
When you migrate from self-hosted to Cloud, you'll need to open a ticket with the Mattermost Support team so they can assist you with the process. The information below describes the migration process. Before you get started, visit our [Support site](https://support.mattermost.com/hc/en-us/requests/new) to open a ticket.
|
||||
|
||||
<Note>
|
||||
|
||||
This migration process is only available to customers using paid Mattermost editions.
|
||||
|
||||
</Note>
|
||||
|
||||
Before you begin your migration, take note of the following information before you begin:
|
||||
|
||||
**User Authentication**
|
||||
|
||||
If you are using the email login method, users will need to reset their passwords after the migration has been completed. Other authentication methods, such as LDAP and GitLab SSO, required changes to your infrastructure allowing the specific authentication method to function in Mattermost cloud.
|
||||
|
||||
**Plugins**
|
||||
|
||||
If you’re using plugins that aren’t listed on the Marketplace, they won’t be included in the export and you won’t have access to them going forward. You can view the list of plugins [in the Support knowledgebase](https://support.mattermost.com/hc/en-us/articles/5346624843924-Mattermost-Plugin-Marketplace-List-as-of-November-12th-2024).
|
||||
|
||||
**Data**
|
||||
|
||||
The migration only includes channel data. No collaborative playbooks data is exported.
|
||||
|
||||
### Migration process
|
||||
|
||||
**Export from your self-hosted instance**
|
||||
|
||||
Use your administrator credentials to log into your self-hosted Mattermost server. Once you're logged in, run:
|
||||
|
||||
```
|
||||
mmctl export create --attachments
|
||||
```
|
||||
|
||||
This creates a full export of the server, and includes attached files. If you don’t want to export attached files, leave out `--attachments`.
|
||||
|
||||
This process can take some time, so `mmctl` will return immediately, and the job will run in the background until the export is fully created. If successful, the command will immediately output a job ID, like this:
|
||||
|
||||
```
|
||||
Export process job successfully created, ID: yfrr9ku5i7fjubeshs1ksrknzc
|
||||
```
|
||||
|
||||
While the job is running, its status can be checked using the ID that was provided when it was created, and when it's done the output will look similar to this:
|
||||
|
||||
```
|
||||
mmctl export job show yfrr9ku5i7fjubeshs1ksrknzc
|
||||
ID: yfrr9ku5i7fjubeshs1ksrknzc
|
||||
Status: success
|
||||
Created: 2021-11-03 10:44:13 -0500 CDT
|
||||
Started: 2021-11-03 10:44:23 -0500 CDT
|
||||
```
|
||||
|
||||
The completed file will be downloaded to your desktop as a `.zip` file.
|
||||
|
||||
<Note>
|
||||
|
||||
Do not rename the file as the file name is referenced in log files, which are used by the Support team to validate the exported file.
|
||||
|
||||
</Note>
|
||||
|
||||
The Support team will provide you with S3 credentials so you can upload the exported file. Once you’ve uploaded the file, please [contact our support team](https://mattermost.com/support/) and let them know.
|
||||
|
||||
### Create a new workspace on the Mattermost Cloud
|
||||
|
||||
In the meantime, you can log into Mattermost Cloud with your Mattermost credentials and create a Cloud workspace.
|
||||
|
||||
<Note>
|
||||
|
||||
Do not create any users in your Mattermost Cloud instance as the migration process performs this task for you.
|
||||
|
||||
</Note>
|
||||
|
||||
### Importing your data into your Mattermost Cloud instance
|
||||
|
||||
Once the export upload to the provided S3 bucket is complete and you’ve shared your Mattermost Cloud instance name/URL, Support can begin the import step.
|
||||
|
||||
Depending on the size of the export this process can take some time. Support will contact you as soon as the import is complete. During this time it is highly recommended you do not use your Mattermost Cloud instance.
|
||||
|
||||
### Start using your Mattermost Cloud instance
|
||||
|
||||
When the export is complete, you can log into your Cloud instance and can invite your users to log in.
|
||||
|
||||
<Note>
|
||||
|
||||
We recommend that you keep your self-hosted Mattermost server until you’ve been using your Cloud instance for a while and all is verified as is as expected.
|
||||
|
||||
</Note>
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: "Cloud data residency"
|
||||
---
|
||||
Mattermost Cloud resides in the `aws-us-east-1` region, located in Virginia, United States. The following customer data will be stored at rest in this data center when using Mattermost Cloud:
|
||||
|
||||
- Channels, messages, replies, and channel membership information
|
||||
- Collaborative playbooks and event runs
|
||||
- User accounts and profiles
|
||||
- Files (e.g., images, docs, etc.) uploaded to the Mattermost Service
|
||||
- Plugin, app- or bot-generated messages and files
|
||||
- Data used to measure user count, usage, and revenue
|
||||
- Data used for analytics and to measure quality of service, e.g., sanitized logs
|
||||
- IDs generated by Mattermost on behalf of the customer
|
||||
|
||||
If you require your data to reside in an area outside of the United States, talk to a [Mattermost Expert](https://mattermost.com/contact-sales/), or consider [deploying one of our self-hosted options](https://mattermost.com/download/) that provides full control of your data. You may also work with [one of our partners](https://mattermost.com/partners) for deploying and hosting your Mattermost server.
|
||||
86
docs/main/administration-guide/manage/cloud-ip-filtering.mdx
Normal file
86
docs/main/administration-guide/manage/cloud-ip-filtering.mdx
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
title: "Cloud IP filtering"
|
||||
---
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
|
||||
IP filtering is a powerful security feature that allows system admins to control access to their workspace by defining approved IP ranges. Only users within these specified IP ranges can access the workspace, ensuring enhanced security for your workspace.
|
||||
|
||||
**IP filtering requires a subscription to Mattermost Cloud Enterprise.**
|
||||
|
||||
## Configure IP filtering
|
||||
|
||||
1. **Log in as system admin**: As a system admin, access the System Console of your workspace by selecting the **Product** <img src={useBaseUrl('/img/ui/products_E82F.svg')} alt="Navigate between Channels, collaborative playbooks, and boards using the product menu icon." className="theme-icon" /> menu and selecting **System Console**.
|
||||
|
||||
2. **Go to Site Configuration**: Go to the **Site Configuration** section.
|
||||
|
||||
3. **Access IP Filtering Settings**: Under **Site Configuration**, select **IP Filtering** to access the IP Filtering settings.
|
||||
|
||||

|
||||
|
||||
## About CIDR notation
|
||||
|
||||
CIDR (Classless Inter-Domain Routing) notation is used to specify a range of IP addresses. It consists of an IP address followed by a forward slash and a number indicating the network's prefix length. For example:
|
||||
|
||||
- `192.168.0.0/24` represents the IP range from `192.168.0.0` to `192.168.0.255`.
|
||||
- The `/24` signifies that the first 24 bits are the network address, leaving 8 bits for host addresses.
|
||||
|
||||
<Tip>
|
||||
|
||||
For a more in-depth explanation of CIDR notation, refer to [this article](https://aws.amazon.com/what-is/cidr/).
|
||||
|
||||
</Tip>
|
||||
|
||||
## Configure IP filters
|
||||
|
||||
### Enable/disable IP filtering
|
||||
|
||||
System admins have the option to enable or disable IP filtering:
|
||||
|
||||
- **Enable:** To activate IP filtering, ensure at least one IP range is added to the whitelist.
|
||||
- **Disable:** Temporarily disable IP filtering by removing all IP ranges from the whitelist, or by flipping the global IP Filtering toggle in the System Console.
|
||||
|
||||

|
||||
|
||||
### Add an IP range
|
||||
|
||||
To add an IP range to the whitelist, follow these steps:
|
||||
|
||||
1. Select the **Add Filter** button within the IP Filtering settings page in the System Console.
|
||||
2. Enter the IP range using CIDR notation. For example, `192.168.1.0/24`.
|
||||
3. Provide a descriptive name or label for the IP range to ease identification in the future.
|
||||
4. Save the changes.
|
||||
|
||||

|
||||
|
||||
<Note>
|
||||
|
||||
The System Console will restrict you from saving changes if the IP address you are accessing your workspace on is not within the ranges you have specified at the time you save your changes.
|
||||
|
||||

|
||||
|
||||
</Note>
|
||||
|
||||
### Edit or remove an existing IP range
|
||||
|
||||
To edit or remove an existing IP range from the whitelist:
|
||||
|
||||
1. Locate the IP range you want to modify within the **IP Filtering** settings.
|
||||
2. Hover over the rule you'd like to edit or delete, and select the respective edit or delete option beside the IP range.
|
||||
3. Make necessary changes or confirm the removal of the IP range.
|
||||
4. Save your changes by selecting **Save**.
|
||||
|
||||
### Unable to access your workspace?
|
||||
|
||||
If you are unable to access your workspace due to previously set IP filters, and you need to regain access to your workspace, [contact our support team](https://mattermost.com/support/).
|
||||
|
||||
<Note>
|
||||
|
||||
Going through this process will disable **all** existing rules applied to your workspace. This means that any IP address will now be able to access it.
|
||||
|
||||
</Note>
|
||||
|
||||
## Conclusion
|
||||
|
||||
By configuring IP filters using CIDR notation, system admins can effectively manage access to the workspace, enhancing security by allowing access only from specified IP ranges.
|
||||
|
||||
For any further assistance or queries, [contact our support team](https://mattermost.com/support/).
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "Cloud workspace management"
|
||||
---
|
||||
This section of the guide is for system admins of Mattermost Cloud deployments.
|
||||
|
||||
<Tip>
|
||||
|
||||
If you're the system admin for a Mattermost self-hosted workspace, see the [Self-hosted administration](/administration-guide/manage/admin/server-maintenance) documentation.
|
||||
|
||||
</Tip>
|
||||
|
||||
- [Workspace migration](/administration-guide/manage/cloud-data-export) - Migrate your workspace using the mmctl tool.
|
||||
- [Cloud data residency](/administration-guide/manage/cloud-data-residency) - Find information about your data in the Cloud.
|
||||
- [Cloud IP filtering](/administration-guide/manage/cloud-ip-filtering) - Restrict access to your Mattermost Cloud workspace to a specific IP address range.
|
||||
- [Cloud Bring Your Own Key (BYOK)](/administration-guide/manage/cloud-byok) - Learn how to manage data encryption processes within a Mattermost Cloud Enterprise Dedicated deployment.
|
||||
|
||||
[Book a live demo](https://mattermost.com/request-demo/) or [talk to a Mattermost expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization's secure collaboration needs. Or try Mattermost yourself with a [1-hour preview](https://mattermost.com/sign-up/) for instant access to a live sandbox environment.
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: "Code signing custom builds"
|
||||
---
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Code signing is an essential process for ensuring the authenticity and integrity of your custom `Mattermost` builds. This guide provides steps on how to code sign a build using your own certificates for Windows, Mac, and Linux.
|
||||
|
||||
<Important>
|
||||
|
||||
Make sure to follow each operating system's guidelines and best practices for signing applications.
|
||||
|
||||
</Important>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="windows" label="Windows">
|
||||
|
||||
1. **Code Signing Certificate**: Obtain a certificate from a Certificate Authority (CA) or use a self-signed certificate if suitable.
|
||||
2. **SignTool**: Available as part of the Windows SDK.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="linux" label="Linux">
|
||||
|
||||
1. **GPG Key**: Create a GPG key if you don't have one.
|
||||
2. **GnuPG**: Install [GnuPG](https://gnupg.org/howtos/card-howto/en/ch02.html) if not already installed.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="mac" label="Mac">
|
||||
|
||||
1. **Developer ID Application Certificate**: Obtain from Apple. It requires an Apple Developer account.
|
||||
2. **Xcode**: Ensure [Xcode](https://developer.apple.com/xcode/) is installed.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Process
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="windows" label="Windows">
|
||||
|
||||
1. **Install SignTool**: Install the Windows SDK to access the `SignTool` utility.
|
||||
|
||||
2. **Obtain a Code Signing Certificate**: Purchase or create a certificate (`.pfx` file) via a CA.
|
||||
|
||||
3. **Import the Certificate**: Open the `.pfx` file and import it into the Windows Certificate Store.
|
||||
|
||||
4. **Sign the Executable**
|
||||
|
||||
- Open the command prompt as Administrator.
|
||||
- Use `SignTool` to sign your executable:
|
||||
|
||||
``` sh
|
||||
signtool sign /v /s "My" /sha1 <cert hash> /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 <path-to-your-executable>
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="linux" label="Linux">
|
||||
|
||||
1. **Create or Import Your GPG Key**: If you don't have a GPG key, create one:
|
||||
|
||||
``` sh
|
||||
gpg --full-generate-key
|
||||
```
|
||||
|
||||
Alternatively, import an existing GPG key, if you have one:
|
||||
|
||||
``` sh
|
||||
gpg --import /path/to/your-key.asc
|
||||
```
|
||||
|
||||
2. **Sign the Package**: Use `dpkg-sig` to sign a Debian package:
|
||||
|
||||
``` sh
|
||||
dpkg-sig --sign builder your-package.deb
|
||||
```
|
||||
|
||||
Use `rpmsign` to sign an RPM package:
|
||||
|
||||
``` sh
|
||||
rpmsign --addsign your-package.rpm
|
||||
```
|
||||
|
||||
3. **Verify the Signature**: Verify the signature of a `.deb` package:
|
||||
|
||||
``` sh
|
||||
dpkg-sig --verify your-package.deb
|
||||
```
|
||||
|
||||
Verify the signature of an `.rpm` package:
|
||||
|
||||
``` sh
|
||||
rpm --checksig your-package.rpm
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="mac" label="Mac">
|
||||
|
||||
1. **Obtain a Code Signing Certificate**: Create a `Developer ID Application` certificate in your Apple Developer account and download it.
|
||||
|
||||
2. **Import the Certificate**: Double-click the certificate to import it into the Keychain.
|
||||
|
||||
3. **Sign the Application**: Use the `codesign` tool from Xcode to sign your application:
|
||||
|
||||
``` sh
|
||||
codesign --deep --force --verify --verbose --sign "Developer ID Application: Your Name (TeamID)" /path/to/your.app
|
||||
```
|
||||
|
||||
4. \[Optional\] **Verify the Signature**: Verify the signature to ensure everything is correctly signed:
|
||||
|
||||
``` sh
|
||||
spctl --assess --verbose=4 /path/to/your.app
|
||||
codesign -dv --verbose=4 /path/to/your.app
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
- **Windows**: Use `SignTool` from the Windows SDK with your imported code signing certificate.
|
||||
- **Mac**: Use `codesign` and `spctl` tools from Xcode with your Apple Developer ID certificate.
|
||||
- **Linux**: Use `GnuPG` to create/sign with your GPG key, `dpkg-sig` for `.deb` packages, and `rpmsign` for `.rpm` packages.
|
||||
385
docs/main/administration-guide/manage/command-line-tools.mdx
Normal file
385
docs/main/administration-guide/manage/command-line-tools.mdx
Normal file
@@ -0,0 +1,385 @@
|
||||
---
|
||||
title: "Command line tools"
|
||||
---
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
In self-managed deployments, a `mattermost` command is available for configuring the system from the directory where the Mattermost server is installed. For an overview of the Mattermost command line interface (CLI), [read this article](https://medium.com/@santosjs/plugging-in-to-the-mattermost-cli-8cdcef2bd1f6) from Santos.
|
||||
|
||||
<Important>
|
||||
|
||||
From Mattermost v6.0, the majority of these CLI commands have been replaced with equivalents available using the [mmctl command line tool](/administration-guide/manage/mmctl-command-line-tool). However, [mattermost import](/administration-guide/manage/command-line-tools#mattermost-import) commands, [mattermost export](/administration-guide/manage/command-line-tools#mattermost-export) commands, and related subcommands, remain available and fully supported from Mattermost v6.0.
|
||||
|
||||
</Important>
|
||||
|
||||
These `mattermost` commands include the following functionality:
|
||||
|
||||
**Compliance Export**
|
||||
|
||||
- Export data
|
||||
- Schedule an export job
|
||||
|
||||
**Database**
|
||||
|
||||
- Initialize the database, execute migrations, and load custom defaults
|
||||
- Migrate the database schema for unapplied migrations
|
||||
- Reset the database to its initial state
|
||||
- Return the most recently applied version number
|
||||
- Roll back database migrations
|
||||
|
||||
**Server Operations**
|
||||
|
||||
- Start the Mattermost job server
|
||||
- Run the Mattermost server
|
||||
- Display Mattermost version information
|
||||
|
||||
## Use the CLI
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="via-mattermost" label="Via Mattermost">
|
||||
|
||||
To run the CLI commands, you must be in the Mattermost root directory. On a default installation of Mattermost, the root directory is `/opt/mattermost`. If you followed our standard [installation process](/deployment-guide/deployment-guide-index), you must run the commands as the user `mattermost`. The name of the executable is `mattermost`, and it can be found in the `/opt/mattermost/bin` directory.
|
||||
|
||||
For example, to get the Mattermost version on a default installation of Mattermost:
|
||||
|
||||
``` sh
|
||||
cd /opt/mattermost/
|
||||
sudo -u mattermost bin/mattermost version
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
- Ensure you run the Mattermost binary as the `mattermost` user. Running it as `root` user (for example) may cause complications with permissions as the binary initiates plugins and accesses various files when running CLI commands. Running the server as `root` may result in ownership of the plugins and files to be overwritten as well as other potential permissions errors.
|
||||
|
||||
- When running CLI commands on a Mattermost installation that has the configuration stored in the database, you might need to pass the database connection string as:
|
||||
|
||||
``` sh
|
||||
bin/mattermost --config="postgres://mmuser:mostest_password@localhost:5432/mattermost_test?sslmode=disable\u0026connect_timeout=10"
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="via-gitlab-omnibus" label="Via GitLab Omnibus">
|
||||
|
||||
On GitLab Omnibus, you must be in the following directory when you run CLI commands: `/opt/gitlab/embedded/service/mattermost`. Also, you must run the commands as the user *mattermost* and specify the location of the configuration file. The executable is `/opt/gitlab/embedded/bin/mattermost`.
|
||||
|
||||
For example, to get the Mattermost version on GitLab Omnibus:
|
||||
|
||||
``` sh
|
||||
cd /opt/gitlab/embedded/service/mattermost
|
||||
sudo /opt/gitlab/embedded/bin/chpst -e /opt/gitlab/etc/mattermost/env -P -U mattermost:mattermost -u mattermost:mattermost /opt/gitlab/embedded/bin/mattermost version
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
The example commands on this documentation page are for a default installation of Mattermost. You must modify the commands so that they work on GitLab Omnibus.
|
||||
|
||||
</Note>
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="via-docker-install" label="Via Docker Install">
|
||||
|
||||
On Docker install, the `/mattermost/bin` directory was added to `PATH`, so you can use the CLI directly with the `docker exec` command. Note that the container name may be `mattermostdocker_app_1` if you installed Mattermost with `docker-compose.yml`.
|
||||
|
||||
For example, to get the Mattermost version on a Docker Install:
|
||||
|
||||
``` sh
|
||||
docker exec -it <your-mattermost-container-name> mattermost version
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="via-docker-preview" label="Via Docker Preview">
|
||||
|
||||
The Docker Install tab details and command references below also apply to the [Mattermost docker preview image](https://github.com/mattermost/mattermost-docker-preview).
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
<Note>
|
||||
|
||||
\- The CLI is run in a single node which bypasses the mechanisms that a [High Availability environment](/deployment-guide/server/high-availability-cluster-based-deployment) uses to perform actions across all nodes in the cluster. As a result, when running [CLI commands](/administration-guide/manage/command-line-tools) in a High Availability environment, tasks that change configuration settings require a server restart. - Parameters in CLI commands are order-specific. - If special characters (`!`, `|`, `(`, `)`, `\`, `'`, or `"`) are used, the entire argument needs to be surrounded by single quotes, or the individual characters need to be escaped out.
|
||||
|
||||
</Note>
|
||||
|
||||
## mattermost CLI commands
|
||||
|
||||
Description
|
||||
Commands for configuring and managing your Mattermost instance and users.
|
||||
|
||||
Options
|
||||
``` text
|
||||
-c, --config {string} Configuration file to use. (default "config.json")
|
||||
--disableconfigwatch {boolean} When true, the config.json file will not be reloaded automatically when another process changes it (default "false")
|
||||
```
|
||||
|
||||
Child Commands
|
||||
- [mattermost db](#mattermost-db) - Database commands
|
||||
- [mattermost export](#mattermost-export) - Compliance export commands
|
||||
- [mattermost help](#mattermost-help) - Generate full documentation for the CLI
|
||||
- [mattermost import](#mattermost-import) - Legacy import command
|
||||
- [mattermost jobserver](#mattermost-jobserver) - Start the Mattermost job server
|
||||
- [mattermost server](#mattermost-server) - Run the Mattermost server
|
||||
- [mattermost version](#mattermost-version) - Display version information
|
||||
|
||||
## mattermost db
|
||||
|
||||
Description
|
||||
Commands related to the database
|
||||
|
||||
Child Commands
|
||||
- [mattermost db downgrade](#mattermost-db-downgrade) - Roll back database migrations. Requires either an update plan to roll back to, or comma-separated version numbers to be rolled back.
|
||||
- [mattermost db init](#mattermost-db-init) - Initialize the database, execute migrations, and load custom defaults
|
||||
- [mattermost db migrate](/administration-guide/manage/command-line-tools#mattermost-db-migrate) - Migrate the database schema for unapplied migrations
|
||||
- [mattermost db reset](#mattermost-db-reset) - Reset the database to its initial state
|
||||
- [mattermost db version](#mattermost-db-version) - Return the most recently applied version number
|
||||
|
||||
Options
|
||||
``` text
|
||||
-h, --help help for db
|
||||
-c, --config string Configuration file to use
|
||||
```
|
||||
|
||||
### mattermost db downgrade
|
||||
|
||||
Description
|
||||
Rolls back database migrations. Requires either an update plan to roll back to, or comma-separated version numbers to be rolled back.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost db downgrade
|
||||
```
|
||||
|
||||
Example
|
||||
``` sh
|
||||
mattermost db downgrade 99,100,101
|
||||
```
|
||||
|
||||
Options
|
||||
``` text
|
||||
--<plan-file> string Runs the rollback migrations defined in the plan file.
|
||||
```
|
||||
|
||||
### mattermost db init
|
||||
|
||||
Description
|
||||
Initializes the database for a given data source name (DSN), executes migrations, and loads custom defaults when specified.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost db init
|
||||
```
|
||||
|
||||
Examples
|
||||
Use the `config` flag to pass the DSN:
|
||||
|
||||
``` sh
|
||||
mattermost db init --config postgres://localhost/mattermost
|
||||
```
|
||||
|
||||
Run this command to use the `MM_CONFIG` environment variable:
|
||||
|
||||
``` sh
|
||||
MM_CONFIG=postgres://localhost/mattermost mattermost db init
|
||||
```
|
||||
|
||||
Run this command to set a custom defaults file to be loaded into the database:
|
||||
|
||||
``` sh
|
||||
MM_CUSTOM_DEFAULTS_PATH=custom.json MM_CONFIG=postgres://localhost/mattermost mattermost db init
|
||||
```
|
||||
|
||||
### mattermost db migrate
|
||||
|
||||
Description
|
||||
Migrates the database schema if there are any unapplied migrations.
|
||||
|
||||
Child Commands
|
||||
- [mattermost db downgrade](#mattermost-db-downgrade) - Roll back database migrations.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost db migrate
|
||||
```
|
||||
|
||||
Example
|
||||
``` sh
|
||||
mattermost db migrate
|
||||
```
|
||||
|
||||
Options
|
||||
``` text
|
||||
--auto-recover bool If the migration plan receives an error during migrations, this command will try to rollback migrations already applied within the plan. Not recommended without reviewing migration plan by combining --save-plan and --dry-run options.
|
||||
--save-plan bool Saves the plan for the migration into the file store so that it can be used for reviewing the plan or for downgrading.
|
||||
--dry-run bool Does not apply the migrations, but it validates how the migration would run based on the given conditions.
|
||||
```
|
||||
|
||||
### mattermost db reset
|
||||
|
||||
Description
|
||||
Resets the database to its initial state. Doesn't start the application server. Only starts the store layer and truncates the tables, excluding the `migrations` table.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost db reset
|
||||
```
|
||||
|
||||
Example
|
||||
``` sh
|
||||
bin/mattermost db reset
|
||||
```
|
||||
|
||||
### mattermost db version
|
||||
|
||||
Description
|
||||
Returns the most recently applied version number.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost db version
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
## mattermost export
|
||||
|
||||
<PlanAvailability slug="ent-plus" />
|
||||
|
||||
Description
|
||||
Commands for exporting data for compliance and for merging multiple Mattermost instances.
|
||||
|
||||
Child Commands
|
||||
- [mattermost export actiance](#mattermost-export-actiance) - Deprecated from Mattermost v10.5 in favor of [mattermost export schedule](#mattermost-export-schedule).
|
||||
- [mattermost export csv](#mattermost-export-csv) - Deprecated from Mattermost v10.5.
|
||||
- [mattermost export global-relay-zip](#mattermost-export-global-relay-zip) - Deprecated from Mattermost v10.5.
|
||||
- [mattermost export schedule](#mattermost-export-schedule) - Schedule a compliance export job.
|
||||
- [mattermost export bulk](#mattermost-export-bulk) - Export data to a file compatible with the Mattermost [bulk import format](/administration-guide/onboard/bulk-loading-data). Deprecated in favor of [mmctl export commands](/administration-guide/manage/mmctl-command-line-tool#mmctl-export).
|
||||
|
||||
### mattermost export actiance
|
||||
|
||||
From Mattermost v10.5, this command has been deprecated. It will be added to the mmctl command line tool in a future version. Until then, please use [mattermost export schedule](#mattermost-export-schedule).
|
||||
|
||||
### mattermost export csv
|
||||
|
||||
From Mattermost v10.5, this command has been deprecated. It will be added to the mmctl command line tool in a future version.
|
||||
|
||||
### mattermost export global-relay-zip
|
||||
|
||||
From Mattermost v10.5, this command has been deprecated. It will be added to the mmctl command line tool in a future version.
|
||||
|
||||
### mattermost export schedule
|
||||
|
||||
Description
|
||||
Schedule an export job in a format suitable for importing into a third-party archive system.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost export schedule
|
||||
```
|
||||
|
||||
Example
|
||||
``` sh
|
||||
bin/mattermost export schedule --exportFrom=1513102632
|
||||
```
|
||||
|
||||
Options
|
||||
``` text
|
||||
--exportFrom string Unix timestamp (seconds since epoch, UTC) to export data from.
|
||||
--timeoutSeconds string Set how long the export should run for before timing out.
|
||||
```
|
||||
|
||||
### mattermost export bulk
|
||||
|
||||
From Mattermost v6.0, this command has been deprecated in favor of [mmctl export commands](/administration-guide/manage/mmctl-command-line-tool#mmctl-export) as the supported way to export data out of Mattermost.
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
## mattermost help
|
||||
|
||||
Description
|
||||
Generate full documentation in Markdown format for the Mattermost command line tools.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost help {outputdir}
|
||||
```
|
||||
|
||||
<div id="command-line-tools-mattermost-jobserver">
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
</div>
|
||||
|
||||
## mattermost import
|
||||
|
||||
Description
|
||||
Import data into Mattermost.
|
||||
|
||||
Child Command
|
||||
- [mattermost import bulk](#mattermost-import-bulk) - Import a Mattermost bulk import file. Deprecated in favor of [mmctl import commands](/administration-guide/manage/mmctl-command-line-tool#mmctl-import).
|
||||
|
||||
### mattermost import bulk
|
||||
|
||||
From Mattermost v6.0, this command has been deprecated in favor of [mmctl import commands](/administration-guide/manage/mmctl-command-line-tool#mmctl-import) as the supported way to import data into Mattermost.
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
## mattermost jobserver
|
||||
|
||||
Description
|
||||
Start the Mattermost job server.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost jobserver
|
||||
```
|
||||
|
||||
Example
|
||||
``` sh
|
||||
bin/mattermost jobserver
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
## mattermost server
|
||||
|
||||
Description
|
||||
Runs the Mattermost server.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost server
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
## mattermost version
|
||||
|
||||
<Note>
|
||||
|
||||
From Mattermost v6.5, this CLI command no longer interacts with the database. The [mattermost db migrate](/administration-guide/manage/command-line-tools#mattermost-db-migrate) CLI command has been introduced to trigger schema migrations.
|
||||
|
||||
</Note>
|
||||
|
||||
Desription
|
||||
Displays Mattermost version information.
|
||||
|
||||
Format
|
||||
``` sh
|
||||
mattermost version
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Executing a command hangs and doesn't complete
|
||||
|
||||
If you have Bleve search indexing enabled, temporarily disable it in **System Console \> Experimental \> Bleve** and run the command again. You can also optionally use the new [mmctl Command Line Tool](/administration-guide/manage/mmctl-command-line-tool).
|
||||
|
||||
Bleve does not support multiple processes opening and manipulating the same index. Therefore, if the Mattermost server is running, an attempt to run the CLI will lock when trying to open the indeces.
|
||||
|
||||
If you aren't using the Bleve search indexing, feel free to post in our [Troubleshooting forum](https://forum.mattermost.com/c/trouble-shoot/16) to get help.
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: "Configure server health check probes"
|
||||
---
|
||||
<PlanAvailability slug="entry-ent" />
|
||||
|
||||
This page describes how to configure health check probes for a Mattermost server.
|
||||
|
||||
Before you begin, you should have a running Mattermost server. If you don't, you can [install Mattermost on various distributions](/deployment-guide/deployment-guide-index).
|
||||
|
||||
<Note>
|
||||
|
||||
[Highly available Mattermost cluster support](/deployment-guide/server/high-availability-cluster-based-deployment) requires Mattermost Enterprise.
|
||||
|
||||
</Note>
|
||||
|
||||
You can perform a health check with the following 2 methods:
|
||||
|
||||
- [ping the APIv4 endpoint](#ping-the-apiv4-endpoint)
|
||||
- [ping the Mattermost server](#ping-the-mattermost-server)
|
||||
|
||||
## Ping the APIv4 endpoint
|
||||
|
||||
You can use the [GET /system/ping APIv4 endpoint](https://api.mattermost.com/#tag/system%2Fpaths%2F~1system~1ping%2Fget) to check for system health.
|
||||
|
||||
A sample request is included below. The endpoint checks if the server is up and healthy based on the configuration setting `GoRoutineHealthThreshold`.
|
||||
|
||||
- If `GoRoutineHealthThreshold` and the number of goroutines on the server exceeds that threshold, the server is considered unhealthy.
|
||||
- If `GoRoutineHealthThreshold` is not set or the number of goroutines is below the threshold the server is considered healthy.
|
||||
|
||||
This endpoint can also be provided to schedulers like [Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/).
|
||||
|
||||
``` go
|
||||
import "github.com/mattermost/mattermost/server/public/model"
|
||||
|
||||
Client := model.NewAPIv4Client("https://your-mattermost-url.com")
|
||||
Client.Login("email@domain.com", "Password1")
|
||||
|
||||
// GetPing
|
||||
status, err := Client.GetPing()
|
||||
```
|
||||
|
||||
## Ping the Mattermost server
|
||||
|
||||
The [Mattermost Probe](https://github.com/csduarte/mattermost-probe) constantly pings a Mattermost server using a variety of probes.
|
||||
|
||||
These probes can be configured to verify core features, including sending and receiving messages, joining channels, pinging a login page, and searching of users and channels.
|
||||
|
||||
The project is contributed by the Mattermost open source community. Suggestions and contributions for the project are welcome.
|
||||
22
docs/main/administration-guide/manage/feature-labels.mdx
Normal file
22
docs/main/administration-guide/manage/feature-labels.mdx
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: "Mattermost feature labels"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Mattermost’s feature labels serve as indicators of the status, maturity, and support level of each feature, helping users and system administrators navigate product feature adoption with clarity and confidence. Feature labels communicate the stage of development, level of readiness, and potential risks associated with a feature for customers seeking to adopt new value.
|
||||
|
||||
## Experimental
|
||||
|
||||
Feature is an early Proof of Concept (POC) with an unstable codebase, minimal QA covering a small or specific set of use cases, and potential UI issues. Security reviews are incomplete, making it unsuitable for production. Distribution of the solution is limited, and our Cloud environments are typically not eligible to use experimental features. Data loss can occur as data schemas and configurations may change, and minimal documentation is available. Caution is advised as the solution may be discarded if its value is not proven.
|
||||
|
||||
## Beta
|
||||
|
||||
Feature is in active development towards General Availability. Not fully complete, but reviewed by our security team, adoption is suitable for a small set of customers behind a feature flag. Identified bugs are fixed on a best effort basis, and no major breaking changes are anticipated, full testing is in progress, and detailed documentation may not be available. Beta is a transitional stage, meaning the solution is maturing but requires careful consideration in a full production deployment as scale and client availability may vary. [Premier Support](https://mattermost.com/support/) is recommended when using beta features in production environments.
|
||||
|
||||
## General Availability
|
||||
|
||||
Feature has undergone thorough validation and testing and has production-level quality. It is feature-complete, meets quality standards, has successfully passed security reviews, and has detailed product documentation available. General Availability features are suitable for widespread production deployment and adoption, and are eligible for commercial support, as they offer stability and reliability, with no expected changes that could disrupt functionality or scalability.
|
||||
|
||||
## Deprecated
|
||||
|
||||
Feature is officially marked for removal from the product. It is no longer supported or actively maintained by the development team. If the feature is still in use in your deployed version, we recommend users discontinue its use and migrate to alternative functionalities.
|
||||
39
docs/main/administration-guide/manage/in-product-notices.mdx
Normal file
39
docs/main/administration-guide/manage/in-product-notices.mdx
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: "In-product notices"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Mattermost in-product notices keep users and administrators informed of the newest product improvements, features, and releases.
|
||||
|
||||
## Administrator notices
|
||||
|
||||
Administrator notices inform system admins when a new server version is available, when external dependencies are being deprecated, or when server upgrades are recommended due to ending support life cycles. System admins may also receive notices about recommended server configuration options to optimize the user experience of their deployment.
|
||||
|
||||

|
||||
|
||||
System admins can disable end user notices by going to **System Console \> Site Configuration \> Notices**.
|
||||
|
||||
## End user notices
|
||||
|
||||
End user notices are used to inform all users when:
|
||||
|
||||
- New desktop app versions and feature enhancements are available for users.
|
||||
- Mattermost is gathering user feedback to improve the product and user experience.
|
||||
|
||||
System admins can disable end user notices by going to **System Console \> Site Configuration \> Notices**.
|
||||
|
||||

|
||||
|
||||
## Frequently asked questions (FAQs)
|
||||
|
||||
### Are notices enabled by default?
|
||||
|
||||
Yes. Notices are enabled by default for all Mattermost users. System admins may choose to disable admin or end user notices in **System Console \> Site Configuration \> Notices**.
|
||||
|
||||
### Will I still receive notices if my server is air-gapped?
|
||||
|
||||
No, the Mattermost server requires a connection to the internet to receive notices.
|
||||
|
||||
### How often will users receive notices?
|
||||
|
||||
Notices will be used to raise awareness of new features as part of our monthly release cadence. Users will only receive notices that specifically apply to them. For example, if a user is already running the latest Desktop App version, they will not receive an upgrade notice.
|
||||
1211
docs/main/administration-guide/manage/logging.mdx
Normal file
1211
docs/main/administration-guide/manage/logging.mdx
Normal file
File diff suppressed because it is too large
Load Diff
150
docs/main/administration-guide/manage/product-limits.mdx
Normal file
150
docs/main/administration-guide/manage/product-limits.mdx
Normal file
@@ -0,0 +1,150 @@
|
||||
---
|
||||
title: "Product limits"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
This page describes some of the product limits that apply to Mattermost, including hard and recommended limits.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Feature</th>
|
||||
<th>Hard Limit</th>
|
||||
<th>Recommended Limit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/create-channels">Group messages</a></td>
|
||||
<td>8 participants</td>
|
||||
<td>If 8 isn't enough, create a private channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/make-calls">Call participants</a></td>
|
||||
<td>Unlimited</td>
|
||||
<td>50</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/administration-guide/configure/custom-branding-tools#custom-brand-text">Custom brand text</a></td>
|
||||
<td>500</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/administration-guide/configure/custom-branding-tools#site-description">Custom site description</a></td>
|
||||
<td>1024</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/administration-guide/manage/logging#advanced-logging">Advanced log output</a></td>
|
||||
<td>500 MB file size, 1000 audit records</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/preferences/set-your-status-availability#set-a-custom-status">Custom status</a></td>
|
||||
<td>100 characters</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/channel-header-purpose#channel-name">Channel name</a></td>
|
||||
<td>64 characters</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/channel-header-purpose#channel-purpose">Channel purpose</a></td>
|
||||
<td>250 characters</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/channel-header-purpose#channel-header">Channel header</a></td>
|
||||
<td>1024 characters</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/manage-channel-bookmarks">Bookmarked links & files</a></td>
|
||||
<td>50</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/message-priority#request-acknowledgements">Message acknowledgement</a> response time</td>
|
||||
<td>5 minutes</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/organize-using-custom-user-groups">Custom user group</a> notifications</td>
|
||||
<td>256 users per group</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/react-with-emojis-gifs#quick-emoji-reactions">Emoji reactions</a> per message</td>
|
||||
<td>50</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/react-with-emojis-gifs#upload-custom-emojis">Custom emoji uploads</a></td>
|
||||
<td>6000</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/team-settings#team-description">Team description</a></td>
|
||||
<td>50 characters</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/administration-guide/configure/environment-configuration-settings#session-length-for-sso">SSO user session duration</a></td>
|
||||
<td>30 days</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/administration-guide/configure/environment-configuration-settings#session-length-for-mobile">Mobile user session duration</a></td>
|
||||
<td>30 days</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/share-files-in-messages">Attachments per message</a> (files or images)</td>
|
||||
<td>10</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/share-files-in-messages#attachment-limits-and-sizes">Attachment file size</a></td>
|
||||
<td>100 MB</td>
|
||||
<td>Configurable</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/share-files-in-messages#attachment-limits-and-sizes">Attachment image file size</a></td>
|
||||
<td>253 MB</td>
|
||||
<td>Configurable</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/share-files-in-messages#attachment-limits-and-sizes">Attachment dimensions</a></td>
|
||||
<td>7680 pixels x 4320 pixels</td>
|
||||
<td>Configurable</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/share-files-in-messages#attachment-limits-and-sizes">Attachment image resolution size</a></td>
|
||||
<td>33 MP (mega pixels) or 8K resolution</td>
|
||||
<td>Configurable</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/preferences/manage-your-profile">User nickname</a></td>
|
||||
<td>64 characters</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/send-messages">Message length</a></td>
|
||||
<td>16,383 characters</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/organize-using-teams#create-a-team">Teams per deployment</a></td>
|
||||
<td>10,000</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/end-user-guide/collaborate/invite-people">Users per team</a></td>
|
||||
<td>No enforced limit</td>
|
||||
<td>Dependent on infrastructure</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
[Book a live demo](https://mattermost.com/request-demo/) or [talk to a Mattermost expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization's secure collaboration needs. Or try Mattermost yourself with a [1-hour preview](https://mattermost.com/sign-up/) for instant access to a live sandbox environment.
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: "Request a server health check"
|
||||
---
|
||||
<PlanAvailability slug="entry-ent" />
|
||||
|
||||
The Mattermost Health Check is a comprehensive evaluation of your system's current operational health available to Mattermost Enterprise customers.
|
||||
|
||||
This evaluation provides you with insights based on your system’s configuration, user activity, and log events that helps you proactively identify issues, enhance collaboration security, optimize resource utilization and scalability which leads to minimized downtime, improved performance, and significant cost savings for your Enterprise organization.
|
||||
|
||||
<Tip>
|
||||
|
||||
Want to configure your own server health check probes for your self-hosted Mattermost deployment? See the [configure server health check probes](/administration-guide/manage/configure-health-check-probes) documentation for details.
|
||||
|
||||
</Tip>
|
||||
|
||||
## Why request a Mattermost Health Check?
|
||||
|
||||
Regularly assessing the health of your Mattermost environment ensures that:
|
||||
|
||||
- System performance remains optimal, with minimal delays or downtime.
|
||||
- User experience is consistently reliable, preventing missed messages or slow load times.
|
||||
- Security and compliance settings are up-to-date and effective.
|
||||
- Scalability aligns with your evolving usage patterns, supporting growth without issues.
|
||||
|
||||
## Get started
|
||||
|
||||
Getting started with a Mattermost Health Check is simple and involves 3 steps:
|
||||
|
||||
1. [Generate a Support Packet](/administration-guide/manage/admin/generating-support-packet): The Mattermost Support Packet contains critical information about your Mattermost environment, including logs, configurations, and usage data.
|
||||
2. Submit Your Support Packet: Once you’ve generated the Support Packet, submit it through our Support System as a [standard support request](https://support.mattermost.com/hc/en-us/requests/new). Please include “Health Check Provided” in the subject line.
|
||||
3. Receive Your Health Check Report: Within 2 weeks of submitting your Support Packet, you will receive a comprehensive performance report. This report will include:
|
||||
|
||||
- Detailed analysis of your current system health.
|
||||
- Actionable recommendations to enhance performance, reliability, and security.
|
||||
- Guidance on best practices for future system maintenance.
|
||||
|
||||
## Get help
|
||||
|
||||
If you have any questions or need assistance, contact your Customer Success Manager or Technical Account Manager, the [Mattermost Support Team](https://mattermost.com/support/), or visit the [Mattermost Help Center](https://support.mattermost.com/).
|
||||
150
docs/main/administration-guide/manage/statistics.mdx
Normal file
150
docs/main/administration-guide/manage/statistics.mdx
Normal file
@@ -0,0 +1,150 @@
|
||||
---
|
||||
title: "Statistics"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Statistics on users, posts, and channels are tracked for each system and team. Enterprise Editions have access to advanced system statistics.
|
||||
|
||||
<Note>
|
||||
|
||||
To maximize performance for large enterprise deployments, statistics for total messages, total hashtag messages, total file messages, messages per day, and activated users with messages per day is configurable by changing the `MaxUsersForStatistics` value [in config.json](/administration-guide/configure/reporting-configuration-settings#maximum-users-for-statistics).
|
||||
|
||||
</Note>
|
||||
|
||||
For advanced metrics for Entry, Enterprise, and Enterprise deployments, [see performance monitoring documentation to learn more](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring).
|
||||
|
||||
## System statistics
|
||||
|
||||
System statistics are viewable under **System Console \> Reporting**. The data shown here is a cumulative sum across all teams on the system.
|
||||
|
||||
Total Users
|
||||
The total number of active accounts created on your system. Excludes deactivated accounts and single-channel guests.
|
||||
|
||||
Single-channel Guests
|
||||
The number of active guest accounts that belong to exactly one active channel on the server. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. Archived channels are excluded. Single-channel guests are counted separately from the primary paid seat count and are free up to a 1:1 ratio with licensed seats. When this count exceeds the allowance, the statistic is highlighted as a warning for system admins.
|
||||
|
||||
Total Teams
|
||||
The total number of teams created on your system.
|
||||
|
||||
Total Channels
|
||||
The total number of public channels and private channels created in all the teams on your system, including deleted channels. Doesn't include direct message channels.
|
||||
|
||||
Total Posts
|
||||
The total number of posts made in all the teams on your system, including deleted posts and posts made using automation.
|
||||
|
||||
Daily Active Users
|
||||
The total number of users who viewed the Mattermost site in the last 24 hours. Excludes bot users.
|
||||
|
||||
Monthly Active Users
|
||||
The total number of users who viewed the Mattermost site in the last 30 days. Excludes bot users.
|
||||
|
||||
Total Posts (graph)
|
||||
The total number of posts made on a certain day in all the teams on your system, including deleted posts and posts made using automation.
|
||||
|
||||
Total Posts from Bots (graph)
|
||||
The total number of posts made by a [bot account](https://developers.mattermost.com/integrate/admin-guide/admin-bot-accounts/) on a certain day in all the teams on your system, including deleted posts and posts made using automation.
|
||||
|
||||
Active Users with Posts (graph)
|
||||
Users who made a post on a certain day in all the teams on your system, including system messages posted from the user's account.
|
||||
|
||||
### Advanced system statistics
|
||||
|
||||
<PlanAvailability slug="entry-ent" />
|
||||
|
||||
Self-hosted deployments include additional system statistics.
|
||||
|
||||
Total Sessions
|
||||
The number of active user sessions connected to your system. Expired sessions are not counted.
|
||||
|
||||
Total Commands
|
||||
The number of active slash commands currently set up on your system. Slash commands that are created and then removed in the **Integrations** menu are not counted.
|
||||
|
||||
Incoming Webhooks
|
||||
The number of active incoming webhooks currently setup on your system. Incoming webhooks that are created and then removed in the **Integrations** menu are not counted.
|
||||
|
||||
Outgoing Webhooks
|
||||
The number of active outgoing webhooks currently set up on your system. Outgoing webhooks that are created and then removed in the **Integrations** menu are not counted.
|
||||
|
||||
WebSocket Conns
|
||||
The number of active WebSocket connections currently on your server.
|
||||
|
||||
Master DB Conns
|
||||
The number of active connections currently on your master database.
|
||||
|
||||
Replica DB Conns
|
||||
The number of active connections currently on one or more of [your read replica databases](/deployment-guide/server/high-availability-cluster-based-deployment#database).
|
||||
|
||||
Total Playbooks
|
||||
The total number of collaborative playbooks on this server.
|
||||
|
||||
Total Playbook Runs
|
||||
The total number of runs (active and complete) on this server.
|
||||
|
||||
Channel Types
|
||||
This chart displays the number of public channels and private channels in a visual format, including channels that might have been deleted.
|
||||
|
||||
Posts, Files and Hashtags
|
||||
This chart displays the number of posts containing files, hashtags, or only text. Posts containing both files and hashtags are counted in both categories, and deleted posts are included.
|
||||
|
||||
## Team statistics
|
||||
|
||||
Team Statistics are viewable under **System Console \> Team Statistics**. The data shown here is a cumulative sum across this team only, and excludes posts made in Direct Message channels, which are not tied to a team.
|
||||
|
||||
Total Users
|
||||
The total number of active accounts on this team. Excludes deactivated accounts.
|
||||
|
||||
Public Channels
|
||||
The number of public channels created in this team. Excludes deleted channels.
|
||||
|
||||
Private Channels
|
||||
The number of private channels created in this team. Excludes deleted channels.
|
||||
|
||||
Total Posts
|
||||
The total number of posts made in this team, including deleted posts and posts made using automation. Excludes posts made in Direct Message channels, which are not tied to a team.
|
||||
|
||||
Total Posts (graph)
|
||||
The total number of posts made on a certain day in this team, including deleted posts and posts made using automation.
|
||||
|
||||
Active Users with Posts (graph)
|
||||
Users who made a post on a certain day in this team, including system messages posted from the user's account.
|
||||
|
||||
Recent Active Users
|
||||
Twenty most recent users who have logged in and had recent browser activity in Mattermost.
|
||||
|
||||
Newly Created Users
|
||||
Most recent users who have joined the team.
|
||||
|
||||
## Troubleshooting/FAQ
|
||||
|
||||
### I see an error: "Not enough data for a meaningful representation"
|
||||
|
||||
If the statistics page is loading endlessly and you get an error message saying "Not enough data for a meaningful representation", check whether you're using an ad blocker. An ad blocker can prevent this page from loading data. To test this, temporarily disable your ad blocker, or view the page in a browser without an ad blocker installed.
|
||||
|
||||
### Can team admins review their own team's statistics?
|
||||
|
||||
<PlanAvailability slug="entry-ent" />
|
||||
|
||||
Yes. With self-hosted deployments, you can enable team admins to see their team's statistics by modifying available delegated granular administration system roles. See the [delegated granular administration](/administration-guide/onboard/delegated-granular-administration) documentation to learn more about these admin roles, including how to manage privileges and assign roles.
|
||||
|
||||
To enable team admins to access their team's statistics:
|
||||
|
||||
1. Go to **System Console \> User Management \> System Roles**, then edit the **Viewer** system admin role.
|
||||
|
||||

|
||||
|
||||
2. Under **Privileges**, expand the **Reporting** section, set **Team Statistics** to **Read only**, then set **System Statistics** and **Server Logs** to **No access**.
|
||||
3. Set all other privileges to **No access** to restrict all users with the **Viewer** role to access only the **Team Statistics** page in the System Console.
|
||||
|
||||

|
||||
|
||||
4. Under **Assigned People**, select **Add People** to assign team admins to the **Viewer** role, and enable them to access their team's statistics.
|
||||
|
||||

|
||||
|
||||
5. Select **Save**.
|
||||
|
||||
<Note>
|
||||
|
||||
System admins must manually add people to or remove people from the **Viewer** system admin role to address team admin changes, such as promotions or demotions.
|
||||
|
||||
</Note>
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: "System-wide notifications"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
System admins can configure system-wide notifications visibile in all channels for all users across all teams.
|
||||
|
||||

|
||||
|
||||
1. Enable system-wide notifications by going to **System Console \> Site Configuration \> System-wide notifications**, and setting **Enable system-wide notifications** to **true**.
|
||||
2. In the **Banner Text** field, enter the notification text you want to share in channels.
|
||||
3. Specify the background and text colors for the banner.
|
||||
4. By default, users can dismiss the banner until they log in again or until you update the banner. To prevent users from dismissing the banner, set **Allow Banner Dismissal** to **false**.
|
||||
5. Select **Save**.
|
||||
|
||||
Update the banner by either changing the text of the banner or by re-enabling the banner after it's been disabled.
|
||||
|
||||
To disable the banner, set **Enable Announcement Banner** to **false**.
|
||||
145
docs/main/administration-guide/manage/team-channel-members.mdx
Normal file
145
docs/main/administration-guide/manage/team-channel-members.mdx
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
title: "Manage team and channel members"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
System admins can manage channel configuration in the System Console, including:
|
||||
|
||||
- **Management:** Manage synchronization, moderation, and membership settings.
|
||||
- **Promoting/demoting Team and Channel Admins:** Team admins and channel admins can be demoted via the System Console.
|
||||
- **View channel members:** System admins can view members of a channel without having to join the channel.
|
||||
- **Member count:** Total member count in a team or channel.
|
||||
- **Archive channels:** System admins can archive channels without having to join the channel.
|
||||
|
||||
## Teams
|
||||
|
||||
To view and manage team information, navigate to **System Console \> Teams**. Teams can be managed by **Group Sync** or **Invite Only**. The type of management in use may affect the management options available for that team.
|
||||
|
||||
Select a team to view its configuration options.
|
||||
|
||||
### Team profile
|
||||
|
||||
The name and description of the team.
|
||||
|
||||
System admins can archive or unarchive the team from within **User Management \> Teams \> Team Management**. Archiving a team makes its contents inaccessible for all users. All related information is archived, including posts from the database. Before archiving a team, we recommend that you perform a database backup.
|
||||
|
||||
### Archive a team
|
||||
|
||||
Select **Archive Team**, then select **Save**. Select **Archive** when prompted to confirm the team archive.
|
||||
|
||||
Alternatively, system admins can use the mmctl `mmctl team archive` to archive teams. See the [mmctl product documentation](/administration-guide/manage/mmctl-command-line-tool#mmctl-team-archive) for details.
|
||||
|
||||
### Unarchive a team
|
||||
|
||||
Select **Unarchive Team**, then select **Save**.
|
||||
|
||||
Alternatively, system admins can use the mmctl `mmctl team restore` to archive teams. See the [mmctl product documentation](/administration-guide/manage/mmctl-command-line-tool#mmctl-team-restore) for details.
|
||||
|
||||
### Team management
|
||||
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
- When **Sync Group Members** is enabled, the **Synced Groups** list is visible and additional groups can be added.
|
||||
- When **Sync Group Members** is not enabled, invitation limitations can be selected.
|
||||
|
||||
### Groups
|
||||
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
You can add and remove groups, as well as promote or demote group members to team admin/member roles.
|
||||
|
||||
### Members
|
||||
|
||||
A list of all members in a channel is visible to system admins. Members can be added and removed from the team members and be promoted or demoted to a team admin/member role. Use the role **Filter** to refine your search results. You can use one filter, or combine filters to search by multiple roles:
|
||||
|
||||
- Guest
|
||||
- Member
|
||||
- Team admin
|
||||
- System admin
|
||||
|
||||
## Channels
|
||||
|
||||
To view and manage channel information, navigate to **System Console \> Channels**. Channels can be managed by **Group Sync** or **Manual Invites**. The type of management in use may affect the management options available for that channel. Use the **Filter** to refine your search results. You can use one filter, or combine filters to search by channel and management type:
|
||||
|
||||
- Public channels
|
||||
- Private channels
|
||||
- Archived channels
|
||||
- Channels that are synchronized to an AD/LDAP Group
|
||||
- Channels with users who were invited manually (not synced from LDAP)
|
||||
|
||||
Select a channel to view its configuration options.
|
||||
|
||||
### Profile
|
||||
|
||||
The name and description of the channel. To archive the channel, select **Archive Channel \> Save**. The channel is still searchable in the **Channels** list. To unarchive the channel, select **Unarchive Channel** and **Save**.
|
||||
|
||||
### Channel management
|
||||
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
- When **Sync Group Members** is enabled, the **Synced Groups** list is visible and additional groups can be added.
|
||||
- When **Sync Group Members** is not enabled, you can select whether the channel is **Private** or **Public**.
|
||||
|
||||
### Advanced access controls
|
||||
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
Advanced access control settings enable system admins to restrict actions within specific channels. These actions include:
|
||||
|
||||
- **Make channel read-only:** [Read-only channels](/administration-guide/onboard/advanced-permissions#read-only-channels) enable system admins to turn off posting in specified channels.
|
||||
- **Restrict reactions:** Turn off the ability for members and guests to post reactions.
|
||||
- **Restrict channel mentions:** Turn off the ability for users to post channel wide mentions (@all/@channel/@here) in specified channels.
|
||||
- **Channel member management:** Only admins have the ability to add and remove channel members in the specified channels.
|
||||
- **Bookmarks management:** Only channel and system admins can [manage channel bookmarks](/end-user-guide/collaborate/manage-channel-bookmarks).
|
||||
|
||||
These settings are modified in **System Console \> User Management \> Channels**.
|
||||
|
||||
<Note>
|
||||
|
||||
These settings are applicable only to Guests and Members. System, team, and channel admins aren't affected. If you wish to grant posting ability to a specific member, you must first promote that member to channel admin.
|
||||
|
||||
</Note>
|
||||
|
||||
The availability of advanced access control settings can also be affected by existing system and team permissions configurations. If there are existing configurations that override the channel settings you would like to apply, it will be indicated in the user interface. These settings can then be adjusted in the relevant panel in the **Permissions** section of the System Console.
|
||||
|
||||
**Configure a channel so that members can post/reply/react but guests can only read and react.**
|
||||
|
||||
1. Navigate to **System Console \> User Management \> Channels**.
|
||||
2. Select **Edit** next to the name of the channel you want to configure.
|
||||
3. In the **Create Posts** panel, uncheck **Guests**.
|
||||
4. In the **Post Reactions** panel, uncheck **Guests** if required.
|
||||
5. Select **Save**.
|
||||
|
||||
The channel is available for all members and guests to access, but guests can only read messages and react to them.
|
||||
|
||||
**Create an Announcement Channel where only Channel Admins are able to post (read-only).**
|
||||
|
||||
1. Create a new channel (either Public or Private).
|
||||
2. Navigate to **System Console \> User Management \> Channels**.
|
||||
3. Select **Edit** next to the name of the channel you just created (you may need to search for it).
|
||||
4. In the **Create Posts** panel, uncheck **Guests** and **Members**.
|
||||
5. In the **Post Reactions** panel, uncheck **Guests** and **Members**.
|
||||
6. Select **Save**.
|
||||
|
||||
The channel is available for all members and guests to access but only Admins can post to the channel.
|
||||
|
||||
### Groups
|
||||
|
||||
<PlanAvailability slug="entry-adv" />
|
||||
|
||||
You can add and remove groups, as well as promote or demote group members to team admin/member roles.
|
||||
|
||||
### Members
|
||||
|
||||
A list of all members in a channel is visible to system admins. Members can be added and removed from the team members and be promoted or demoted to a team admin/member role. Use the role **Filter** to refine your search results. You can use one filter, or combine filters to search by multiple roles:
|
||||
|
||||
- Guest
|
||||
- Member
|
||||
- Channel admin
|
||||
- System admin
|
||||
|
||||
<Note>
|
||||
|
||||
From Mattermost v11.5.2, system admins can set the complete membership of a channel in a single API call. The server computes the diff against the current membership and adds or removes users as needed. See the [API documentation](https://api.mattermost.com/#tag/channels/operation/SetChannelMembers) for details.
|
||||
|
||||
</Note>
|
||||
103
docs/main/administration-guide/manage/telemetry.mdx
Normal file
103
docs/main/administration-guide/manage/telemetry.mdx
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: "Telemetry"
|
||||
---
|
||||
As described in the privacy policy in each Mattermost server, telemetry data optionally shared from your Mattermost servers is used to identify security and reliability issues, to analyze and fix software problems, to help improve the quality of Mattermost software and related services, and to make design decisions for future releases.
|
||||
|
||||
Telemetry data is encrypted in transit, does not include personally identifiable information or message contents, and details of how the information is used and processed is available in our [Privacy Policy](https://mattermost.com/privacy-policy/).
|
||||
|
||||
We use the data for the following purposes to:
|
||||
|
||||
- Identify security and reliability issues.
|
||||
- Analyze and fix software problems.
|
||||
- Help improve the quality of Mattermost software and related services.
|
||||
- Make design decisions for future releases.
|
||||
|
||||
<Note>
|
||||
|
||||
Telemetry data collection is enabled by default for all Mattermost deployments. Self-hosted system admins can opt out of sharing telemetry data from Mattermost self-hosted servers within the System Console. Cloud system admins can't disable telemetry for Mattermost Cloud deployments.
|
||||
|
||||
</Note>
|
||||
|
||||
## Security update check feature
|
||||
|
||||
New threats to system security constantly arise. To alert you of relevant, high priority security updates, Mattermost servers are configured to share diagnostic information with Mattermost Inc. so that we can provide appropriate alerts.
|
||||
|
||||
The following data is collected once every 24 hours:
|
||||
|
||||
- Mattermost server build number and version
|
||||
- Type of build (Enterprise Edition or Team Edition)
|
||||
- Server operating system
|
||||
- The server diagnostic ID (same as the ID accessing the push notification proxy, and is used to prevent double-counting of telemetry data)
|
||||
- Database type
|
||||
- Database version
|
||||
- Number of teams
|
||||
- Number of users
|
||||
- Number of activated users
|
||||
- Whether or not the unit tests have been run
|
||||
- Date and time of the last check for security updates
|
||||
|
||||
### Opt out
|
||||
|
||||
To opt out, you can disable this security update check feature for self-hosted deployments in the System Console by going to **Environment \> SMTP \> Enable Security Alerts**. See the [enable security alerts](/administration-guide/configure/environment-configuration-settings#enable-security-alerts) documentation for details. When this feature is disabled, you will not receive any security alerts.
|
||||
|
||||
## Error and diagnostics reporting feature
|
||||
|
||||
When enabled, server errors and panics are automatically sent to the Mattermost-hosted [Sentry](https://sentry.io/welcome/) endpoint for diagnosis. No message content or personally identifiable information is included.
|
||||
|
||||
Mattermost error and diagnostic data is collected for the following purposes:
|
||||
|
||||
- To add improvements that are specific to your usage, upgrade, and deployment patterns, including identifying security and reliability issues.
|
||||
- To analyze and fix software problems.
|
||||
- To help improve the quality of Mattermost software and related services.
|
||||
- To make design decisions for future releases.
|
||||
|
||||
### Opt out
|
||||
|
||||
To opt out, you can disable the error and diagnostics reporting feature for self-hosted deployments in the System Console by going to **Environment \> Logging \> Enable Diagnostics and Error Reporting**. See the [enable diagnostics and error reporting](/administration-guide/configure/environment-configuration-settings#enable-diagnostics-and-error-reporting) documentation for details.
|
||||
|
||||
## Android Mobile App performance monitoring
|
||||
|
||||
To improve Android app performance, we are collecting trace events and device information, collectively known as metrics, to identify slow performing key areas. Those metrics will be sent only from users using the Android app Beta build starting in version v1.20, who are logged in to servers that allow sending [diagnostic information](/administration-guide/configure/environment-configuration-settings#enable-diagnostics-and-error-reporting).
|
||||
|
||||
Trace events
|
||||
Includes duration on how long the action took place like startup, team/channel switch, posts loading/update and channel drawer open/close. The naming convention is interpreted as `[start observation]:[end observation]`, e.g. `start:overall` as from app start until fully rendered or `post_list:thread` as on press of post at post list until thread is opened. Complete list of trace events are the following:
|
||||
|
||||
- start:overall
|
||||
- start:process_packages
|
||||
- start:content_appeared
|
||||
- start:select_server_screen
|
||||
- start:channel_screen
|
||||
- team:switch
|
||||
- channel:loading
|
||||
- channel:switch_loaded
|
||||
- channel:switch_initial
|
||||
- channel:close_drawer
|
||||
- channel:open_drawer
|
||||
- posts:loading
|
||||
- post_list:thread
|
||||
- post_list:permalink
|
||||
|
||||
Device information
|
||||
The information being collected is non-personally identifiable. Except for system_version, device information is based from [react-native-device-info](https://github.com/mattermost/react-native-device-info#react-native-device-info) library. Refer to the linked documentation to learn more. Complete list of device information are the following:
|
||||
|
||||
- api_level
|
||||
- build_number
|
||||
- bundle_id
|
||||
- brand
|
||||
- country
|
||||
- device_id
|
||||
- device_locale
|
||||
- device_type
|
||||
- device_unique_id
|
||||
- height
|
||||
- is_emulator
|
||||
- is_tablet
|
||||
- manufacturer
|
||||
- max_memory
|
||||
- model
|
||||
- server_version
|
||||
- system_name
|
||||
- system_version
|
||||
- timezone
|
||||
- version
|
||||
- width
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: "User satisfaction surveys"
|
||||
---
|
||||
<PlanAvailability slug="all-commercial" />
|
||||
|
||||
Feedback is used to measure user satisfaction and improve product quality by hearing directly from users. Please refer to our [privacy policy](https://mattermost.com/privacy-policy/) for information on the collection and use of information received through our services.
|
||||
|
||||
<Important>
|
||||
|
||||
**Mattermost User Satisfaction Surveys are deprecated from Mattermost v10.11** and are no longer included as a pre-packaged plugin for new Mattermost deployments. Existing deployments that have this plugin enabled will continue to work, but we strongly recommend migrating to [user surveys](/administration-guide/configure/manage-user-surveys) for enhanced customization options, and local data storage, without telemetry data transmission back to Mattermost.
|
||||
|
||||
</Important>
|
||||
|
||||
## Administration
|
||||
|
||||
### Is the survey enabled by default?
|
||||
|
||||
**For Mattermost Server versions prior to v10.11**: The user satisfaction survey is a pre-packaged plugin, and surveys are enabled by default on all servers. However, the plugin will not be activated on any servers that have [Error and Diagnostic Reporting](/administration-guide/manage/telemetry) disabled, meaning no surveys or data collection occurs.
|
||||
|
||||
**For Mattermost Server v10.11 and later**: The User Satisfaction Survey Plugin is no longer included as a pre-packaged plugin for new deployments. We recommend using the [Mattermost User Survey integration](/administration-guide/configure/manage-user-surveys) instead.
|
||||
|
||||
### How can surveys be disabled?
|
||||
|
||||
Disabling the **User Satisfaction Surveys** plugin from **System Console \> Plugins \> Plugin Management** will disable surveys and all data collection by the plugin.
|
||||
|
||||
<Note>
|
||||
|
||||
- If surveys have been disabled from the plugin configuration in **System Console \> Plugins \> User Satisfaction Surveys**, but the plugin itself is still enabled, surveys won't be scheduled but users can still send written feedback by messaging Surveybot.
|
||||
- When the plugin or surveys in the plugin configuration are disabled, they remain disabled for subsequent server upgrades.
|
||||
|
||||
</Note>
|
||||
|
||||
### When is the survey scheduled?
|
||||
|
||||
Users will receive surveys 21 days after every server upgrade, assuming the following conditions are true:
|
||||
|
||||
- User Satisfaction Surveys plugin is enabled in **System Console \> Plugins \> Plugin Management**.
|
||||
- Surveys are enabled in the plugin configuration in **System Console \> Plugins \> User Satisfaction Surveys**.
|
||||
- User account is greater than 21 days old.
|
||||
- User has not completed a survey in the last 90 days.
|
||||
- User has not been sent a survey in the last 90 days.
|
||||
- Current server version is greater than the server version of the last survey, excluding dot releases.
|
||||
|
||||
The above conditions mean that at maximum frequency a user will receive a survey every 90 days, assuming the server is upgraded within that time period.
|
||||
|
||||
### How will I be notified when a survey is scheduled?
|
||||
|
||||
System admins will receive an email notification and in-product direct message from "Surveybot" mentioning the scheduled date the survey will be triggered.
|
||||
|
||||

|
||||
|
||||
## Survey Data
|
||||
|
||||
### How is the survey received?
|
||||
|
||||
Once the survey is triggered on the server, all users will receive an in-product direct messages from "Surveybot" on their next login or page refresh in Mattermost.
|
||||
|
||||
Users can optionally select a 0-10 score on how likely they are to recommend Mattermost and then provide written feedback about their experience. Selecting a score and providing feedback are optional, and the survey can be ignored without interrupting usage of Mattermost.
|
||||
|
||||

|
||||
|
||||
### What data is collected?
|
||||
|
||||
Data is only collected when a user selects a score or provides written feedback in response to survey questions. Please refer to our [privacy policy](https://mattermost.com/privacy-policy/) for more information on the collection and use of information received through our services. The following **non-personally identifiable information** is collected:
|
||||
|
||||
- Survey information:
|
||||
- Score (0-10) submitted by the user
|
||||
- Written feedback submitted by the user (if applicable)
|
||||
- Timestamp of the survey submission
|
||||
|
||||
- Server information:
|
||||
- Server/Web App version the survey was submitted on
|
||||
- Installation date of the server
|
||||
- Diagnostic ID used for error and diagnostics reporting
|
||||
- License ID used for error and diagnostics reporting (if applicable)
|
||||
- Enterprise or Professional (if applicable)
|
||||
|
||||
- User information:
|
||||
- User role (system admin, team admin, or member)
|
||||
- Account creation timestamp
|
||||
- User ID of the surveyed user
|
||||
|
||||
### Will this data be sent through my firewall?
|
||||
|
||||
If Mattermost is self-hosted in a private network with firewall then data from the User Satisfaction Surveys plugin is not sent unless outbound connections are allowed or specifically configured for this plugin.
|
||||
Reference in New Issue
Block a user