{"id":19591965,"url":"https://github.com/catalyst/moodle-tool_mfa","last_synced_at":"2025-11-06T23:02:36.911Z","repository":{"id":35522460,"uuid":"217170627","full_name":"catalyst/moodle-tool_mfa","owner":"catalyst","description":"A Multi-Factor Authentication Moodle plugin with flexible support for TOTP, Email, IP and more","archived":false,"fork":false,"pushed_at":"2025-09-30T00:01:46.000Z","size":1738,"stargazers_count":35,"open_issues_count":99,"forks_count":41,"subscribers_count":30,"default_branch":"MOODLE_400_STABLE","last_synced_at":"2025-10-27T10:43:56.382Z","etag":null,"topics":["2fa","google-authenticator","mfa","moodle-plugin","totp"],"latest_commit_sha":null,"homepage":"https://moodle.org/plugins/tool_mfa","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/catalyst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2019-10-23T23:20:51.000Z","updated_at":"2025-09-25T07:40:54.000Z","dependencies_parsed_at":"2023-02-17T12:31:04.237Z","dependency_job_id":"1293dd6b-f0ef-40dc-adf4-4e01413a0759","html_url":"https://github.com/catalyst/moodle-tool_mfa","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/catalyst/moodle-tool_mfa","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-tool_mfa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-tool_mfa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-tool_mfa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-tool_mfa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/catalyst","download_url":"https://codeload.github.com/catalyst/moodle-tool_mfa/tar.gz/refs/heads/MOODLE_400_STABLE","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-tool_mfa/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":283095890,"owners_count":26778518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-06T02:00:06.180Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["2fa","google-authenticator","mfa","moodle-plugin","totp"],"created_at":"2024-11-11T08:32:13.951Z","updated_at":"2025-11-06T23:02:36.904Z","avatar_url":"https://github.com/catalyst.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# moodle-tool_mfa\n\n* [What is this?](#what-is-this)\n* [Why another MFA plugin for Moodle?](#why-another-mfa-plugin-for-moodle)\n* [Branches](#branches)\n* [Installation](#installation)\n* [Configuration](#configuration)\n  * [Authentication factors](#authentication-factors)\n    * [TOTP](#totp)\n    * [Mobile SMS](#mobile-sms)\n    * [WebAuthn / FIDO2](#webauthn--fido2)\n    * [IP Range](#ip-range)\n    * [Email](#email)\n    * [Lockout threshold](#lockout-threshold)\n  * [User filtering factors](#user-filtering-factors)\n    * [Auth type](#auth-type)\n    * [Non-admin](#non-admin)\n    * [User capability](#user-capability)\n    * [Role factor](#role-factor)\n    * [Login banner factor](#login-banner-factor)\n  * [Login flow factors](#login-flow-factors)\n    * [Grace mode](#grace-mode)\n    * [No-setup factor](#no-setup-factor)\n    * [Security questions](#security-questions)\n  * [Other factors](#other-factors)\n  * [Moodle Mobile app](#moodle-mobile-app)\n* [Points and examples](#points-and-examples)\n* [Debugging](#debugging)\n* [Security issues](#security-issues)\n* [Support](#support)\n\n## What is this?\n\nThis is a Moodle plugin which adds Multi-Factor authentication (MFA), also known as Two-factor authentication (2FA) on top of your existing chosen authentication plugins.\n\nhttps://en.wikipedia.org/wiki/Multi-factor_authentication\n\n## Why another MFA plugin for Moodle?\n\nThere are other 2FA plugins for moodle such as:\n\nhttps://moodle.org/plugins/auth_a2fa\n\nThis one is different because it is NOT a Moodle authentication plugin. It leverages new APIs that Catalyst specifically implemented in Moodle Core to enable plugins to *augment* the login process instead of replacing it. This means that this MFA plugin can be added on top of any other authentication plugin resulting in a much cleaner architecture, and it means you can compose a solution that does everything you need instead of compromising by swapping out the entire login flow.\n\nSee this tracker and the dev docs for more info:\n\nhttps://tracker.moodle.org/browse/MDL-66173\n\nhttps://docs.moodle.org/dev/Login_callbacks\n\nThe other major difference is that we support multiple authentication factor **types** as sub plugins, e.g. SMS, IP Range, Email, TOTP and WebAuthn / FIDO2 and in future anything else as new sub-plugins. They can be flexible configured so that different combinations of factors are considered enough.\n\n## Moodle supported branches\n| Version         |  Branch      | Required patches     |\n|-----------------|--------------|----------------------|\n| Moodle 4.0 - 4.2| MOODLE_400_STABLE | None            |\n| Moodle 4.3+     | Not supported here, now in Moodle core | |\n\n## Totara supported branches\n| Version         |  Branch      | Required patches     |\n|-----------------|--------------|----------------------|\n| Totara 12-17    | TOTARA_12 | MDL-66340, MDL-60470 |\n| Totara 18       | TOTARA_18 | MDL-66340, MDL-60470 |\n| Totara 19       | TOTARA_19 | MDL-66340, MDL-60470 |\n\n## Installation\n\nStep 1: Install the local module\n--------------------------------\n\nUsing git submodule:\n\n```\ngit submodule add git@github.com:catalyst/moodle-tool_mfa.git admin/tool/mfa\n```\n\nOR you can download as a zip from github\n\nhttps://github.com/catalyst/moodle-tool_mfa/archive/master.zip\n\nExtract this into /var/www/yourmoodle/admin/tool/mfa/\n\nThen run the moodle upgrade as normal.\n\nhttps://docs.moodle.org/en/Installing_plugins\n\n\nStep 2: Apply core patches\n-------------------------------\n\nThis plugin requires [MDL-60470](https://tracker.moodle.org/browse/MDL-60470) which was only added in 3.7, and [MDL-66340](https://tracker.moodle.org/browse/MDL-66340), which was added in 3.8.\n\nYou can easily backport these patches in one line for 3.5, 3.6 and 3.7:\n\nFor Moodle 3.5:\n\n```\ngit am --whitespace=nowarn \u003c admin/tool/mfa/patch/core35.diff\n```\n\nFor Moodle 3.6:\n\n```\ngit am --whitespace=nowarn \u003c admin/tool/mfa/patch/core36.diff\n```\n\nFor Moodle 3.7:\n\n```\ngit am --whitespace=nowarn \u003c admin/tool/mfa/patch/core37.diff\n```\n\n### Manual cherry-pick\nIn case the patches do not work due to an update to older Moodle branches (such as security updates), you can manually perform the cherry-picks.\nFor [MDL-60470](https://tracker.moodle.org/browse/MDL-60470):\n\n```\ngit cherry-pick bf9f255523e5f8feb7cb39067475389ba260ff4e\n```\nIf there are merge conflicts, ensure the lines that you are adding are consistent with the lines being added inside the patch files. Everything else can safely be ignored.\n\nFor [MDL-66340](https://tracker.moodle.org/browse/MDL-66340):\n\n```\ngit cherry-pick 4ed105a9fd4c37e063d384ff155bd10c3bfbb303\n```\nAs with above, if there are merge conflicts, ensure the lines that you are adding are consistent with the lines being added inside the patch files. Everything else can safely be ignored.\n\nOnce this has been performed, you can generate your own patch files using `git format-patch`. An example for Moodle 3.5 is below:\n```\ngit format-patch MOODLE_35_STABLE --stdout \u003e admin/tool/mfa/patch/new_core35.diff\n```\n\n## Configuration\n\nWARNING: Do not try to fully configure this plugin in the web GUI immediately after installation, at this point during the upgrade process you are not actually logged in so it is easy to 'brick' your moodle and lock yourself out.\n\nThe main concept to understand is the concept of factors. Each user must satisfy some combination of factors which sum to 100 points in order to login. By configuring multiple factors and weighting them you can easily have quite complex and flexible rules.\n\n### Authentication factors\n\nThese are what you would consider 'normal' 2FA or MFA factors.\n\n#### TOTP\n\nThis is standard Time-base One Time Password ([TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm)) using Google Authenticator, Authy, Duo or any other app which conforms to the open standard.\n\n#### Mobile SMS\n\nSend One Time security codes to mobile via SMS using AWS SNS.\n\n#### WebAuthn / FIDO2\n\nWith [FIDO Authentication](https://fidoalliance.org/fido2/), users sign in with phishing resistant credentials, called passkeys. Passkeys can be stored on devices, like smartphones or hardware security keys, and enable password-only logins to be replaced with secure and fast login experiences across websites and apps.\n\nThe WebAuthn / FIDO2 factor has been tested with the [Swissbit iShield Key series](https://www.swissbit.com/en/products/ishield-key/) and Yubico products. Other FIDO2 certified security keys should also be compatible with this plugin.\n\n#### IP Range\n\nUse this factor to say that if you are on a secure network then that counts for something. This is very useful because it requires no setup by the end user, so you can set it up so that you can login fully via a secure network, and once logged in they can setup other factors like TOTP, and then use those other factors for logging in when not on a secure network.\n\n#### Email\n\nA simple factor which sends a short lived code to your email which you then need to enter to login. Generally speaking this is a low security factor because typically the same username and password which logs you into moodle is the same which logs you into your email so it doesn't add much value.\n\nThis factor was implemented as a proof of concept of a factor which can return a hard FAIL state, ie positive evidence that your account is compromised rather than NEUTRAL where we simply lack evidence of additional factors that the end user is who they say they are.\n\n#### Lockout threshold\n\nThis is a generic setting which applies to all the 'input' factors above which is the amount of attempts a user has at answering input factors before they are not permitted to login. If your account is locked there is an admin report to find and unlock these users.\n\n### User filtering factors\n\nThese are pseudo factors which make it easier to setup policies around who MFA should apply to or not.\n\n#### Auth Type\n\nThis is so you can specify that users with certain auth types, eg SAML via ADFS, which may have already done it's own MFA checks, is worth 100 points which makes it exempt from additional checks.\n\n#### Non-admin\n\nThis factor enables you to give points for free to a user who is not an admin. This makes it easy to require admin users to have 2 or more factors while not affecting normal users.\n\n#### User capability\n\nThis factor checks whether a user has a capability, in the system context. If the user has this capability, they will not gain the points for this factor, and must instead use other factors to authenticate with the system. This is similar to the non-admin factor, however it operates on a role basis. In practice, the capability 'factor/capability:cannotpassfactor' should be given to roles who must use other factors to authenticate to the system. There is an additional setting for this factor, that will allow admins to gain points for this factor, as by default they will always gain no points for this factor.\n\n#### Role Factor\n\nThis factor checks whether a user has any chosen roles assigned in any context, and does not provide points if so. This can be used to ensure the selected roles must use a higher level of authentication such as TOTP, while letting non-specified roles authenticate seamlessly. This factor should generally have high privilege roles such as Manager and Administrator selected to enforce higher account security for these groups.\n\n#### Login banner Factor\n\nThis factor allows for display of a policy which forces users to read and accept a policy on every login. This is more flexible than the Moodle policy tool, which is built for one time acceptance. To set the message, a custom language pack should be used to override factor_loginbanner/policytext. This means that it can be replaced with an arbitrary set of HTML to display to the users. This factor should be used with a weight of 0 if you wish it to be an additional layer over the top of the MFA flow, without contributing any weight.\n\n### Login flow factors\n\nThese pseudo factors affect the overall setup flow for users.\n\n#### Grace mode\n\nThe grace mode is a pseudo factor to allow users to log in without interacting with MFA for a set period of time. Users can only achieve the points for this factor if there are no other input factors for them to interact with during the login process. This factor should be placed last in the list, that way all other factors are interacted with during the login process first. On the first page after login, if a user is currently within their grace period, regardless of whether they used gracemode as a login factor, they are presented a notification informing them of the grace period length, and that they may need to setup other factors or risk being locked out once the grace period expires.\n\n#### No-setup Factor\n\nThis pseudo factor is designed to allow people to pass only if they have not setup other factors for MFA already. Once another factor, such as TOTP is setup for a user, this factor no longer gives points, therefore the user must use TOTP to authenticate. This allows for an optional MFA rollout, where only users who wish to use MFA are affected by the MFA rollout.\n\n#### Security Questions\n\nAnother Catalyst plugin is the Security Questions plugin which augments the password reset process to be based off questions specific to the user rather than only access to the users email.\n\nThere is a Security Questions factor, BUT this is only because both plugins use the same callbacks and clash so this factor makes the two plugins compatible with each other.\n\nIt is possible that this factor could be turned into a proper factor which accepts answers to these questions if no other factors can be used.\n\nhttps://github.com/catalyst/moodle-tool_securityquestions\n\n\n### Other factors\n\nIn theory you could impement almost anything as a factor, such as time of day, retina scans, or push notificatons. For a list of potential factor ideas see:\n\nhttps://en.wikipedia.org/wiki/Multi-factor_authentication#Authentication_factors\n\n### Moodle Mobile App\n\nBy default the Moodle Mobile app handles the authentication of users directly, which circumvents the steps that tool_mfa adds.\n\nTo enforce MFA for the app as well you must set the tool_mobile 'typeoflogin' admin setting to be 'Via a browser window'.\n\n## Points and examples\n\nIf a users cumulative points is high enough then they are able to login. Points can be weighted for different factors. Some factors do not require any input, such as checking their IP Address is inside secure subnet, while other factors require input such as entering a code like TOTP or SMS. Factors with no input are checked first and then the remaining factors are checked in from the largest points to the smaller until you either have a cumulative points high enough to login, or you run out of factors and you are denied login.\n\nWhen you configure the points in the admin settings it will generate a list of valid factor permutations to easily check it's configured the way you want.\n\n### Example 1\n\nIf you have 3 factors configured, all factors default to 100 points effectiely making any of then enough to login:\n\n```\nauth=saml =\u003e 100\niprange =\u003e 100\ntotp =\u003e 100\n```\n\nThen it will show:\n\n```\nYou must be:\n* has an authentication type of saml\nOR\n* is on a secured network\nOR\n* using a TOTP app\n```\n\n### Example 2\n\nIf you change all 3 points to 50 then it would say:\n\n```\nYou must be:\n* has an authentication type of saml AND is on a secured network\nOR\n* has an authentication type of saml AND using a TOTP app\nOR\n* is on a secured network AND using a TOTP app\n```\n\n### Example 3\n\nWith a configuration of:\n\n```\nauth_saml =\u003e 100\niprange =\u003e 100\ntotp =\u003e 100\nemail =\u003e 50\nsecurity_quesstions =\u003e 50\n```\n\nThen these are valid conditions:\n\n```\nYou must be:\n* has an authentication type of saml\nOR\n* is on a secured network\nOR\n* using a TOTP app\nOR\n* has valid email setup AND answers security questions\n```\n\n## Debugging\n\nWhile you are setting up MFA there are 2 things which help make it simple to see what is going on:\n\n1) In the settings page is a 'Summary of good conditions for login' which does what it says on the box. If you have not setup any factors, or if they are configured in a way which would never all login then it will warn you.\n\n2) You can turn on debug mode, when you are logging in and stepping through the MFA login flow if will show you the list of factors and how they have been resolved. This is also shown on the MFA user settings page after you have logged in showing what combination was used for you session.\n\nIf you have inadvertantly messed things up and locked yourself out, you can disable the whole MFA plugin from the CLI:\n\n```sh\nphp admin/cli/cfg.php --component=tool_mfa --name=enabled --set=0\n```\n\n## Security issues\n\nIf you find a security issue with this or any catalyst plugin, please DO NOT open a github issue.\n\nInstead please responsibly disclose the issue in private to us via email:\n\nsecurity@catalyst-au.net\n\n## Support\n\nIf you have issues please log them in github here\n\nhttps://github.com/catalyst/moodle-tool_mfa/issues\n\nPlease note our time is limited, so if you need urgent support or want to\nsponsor a new feature then please contact Catalyst IT Australia:\n\nhttps://www.catalyst-au.net/contact-us\n\nThis plugin was developed by Catalyst IT Australia:\n\nhttps://www.catalyst-au.net/\n\n\u003cimg alt=\"Catalyst IT\" src=\"https://cdn.rawgit.com/CatalystIT-AU/moodle-auth_saml2/master/pix/catalyst-logo.svg\" width=\"400\"\u003e\n\n## Warm thanks\nThanks to the various authors and contributors to this plugin!\n\nThanks to [Swissbit](https://www.swissbit.com/en/) for sponsoring the work to add WebAuthn / FIDO2 support to this plugin.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatalyst%2Fmoodle-tool_mfa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcatalyst%2Fmoodle-tool_mfa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatalyst%2Fmoodle-tool_mfa/lists"}