Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2587,7 +2587,7 @@ See the [Telemetry](/administration-guide/manage/telemetry#security-update-check

With self-hosted deployments, you can configure Mattermost as a [high availability cluster-based deployment](/deployment-guide/reference-architecture/scale/high-availability-cluster-based-deployment) by going to **System Console \> Environment \> High Availability**, or by editing the `config.json` file as described in the following tables. Changes to configuration settings in this section require a server restart before taking effect.

In a Mattermost high availability cluster-based deployment, the System Console is set to read-only, and settings can only be changed by editing the `config.json` file directly. However, to test a high availability cluster-based environment, you can disable `ClusterSettings.ReadOnlyConfig` in the `config.json` file by setting it to `false`. This allows changes applied using the System Console to be saved back to the configuration file.
When a Mattermost high availability cluster-based deployment uses `config.json` for configuration, the System Console is set to read-only by default, and settings can only be changed by editing the `config.json` file directly. However, to test a high availability cluster-based environment, you can disable `ClusterSettings.ReadOnlyConfig` in the `config.json` file by setting it to `false`. This allows changes applied using the System Console to be saved back to the configuration file. When configuration is stored in the database, `ClusterSettings.ReadOnlyConfig` is ignored and the System Console remains fully editable. See [Store configuration in your database](/administration-guide/configure/configuration-in-your-database) for details.

### Enable high availability mode

Expand Down
1 change: 1 addition & 0 deletions docs/main/administration-guide/manage/admin/migration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This Mattermost Migration Guide is organized into sections based on migration sc
Whether you’re migrating from another platform, upgrading your database, or using bulk tools for data management, this guide provides the resources and instructions you need for a successful migration. Use the navigation below to explore detailed guidance tailored to your migration needs.

- [Migrate from MySQL to PostgreSQL](/deployment-guide/postgres-migration) - Learn how to migrate from MySQL to PostgreSQL.
- [Migrate to FIPS-compliant images](/deployment-guide/server/fips-migration) - Learn how to switch an existing Docker or Kubernetes deployment to the FIPS-compliant Mattermost images.
- [Server migration guide](/administration-guide/onboard/migrating-to-mattermost) - Learn about about migrating to Mattermost.
- [Migrate from Slack](/administration-guide/onboard/migrate-from-slack) - Learn how to migrate from Slack to Mattermost.
- [Migrate from Rocket.Chat](/administration-guide/onboard/migrate-from-rocketchat) - Learn how to migrate from Rocket.Chat to Mattermost.
Expand Down
40 changes: 35 additions & 5 deletions docs/main/administration-guide/onboard/sso-saml-keycloak.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ This was tested with Keycloak v26.4.0. We recommend adding Mattermost as a clien

> - **Sign Documents**: **Off**
> - **Sign Assertions**: **On**
> - **Signature Algorithm**: `RSA_SHA1`
> - **Signature Algorithm**: `RSA_SHA256`
> - **SAML signature key name**: `NONE`
> - **Canonicalization Method**: `EXCLUSIVE`
> - **Encryption Algorithm**: `AES_256_GCM`
Expand All @@ -54,15 +54,15 @@ This was tested with Keycloak v26.4.0. We recommend adding Mattermost as a clien
>
> ![In Keycloak, configure the Signature and Encryption settings for the Mattermost client.](/images/keycloak_1_client_signature_encryption.png)
>
> <div class="warning">
> <div class="note">
>
> <div class="title">
>
> Warning
> Note
>
> </div>
>
> Mattermost only supports `RSA_SHA1` for Keycloak SAML, because Keycloak is using `xmlenc` for `RSA_SHA512` and `RSA_SHA256`, wheras Mattermost currently only supports `xmldsig`. So make sure to use `RSA_SHA1` as the *Signature Algorithm* and *Digest Method* as described in this section.
> Earlier versions of this documentation recommended `RSA_SHA1`. Use `RSA_SHA256` instead. [NIST SP 800-131A](https://csrc.nist.gov/pubs/sp/800/131/a/r2/final) set December 31, 2013 as the deadline after which SHA-1 is disallowed for digital signature generation. Revision 2 of that publication, published in March 2019, allows SHA-1 signature generation only where NIST protocol-specific guidance specifically permits it. A Keycloak server running in FIPS mode returns a `500` error when it tries to sign the assertion with `RSA_SHA1`. Mattermost validates `RSA_SHA256`-signed assertions, and Keycloak derives the signature digest method from the signature algorithm you select here.
>
> </div>

Expand All @@ -86,7 +86,37 @@ This was tested with Keycloak v26.4.0. We recommend adding Mattermost as a clien
>
> </div>
>
> Mattermost does not support request signing with Keycloak so make sure to disable the Client signature setting as mentioned above.
> Leave **Client signature required** off, as shown above. Mattermost does sign its authentication requests when you enable **Sign Request** in step 4 of the Mattermost section below, but Keycloak validates those signatures only if you also import the Mattermost service provider certificate as a signing key on this tab. Turning **Client signature required** on without importing that certificate causes Keycloak to reject Mattermost's authentication requests.
>
> </div>
>
> <div class="note">
>
> <div class="title">
>
> Note
>
> </div>
>
> **If your Keycloak server runs in FIPS mode**, the **Archive Format** list offers only `BCFKS`, because `PKCS12` and `JKS` are unavailable. Export the `BCFKS` keystore, then convert it to `PKCS12` before you continue:
>
> ```console
> keytool -importkeystore -srckeystore keystore.bcfks -srcstoretype BCFKS -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider -providerpath /path/to/bc-fips-<version>.jar -destkeystore keystore.p12 -deststoretype PKCS12
> ```
>
> Point `-providerpath` at your Bouncy Castle FIPS JAR. `keytool` prompts for the source and destination store passwords. The converted `keystore.p12` then works with the extraction commands in step 4 of Configure SAML in Mattermost below.
>
> Convert the whole keystore as shown above rather than looking for a way to export the key on its own, because `keytool` has no command that exports a private key by itself.
>
> As an alternative, generating the keypair locally and importing only the certificate into Keycloak avoids the keystore conversion entirely, and works on FIPS and non-FIPS servers alike:
>
> ```console
> openssl req -x509 -newkey rsa:2048 -nodes -days 1095 -subj "/CN=mattermost" -keyout mattermost.key -out mattermost.crt
> ```
>
> Keep `-nodes`, because Mattermost can't read a passphrase-protected private key. Set `-days` explicitly, because it defaults to 30. Keep `-keyout` and `-out`, because without them the certificate goes to standard output and the private key goes to a configuration-dependent default filename.
>
> Import only `mattermost.crt` into the encryption keys section of this tab, then upload both files in step 4 below and skip the `openssl pkcs12` extraction commands, since you already have the files those commands would have produced.
>
> </div>
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ We recommend reviewing the [additional upgrade notes](#additional-upgrade-notes)
</thead>
<tbody>
<tr>
<td rowspan="2">v11.10</td>
<td rowspan="3">v11.10</td>
<td><p>Starting with v11.10.1, the updated <code>glibc-openssl-fips</code> bundle includes a new OpenSSL build that enforces the FIPS minimum key length of 112 bits for HMAC operations. The PostgreSQL driver (lib/pq) passes the database password as the HMAC key during SCRAM authentication, so a password shorter than 112 bits, or 14 ASCII characters, now causes a panic on connect rather than a graceful failure. Before upgrading, FIPS deployments should verify that the password in <code>SqlSettings.DataSource</code> is at least 14 characters and rotate it in PostgreSQL if it is shorter. Standard, non-FIPS builds are unaffected.</p></td>
</tr>
<tr>
<td><p>This migration adds a new composite index, <code>idx_propertyvalues_groupid_updateat_id</code>, on the <code>PropertyValues</code> table covering the columns <code>GroupID</code>, <code>UpdateAt</code>, and <code>ID</code>. The <code>PropertyValues</code> table is part of the Properties/Custom Attributes feature introduced in recent Mattermost versions. This index improves query performance for lookups and range scans that filter or sort by <code>GroupID</code> and <code>UpdateAt</code>, which are common access patterns for this feature. The index is created using <code>CONCURRENTLY</code>, so the build process does not block concurrent reads or writes against the <code>PropertyValues</code> table. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included are:</p><pre><code>{"-- morph:nontransactional\nCREATE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyvalues_groupid_updateat_id\n ON PropertyValues(GroupID, UpdateAt, ID);"}</code></pre><pre><code>{"-- morph:nontransactional\nDROP INDEX CONCURRENTLY IF EXISTS idx_propertyvalues_groupid_updateat_id;"}</code></pre></td>
</tr>
<tr>
Expand Down Expand Up @@ -393,7 +396,10 @@ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channeljoinrequests_user_status_crea
ALTER TYPE permission_level ADD VALUE IF NOT EXISTS 'admin';</code></pre></td>
</tr>
<tr>
<td rowspan="6">v11.7</td>
<td rowspan="7">v11.7</td>
<td>Starting with v11.7.10, the updated <code>glibc-openssl-fips</code> bundle includes a new OpenSSL build that enforces the FIPS minimum key length of 112 bits for HMAC operations. The PostgreSQL driver (lib/pq) passes the database password as the HMAC key during SCRAM authentication, so a password shorter than 112 bits, or 14 ASCII characters, now causes a panic on connect rather than a graceful failure. Before upgrading, FIPS deployments should verify that the password in <code>SqlSettings.DataSource</code> is at least 14 characters and rotate it in PostgreSQL if it is shorter. Standard, non-FIPS builds are unaffected.</td>
</tr>
<tr>
<td>FIPS builds require a minimum of 14 characters for passwords, atmos/camo proxy configuration, and shared channel secrets. Shorter passwords for existing users will no longer be valid and require a password reset. Non-FIPS builds are unaffected.</td>
</tr>
<tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,17 @@ Back up your Mattermost database and file storage locations before configuring h
mmctl config set ClusterSettings.Enable true
mmctl config set ClusterSettings.ClusterName production
mmctl config set ClusterSettings.UseIPAddress true
mmctl config set ClusterSettings.ReadOnlyConfig true
mmctl config set ClusterSettings.GossipPort 8074
```

If you're storing configuration in `config.json` rather than the database, also set `ClusterSettings.ReadOnlyConfig` to `true` to prevent System Console changes from writing to one node's `config.json` and diverging from other nodes:

```bash
mmctl config set ClusterSettings.ReadOnlyConfig true
```

When configuration is stored in the database (see [Store configuration in your database](/administration-guide/configure/configuration-in-your-database)), `ClusterSettings.ReadOnlyConfig` is ignored because all nodes read the same configuration from the shared database.

See the [high availability configuration settings](/administration-guide/configure/environment-configuration-settings#high-availability) documentation for details on all available cluster settings, including `OverrideHostname` for non-standard network configurations.

8. **Restart Mattermost servers:** Restart each Mattermost server in the cluster to apply the new configuration.
Expand Down
2 changes: 1 addition & 1 deletion docs/main/deployment-guide/server/containers/fips-stig.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ All application-level code uses only FIPS-approved algorithms, ensuring that cry
<Note>

- The Mattermost FIPS image includes only prepackaged Boards, Playbooks, and Agents. Additional plugins can be added to the Mattermost FIPS image, but they will run in non-FIPS mode.
- Existing Docker or Kubernetes-based deployments can change the image from `mattermost/mattermost-enterprise-edition` to `mattermost/mattermost-enterprise-fips-edition`.
- Existing Docker or Kubernetes-based deployments can change the image from `mattermost/mattermost-enterprise-edition` to `mattermost/mattermost-enterprise-fips-edition`. See [Migrate an existing deployment to FIPS-compliant images](/deployment-guide/server/fips-migration) for step-by-step instructions.

</Note>
145 changes: 145 additions & 0 deletions docs/main/deployment-guide/server/fips-migration.mdx
Original file line number Diff line number Diff line change
@@ -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`.
Loading
Loading