{"id":13724127,"url":"https://github.com/mattermost/mattermost-operator","last_synced_at":"2026-03-06T09:15:40.690Z","repository":{"id":37431893,"uuid":"174368288","full_name":"mattermost/mattermost-operator","owner":"mattermost","description":"Mattermost Operator for Kubernetes","archived":false,"fork":false,"pushed_at":"2026-02-16T18:04:01.000Z","size":45693,"stargazers_count":134,"open_issues_count":27,"forks_count":82,"subscribers_count":28,"default_branch":"master","last_synced_at":"2026-02-16T19:19:05.024Z","etag":null,"topics":["golang","hacktoberfest","kubernetes","mattermost"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mattermost.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-03-07T15:14:20.000Z","updated_at":"2026-02-16T18:02:24.000Z","dependencies_parsed_at":"2024-01-01T23:57:57.752Z","dependency_job_id":"5bcc1206-ae82-41fa-a6e4-4ac09b688bac","html_url":"https://github.com/mattermost/mattermost-operator","commit_stats":null,"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"purl":"pkg:github/mattermost/mattermost-operator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattermost%2Fmattermost-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattermost%2Fmattermost-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattermost%2Fmattermost-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattermost%2Fmattermost-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattermost","download_url":"https://codeload.github.com/mattermost/mattermost-operator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattermost%2Fmattermost-operator/sbom","scorecard":{"id":626316,"data":{"date":"2025-08-11","repo":{"name":"github.com/mattermost/mattermost-operator","commit":"d7020397cd1d1d31d142d9d228d62a2b035f6364"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":7.1,"checks":[{"name":"Maintained","score":10,"reason":"14 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":9,"reason":"Found 20/21 approved changesets -- score normalized to 9","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: topLevel 'contents' permission set to 'read': .github/workflows/cd.yml:11","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:15","Warn: no topLevel permission defined: .github/workflows/cleandocker.yml:1","Warn: no topLevel permission defined: .github/workflows/notify-release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":5,"reason":"dependency not pinned by hash detected -- score normalized to 5","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/cd.yml:58: update your workflow using https://app.stepsecurity.io/secureworkflow/mattermost/mattermost-operator/cd.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:163: update your workflow using https://app.stepsecurity.io/secureworkflow/mattermost/mattermost-operator/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/notify-release.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/mattermost/mattermost-operator/notify-release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/notify-release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/mattermost/mattermost-operator/notify-release.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:5","Warn: containerImage not pinned by hash: Dockerfile:19","Warn: containerImage not pinned by hash: Dockerfile.fips:5","Warn: containerImage not pinned by hash: Dockerfile.fips:22","Warn: goCommand not pinned by hash: scripts/k8s.io/code-generator/generate-groups.sh:53","Info:  10 out of  11 GitHub-owned GitHubAction dependencies pinned","Info:  10 out of  13 third-party GitHubAction dependencies pinned","Info:   0 out of   4 containerImage dependencies pinned","Info:   0 out of   1 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/mattermost/.github/SECURITY.md:1","Info: Found linked content: github.com/mattermost/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/mattermost/.github/SECURITY.md:1","Info: Found text in security policy: github.com/mattermost/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Branch-Protection","score":5,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'master'","Info: 'allow deletion' disabled on branch 'release-v1.20'","Info: 'allow deletion' disabled on branch 'release-v1.19'","Info: 'force pushes' disabled on branch 'master'","Info: 'force pushes' disabled on branch 'release-v1.20'","Info: 'force pushes' disabled on branch 'release-v1.19'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'master'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'release-v1.20'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'release-v1.19'","Warn: 'stale review dismissal' is disabled on branch 'master'","Warn: 'stale review dismissal' is disabled on branch 'release-v1.20'","Warn: 'stale review dismissal' is disabled on branch 'release-v1.19'","Warn: required approving review count is 1 on branch 'master'","Warn: required approving review count is 1 on branch 'release-v1.20'","Warn: required approving review count is 1 on branch 'release-v1.19'","Warn: codeowners review is required - but no codeowners file found in repo","Warn: codeowners review is required - but no codeowners file found in repo","Warn: codeowners review is required - but no codeowners file found in repo","Warn: 'last push approval' is disabled on branch 'master'","Warn: 'last push approval' is disabled on branch 'release-v1.20'","Warn: 'last push approval' is disabled on branch 'release-v1.19'","Warn: no status checks found to merge onto branch 'master'","Warn: no status checks found to merge onto branch 'release-v1.20'","Warn: no status checks found to merge onto branch 'release-v1.19'","Info: PRs are required in order to make changes on branch 'master'","Info: PRs are required in order to make changes on branch 'release-v1.20'","Info: PRs are required in order to make changes on branch 'release-v1.19'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":8,"reason":"SAST tool is not run on all commits -- score normalized to 8","details":["Warn: 25 commits out of 29 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T06:34:46.350Z","repository_id":37431893,"created_at":"2025-08-21T06:34:46.350Z","updated_at":"2025-08-21T06:34:46.350Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30168698,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T07:56:45.623Z","status":"ssl_error","status_checked_at":"2026-03-06T07:55:55.621Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","hacktoberfest","kubernetes","mattermost"],"created_at":"2024-08-03T01:01:50.764Z","updated_at":"2026-03-06T09:15:40.680Z","avatar_url":"https://github.com/mattermost.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Mattermost Operator for Kubernetes ![CircleCI branch](https://img.shields.io/circleci/project/github/mattermost/mattermost-operator/master.svg) [![Community Server](https://img.shields.io/badge/Mattermost_Community-cloud_channel-blue.svg)](https://community.mattermost.com/core/channels/cloud)\n\n[![Mattermost](https://user-images.githubusercontent.com/7205829/137170381-fe86eef0-bccc-4fdd-8e92-b258884ebdd7.png)](https://mattermost.com)\n\n\n## Summary\n[Mattermost](https://mattermost.com) is an open source platform for secure collaboration across the entire software development lifecycle. It's written in Golang and React and runs as a single Linux binary with MySQL or PostgreSQL.\n\nThis repo contains a Kubernetes Operator for Mattermost to simplify deploying and managing your Mattermost instance.\n\nThe Mattermost server source code is available at https://github.com/mattermost/mattermost-server.\n\n## Install\n\nSee the installation instructions at https://docs.mattermost.com/install/install-kubernetes.html.\n\n## Custom Resource Documentation\n\nYou can review the full list of CRD configuration options [here](./docs/mattermost_v1beta1_crd.md).\n\n## Migrate to Mattermost Custom Resource\n\nIn version `v2.0.0` of the Mattermost Operator, several breaking changes will be introduced. Some of the more significant ones are:\n- The name of the Custom Resource changed from `ClusterInstallation` to `Mattermost`.\n- Support for `BlueGreen` and `Canary` deployments was dropped.\n- Layout of some fields changed.\n\nTo prepare for the new release all `ClusterInstallation` Custom Resources need to be migrated to `Mattermost`.\nMattermost Operator in version `v1.12.0` provides a mechanism to make the migration easier.\nTo run the migration see [the automatic migration guide](./docs/migration.md).\n\n\n## Restore an existing Mattermost MySQL Database\nTo restore an existing Mattermost MySQL Database into a new Mattermost installation using the Mattermost Operator you will need to follow these steps:\n\nUse Case: An existing AWS RDS Database\n  - First you need to dump the data using mysqldump\n  - Create an EC2 instance and install MySQL\n  - Restore the dump in this new database\n  - Install `Percona XtraBackup`\n  - Perform the backup using the `Percona XtraBackup`\n    - `xtrabackup --innodb_file_per_table=1 --innodb_flush_log_at_trx_commit=2 --innodb_flush_method=O_DIRECT --innodb_log_files_in_group=2 --log_bin=/var/lib/mysql/mysql-bin --open_files_limit=65535 --innodb_buffer_pool_size=512M --innodb_log_file_size=128M --server-id=100 --backup=1 --slave-info=1 --stream=xbstream --host=127.0.0.1 --user=USER --password=PASSWORD --target-dir=~/xtrabackup_backupfiles/ | gzip - \u003e BACKNAME.gz`\n  - Upload to an AWS S3 bucket\n  - Create a Mattermost Cluster, for example:\n  ```\n  apiVersion: mattermost.com/v1alpha1\n  kind: ClusterInstallation\n  metadata:\n    name: example-clusterinstallation\n  spec:\n    ingressName: example.mattermost-example.dev\n  ```\n  - Create the Restore/Backup secret with the AWS credentials\n  ```\n  apiVersion: v1\n  kind: Secret\n  metadata:\n    name: restore-secret\n  type: Opaque\n  stringData:\n    AWS_ACCESS_KEY_ID: XXXXXXXXXXXX\n    AWS_SECRET_ACCESS_KEY: XXXXXXXXXXXX/XXXXXXXXXXXX\n    AWS_REGION: us-east-1\n    S3_PROVIDER: AWS\n  ```\n  - Create the mattermost restore manifest to deploy\n  ```\n  apiVersion: mattermost.com/v1alpha1\n  kind: MattermostRestoreDB\n  metadata:\n    name: example-mattermostrestoredb\n  spec:\n    initBucketURL: s3://my-sample/my-backup.gz\n    mattermostClusterName: example-clusterinstallation\n    mattermostDBName: mattermostdb\n    mattermostDBPassword: supersecure\n    mattermostDBUser: mmuser\n    restoreSecret: restore-secret\n  ```\n\nIf you have an machine running MySQL you just need to perform the `Percona XtraBackup` step\n\n## Developer Flow\nTo test the operator locally. We recommend [Kind](https://kind.sigs.k8s.io/), however, you can use Minikube or Minishift as well.\n\n### Prerequisites\nTo develop locally you will need the [Operator SDK](https://github.com/operator-framework/operator-sdk).\n\nFirst, checkout and install the operator-sdk CLI:\n\n```bash\nmkdir -p $GOPATH/src/github.com/operator-framework\ncd $GOPATH/src/github.com/operator-framework\ngit clone https://github.com/operator-framework/operator-sdk\ncd operator-sdk\ngit checkout master\nmake install\n```\n\nIf you made changes to any structs representing Custom Resources make sure to regenerate code and manifests:\n```\nmake generate manifests\n```\n\nIf generation produced any unexpected changes, clean old binaries and rerun the generation:\n```\nmake clean generate manifests\n```\n\n\u003e If the manifest generation is making changes to package paths this is [a known bug](https://github.com/kubernetes/gengo/issues/147) while running the previous command outside `GOPATH` or by having the `GOPATH` flag unset. Make sure you clone the repository in the appropriate folder (see below) and that your `GOPATH` environment variable is set.\n\n### Building mattermost-operator\nTo start contributing to mattermost-operator you need to clone this repo to your local workspace.\n\n```bash\nmkdir -p $GOPATH/src/github.com/mattermost\ncd $GOPATH/src/github.com/mattermost\ngit clone https://github.com/mattermost/mattermost-operator\ncd mattermost-operator\ngit checkout master\nmake build\n```\n\n### Testing locally with Kind\nDeveloping and testing local changes to Mattermost Operator is fairly simple. For that you can deploy Kind cluster.\n\n\u003e **NOTE:**\n\u003e You don't need to push the mattermost-operator image to DockerHub or any other registry if testing with kind. You can load the image, built with `make build-image`, directly to the Kind cluster by running the following:\n\u003e ```bash\n\u003e kind load docker-image mattermost/mattermost-operator:test\n\u003e ```\n\nTo spin up an appropriate Kind cluster and deploy dependencies, run:\n```bash\nmake kind-start mysql-minio-operators\n```\n\nAfter Kind cluster is up and running, build Mattermost Operator image, load it to Kind cluster and deploy it. For that, run:\n```bash\nmake build-image kind-load-image deploy\n```\n\n### Accessing Mattermost Installation on Kind\n\nAfter you create Mattermost installation using Mattermost Operator on Kind cluster,\nport-forward the service to access it:\n```bash\nkubectl port-forward svc/[MATTERMOST_NAME] 8065:8065\n```\n\n### Running Operator locally against K8s cluster\n\nMattermost Operator can be run on local machine against remote a Kubernetes cluster to rapidly test changes during the development.\n\nTo run Operator locally:\n- Make sure you are connected to a Kubernetes cluster.\n- Install Custom Resources by running: `kubectl apply -f ./config/crd/bases`.\n- Install MinIO and MySQL operators: `make mysql-minio-operators`.\n- Make sure Mattermost Operator **is not** running in the cluster or scale it down to 0 replicas to avoid unexpected behaviour.\n- Run Operator binary: `go run .`\n\nBe aware that running Operator locally does not verify Kubernetes manifests, RBAC rules, leader election etc.\n\n## Notes\n\n### Installation Size\n\nThe `spec.Size` field was modified to be treated as a write-only field.\nAfter adjusting values according to the size, the value of `spec.Size` is erased.\n\nReplicas and resource requests/limits values can be overridden manually but setting new Size will override those values again regardless if set by the previous Size or adjusted manually.\n\n## Release\n\nTo release a new version of Mattermost Operator you need to:\n\n- Have the repository up-to-date\n- Have the remote upstream configured\n- Have a clean repo, not pending commits and changes\n\nAs a first step of release process generate deployment manifests:\n```\nmake yaml\n```\n\nWe have a script that changes some files, commit those changes and then tag the main branch.\n\nTo run you can issue the following command:\n\n```bash\n./scripts/release.sh --tag=\u003cDESIRED_TAG\u003e\n```\n\nwhere:\n- `\u003cDESIRED_TAG\u003e` can be 1.10.1 for example\n\n## Why the Mattermost Operator Uses a ClusterRole\n\nThe Mattermost Operator is designed to manage and orchestrate multiple Mattermost installations within a Kubernetes cluster.  \nTo enable this, it requires **cluster-wide permissions**, which are granted through a `ClusterRole`.\n\n### Design Philosophy\n\nThe operator follows a **high-privilege controller model** built around the **principle of least privilege for managed applications**.\n\n- The operator itself requires elevated privileges at the cluster level to create and manage resources across namespaces.  \n- Each Mattermost installation it provisions is isolated using its own **`ServiceAccount`** and **namespace-scoped `Role`**, ensuring that each deployment operates with minimal privileges.\n\nThis approach balances **security** and **convenience** — administrators do not need to manually create RBAC policies for each Mattermost instance.\n\nThis allows the operator to:\n\n1. **Multi-Namespace Deployments**  \n   The operator supports multiple Mattermost instances deployed across different namespaces (e.g., `dev`, `staging`, `prod`) using a single operator instance.  \n   This enables platform teams to offer *Mattermost-as-a-Service* to multiple internal teams.\n\n2. **Cluster-Scoped Resources**  \n   Some Kubernetes resources managed by the operator (such as `IngressClass`) are **cluster-scoped** and cannot be managed with namespace-limited roles.\n\n3. **Cross-Namespace Integrations**  \n   The operator can provision and manage external dependencies — such as **MySQL clusters** or **MinIO instances** — that may reside in different namespaces.  \n   Managing these cross-namespace resources requires cluster-level permissions.\n\n4. **Namespace Metadata Access**  \n   The operator needs to read and interact with namespace metadata to properly configure DNS names, routing, and service discovery across installations.\n\n5. **Operational Flexibility**  \n   Operating at the cluster level simplifies management workflows.  \n   Platform administrators can deploy, update, and monitor multiple Mattermost instances without deploying a separate operator in each namespace.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattermost%2Fmattermost-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattermost%2Fmattermost-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattermost%2Fmattermost-operator/lists"}