Moodle 5.3 OAuth2: A UK Guide to Migrating Your VLE Integrations
Static token stuck in your ERP for years? Moodle 5.3 introduces OAuth 2. See what's changing, what's not, and where to begin.
by Cleverson Gouvêa

Moodle OAuth2 truly arrived with Moodle 5.3 LTS, released on 5 October 2026, and it changes how ERPs, student information systems, CRMs, and apps authenticate with your VLE. Instead of a static token that lives for years in a configuration file, you'll now have tokens that expire in an hour, secrets with validity periods, and immediate revocation. This guide shows what's changed, what hasn't, and how to plan your migration without breaking any integrations.
TL;DR
- Moodle 5.3 introduced its own OAuth 2 server, client manager, personal access tokens, and revocation endpoints (official release notes).
- These tokens are valid only for the new REST API (
/api/rest/v2). Classic web services continue to use the usual static token. They are separate systems.- The new REST API still covers only a few parts of Moodle. Enrolment, user creation, and grades remain on classic web services in 2026.
- The correct approach now isn't to "migrate everything," but rather to inventory, isolate authentication, and migrate by function as the REST API grows.
- New pitfall: by default, every authenticated user can create a personal token. Review this permission on upgrade day.
What Moodle 5.3 OAuth2 Is (and Isn't)
Until 5.2, anyone integrating an external system with Moodle primarily had one path: the classic web services. You enable web services, activate the REST protocol, create an external service with the allowed functions, and generate a token for a technical user. This token goes in the URL (wstoken=...) of each call to webservice/rest/server.php. It doesn't expire automatically unless someone fills in the "valid until" field.
OAuth 2 is a standard authorisation protocol (RFC 6749, from the IETF). Instead of a fixed password, the client system exchanges credentials for a short-lived access token and requests another when it expires. What the token can do is controlled by scopes, a list of explicit permissions.
In Moodle 5.3, this appears in a list of development tickets worth knowing, as each one translates into a new screen or behaviour on your site:
- MDL-89251: OAuth 2 server implementation in the backend
- MDL-89181: OAuth 2 client manager
- MDL-88473: Token revocation endpoints and logic
- MDL-88468 and MDL-88472: Screens for managing OAuth 2 clients and login flows
- MDL-87706: Personal access token interface
Now, the point almost every release announcement skips: Moodle 5.3 OAuth2 does not replace the classic web services token. The official REST API tokens documentation is explicit: the new tokens only work with the new REST API, have their own creation and management pages, and the "Enable web services" option doesn't even affect them. The classic token remains, managed under Site administration > Server > Web services > Manage tokens.
If you want an overview of integration before diving into authentication details, start with our guide on how to integrate Moodle with other systems. This post is a deep dive into the OAuth 2 part.
Static Token vs. Moodle OAuth2: The Key Comparison
Before comparing, a practical definition: adopting Moodle OAuth2 means exchanging permanent credentials for temporary, scoped credentials. The static token has a real advantage: it's simple. One line of configuration and the ERP talks to Moodle. The problem is what happens next. In audits of environments we've taken over, it's common to find tokens created years ago, linked to an administrator account, with no IP restriction and no expiry date. If it leaked in a repository, a log, or an email, it's valid until someone remembers to revoke it.
The table summarises the three ways to authenticate an integration in Moodle 5.3:
| Criterion | Web service token (classic) | Personal access token (new) | OAuth 2 client (new) |
|---|---|---|---|
| Where it works | Classic web service functions | New REST API only | New REST API only |
| Who creates it | Administrator or user with permission | The user themselves, in Preferences | Administrator registers the app |
| Validity | Indefinite, if 'valid until' isn't set | 7 days to 1 year (default: 1 month) | 1-hour access token |
| Renewal | Manual | Create another token | Refresh token (1 month) or new request |
| Permission limit | Service functions + user permissions | Scopes + user permissions | Scopes (+ user, in login flow) |
| Revocation | Delete the token | Immediate, via user screen | Immediate; deactivating the client cuts everything |
| Best use today | ERP, enrolment, grades, catalogue | Ad-hoc scripts and automations | New apps and integrations on the REST API |
The figures in the last two columns come from the official documentation for OAuth 2 clients and personal access tokens.
Why OAuth 2 Reduces the Impact of a Breach
With Moodle OAuth2, a stolen access token is valid for at most one hour. The client secret expires in one year. And, if something seems wrong, deactivating the client immediately invalidates issued tokens and prevents the use of secrets. For those who need to respond to a security questionnaire or a UK GDPR compliance for Moodle audit, this changes "we have an eternal key somewhere" to "we have credentials with a timeframe, scope, and audit trail."
Where the Static Token Still Wins
Operational simplicity. Implementing Moodle OAuth2 assumes the system on the other side knows how to request and renew tokens. A legacy ERP that only knows how to send a fixed parameter in the URL won't learn to renew tokens on its own. In this case, migration requires an intermediary piece (I'll discuss it later), and that comes with a cost.
The Two OAuth 2 Flows in 5.3: Which Suits Each Integration
Anyone configuring Moodle OAuth2 needs to decide two things right at the start. When registering a client in Site administration > Server > OAuth 2 clients, you choose the client type and the main flow. These two choices cannot be changed later. If you make a mistake, you create another client.
Authorization Code: When There's a User on the Other Side
This is the "log in with Moodle" flow. The user logs into Moodle, sees the scopes the app requests, and approves or cancels. The app receives a 1-hour access token and a 1-month refresh token. If the user has already approved all scopes before, Moodle doesn't ask again.
Suitable for:
- Institution's own mobile app. Since the app runs on the student's phone, it's a public client: it cannot keep a secret. In this case, Moodle requires PKCE (RFC 7636), a protection that prevents the use of an intercepted authorisation code.
- Student portal or dashboard showing the user's own data.
- Teacher tools acting on behalf of the logged-in user.
The return address (callback) must be HTTPS, with the exception of localhost for development.
Client Credentials: Machine-to-Machine Communication
No logged-in user. The server system exchanges client ID and secret for an access token. There is no refresh token: when the token expires, the integration requests another. Only confidential clients (running on a server you control) can use this flow.
It's the natural candidate for ERP, student information system, and CRM when the operation already exists in the REST API. It's also where Moodle OAuth2 demands the most discipline. But read the documentation's own warning carefully: with Client Credentials, the app acts as the main site administrator, limited only by the scopes. Anyone with the ID and a valid secret can use it. A broad scope here is a master key with an expiry date.
The Real Limit of Moodle OAuth2 in 2026: The REST API is Still Partial
The new REST API is built on Moodle's routing subsystem (based on the Slim Framework), available since 4.5. The api group routes are under the /api/rest/v2 prefix, according to the routing documentation for developers. Administrators navigate endpoints and required scopes in Site administration > Development > Moodle REST API UI, a Swagger interface.
The problem is coverage. The 5.3 documentation states that only some parts of Moodle are available via the REST API and that more will come in future versions. In practice, for those integrating ERPs and student information systems, this means:
- Creating users, enrolling, unenrolling, and submitting grades continue to depend on classic functions, such as
core_user_create_usersandenrol_manual_enrol_users. - An OAuth 2 token does not call these functions. There is no bridge between the two worlds.
- The available scopes vary by site, because plugins can add their own. Don't rely on a generic list: check your Moodle's Swagger interface.
In other words: today, Moodle OAuth2 effectively handles apps and read operations already covered by the REST API. Heavy academic administration integration still runs on the classic token. Anyone selling "complete migration to OAuth 2" at this point is selling something Moodle itself doesn't yet deliver.
How to Plan Your Integration Migration to Moodle OAuth2
A good migration is gradual and begins before changing any tokens. Planning Moodle OAuth2 is, first and foremost, an inventory task. This is the roadmap we use.
1. Inventory All Existing Tokens
Open Manage tokens and list each token: user, service, enabled functions, IP restriction, expiry date, and who uses it. In almost every inventory, at least one token appears that no one knows who it belongs to. That's the first one to investigate.
2. Classify Each Integration
For each system, answer three questions:
- Is there a human user in the flow? If yes, the target is Authorization Code. If not, Client Credentials.
- Do the operations it performs already exist in the REST API? Check the Swagger interface. If not, it stays on the classic token for now.
- Can the system on the other side renew tokens? A closed ERP that doesn't accept renewal logic will need an intermediary.
3. Isolate Authentication in an Intermediate Layer
This is the decision that saves the most money in the long run. The ERP's business logic shouldn't call Moodle directly. It should call a small integration service, which knows how to authenticate, renew tokens, log, and securely repeat calls. When the enrolment function migrates to the REST API, you replace one module, not rewrite the entire integration. We describe this design in the technical guide for SGA connected to Moodle.
4. Harden What Remains on the Classic Token
While the function hasn't migrated, reduce the risk of the static token: use a dedicated technical user (never the administrator), a service with only the necessary functions, IP restriction, and an expiry date. All of this already exists in classic web services, and almost no one uses it.
5. Pilot with a Small, Read-Only Case
The first production test of Moodle OAuth2 should be something that only reads data and whose error won't lock students out: a dashboard, a report, an app screen. Test token renewal, secret expiry, and revocation before putting write operations into production.
6. Run in Parallel and Only Then Revoke
Keep the old integration active until the new one goes through a complete cycle (an end of term, for example). Then revoke the classic token. Not before.
Pitfalls to Expect During the 5.3 Upgrade
Every User Can Create a Personal Token by Default
The moodle/api:createtoken capability is granted to the 'Authenticated user' role. In practice, any student can generate a token for the REST API, within their own permissions and scopes. For most institutions, this doesn't make sense. Decide consciously: remove the capability from the default role and grant it only to those who need it.
The OAuth 2 Clients Screen Disappears Without Composer Dependencies
OAuth 2 clients only appear if the site's Composer dependencies are installed. Installations done by 'unzipping' on shared hosting often lack this, and the screen simply won't exist. It's not a bug. It's a requirement.
A Secret Expiring in One Year Will Break Integrations
Confidential client secrets expire in one year and appear only once, upon creation. Moodle allows up to two active secrets at the same time precisely so you can rotate without downtime: generate the new one, swap it in the client system, then revoke the old one. Put the expiry date on your operations calendar on the day you create the client.
Old Web Service Plugins Will Break
Moodle 5.3 deprecated the old \external_* classes (MDL-81225). Custom or third-party plugins still using these classes currently work with a warning and are likely to break in a subsequent version. Include this in your inventory.
The Upgrade Itself Has Heavy Prerequisites
Moodle 5.3 requires PHP 8.3 or higher (64-bit, with the sodium extension and max_input_vars of at least 5,000), PostgreSQL 17, MySQL 8.4 or MariaDB 11.4, and only upgrades from Moodle 4.4. If your VLE is on 4.1 or 4.3, there's an intermediate step. I detailed the path in the checklist for upgrading Moodle 4.5 to 5.
When NOT to Migrate to Moodle OAuth2 Right Now
There are scenarios where postponing Moodle OAuth2 is the right decision:
- Your VLE isn't on 5.3 yet. First the upgrade, with user acceptance testing (UAT). Mixing the two changes multiplies the risk.
- The integration only performs operations not yet covered by the REST API. There's nowhere to migrate to. Harden the classic token and wait.
- The system on the other side doesn't support token renewal and there's no budget for the intermediate layer in this cycle.
- Low volume and stable manual process. If the admin staff imports a CSV weekly without issue, the priority is probably elsewhere.
And there's the opposite scenario, where it's worth starting now: a new mobile app, a student portal in development, or any project starting today. Building on the classic token now is creating technical debt you'll pay off in two versions' time. For those evaluating their own app, OAuth 2 with PKCE changes the security equation, and I wrote about the investment in your own Moodle app.
Regarding timing: 5.3 is an LTS release, with general support until 4 October 2027 and security fixes until 1 October 2029, according to the official release calendar. There's time to carry out the migration in stages, without rush or improvisation.
Cost and Timeframe
There's no standard price for migrating integrations to Moodle OAuth2, because the cost depends on the number of integrations and what each system on the other side accepts. But you can know where the money will go:
- Inventory and Classification: This is the cheapest step and the one that prevents the most waste. Generally, a few days.
- Intermediate Layer: This is the real investment. Once built, it serves all integrations.
- Migration by Function: Each migrated flow requires testing of renewal, expiry, and revocation, as well as UAT with a Moodle copy.
- Maintenance: Moodle releases versions in April and October. With each one, the REST API may gain new endpoints and scopes, and it's worth re-evaluating what can move off the classic token.
If the budget you received doesn't include a UAT environment or a review with each version, it's not cheaper. It's incomplete.
How Agathas Web Can Help
Agathas Web has been working with Moodle for over 15 years. Our team holds the Moodle Developer Certification from the Moodle Academy and operates VLEs in production, from server to app. We are an independent company, not a Moodle Partner. Planning and executing the adoption of Moodle OAuth2 is part of our Moodle development and support service.
What's included in the project:
- Token and integration inventory, with classification of what migrates now, what waits, and what needs hardening
- Upgrade to 5.3 LTS with UAT, including the PHP, database, and Composer requirements that make the OAuth 2 clients screen exist
- Integration layer with token renewal, logging, queuing, and idempotence, for ERP, student information system (including our SGA), CRM, and payment gateway
- OAuth 2 client configuration with minimal scopes, scheduled secret rotation, and personal token permission review
- Mobile app and WhatsApp via the Official API, triggered by Moodle events and authenticated correctly
- Managed hosting dedicated to Moodle, with monitoring and verified backup
How it works: we start with a diagnostic discussion to understand your systems, volume, and pain points. Then comes a technical proposal with architecture, timeline, and investment. Execution is done in a separate environment, UAT with your team, and only then goes to production. The integration code remains with you.
To engage us, contact us via the Agathas Web Moodle services page or the WhatsApp contact displayed there.
Conclusion: Moodle OAuth2 is a Destination, Not a Switch
Moodle 5.3 OAuth2 is the best security news for integrations in years: one-hour tokens, secrets with validity, explicit scopes, and immediate revocation. But it lives within the new REST API, which still only covers part of Moodle. Anyone trying to swap everything at once will find that enrolment and grades have nowhere to go.
The path that works is to inventory, isolate authentication, harden the classic token, and migrate function by function as the REST API grows. If you want this plan executed by those who operate Moodle in production, explore the Agathas Web Moodle service and request a diagnostic of your integrations.
Related posts

Moodle VPS or Managed Hosting: The True Cost for UK Organisations
A VPS might cost less than £30 a month. But updating, backing up, and securing Moodle on it costs significantly more. See the full breakdown.

Branded Moodle App: Proving its Worth for UK Education
A store icon won't pay the bills. Understand the payback calculation, hidden app store costs, and when to opt for the official Moodle app.

Moodle 4.5 to 5 Upgrade: A UK Expert's Practical Checklist
Moodle 5.3 LTS is out, and 4.5 loses security in 2027. Database, /public folder, plugins, and rollback: what practically hinders your upgrade.