{"record":{"id":"3e87d8bdfac92728","repo":"RocketChat/Rocket.Chat","slug":"error-action-not-allowed-3e87d8","errorCode":"error-action-not-allowed","errorMessage":"Adding OAuth Services is not allowed","messagePattern":"Adding OAuth Services is not allowed","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/auth/addOAuthService.ts","lineNumber":18,"sourceCode":"import type { ServerMethods } from '@rocket.chat/ddp-client';\nimport { check } from 'meteor/check';\nimport { Meteor } from 'meteor/meteor';\n\nimport { hasPermissionAsync } from '../../lib/authorization/hasPermission';\nimport { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';\nimport { addOAuthService } from '../../lib/oauth/addOAuthService';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\taddOAuthService(name: string): void;\n\t}\n}\n\nexport const addOAuthServiceMethod = async (userId: string, name: string): Promise<void> => {\n\tif ((await hasPermissionAsync(userId, 'add-oauth-service')) !== true) {\n\t\tthrow new Meteor.Error('error-action-not-allowed', 'Adding OAuth Services is not allowed', {\n\t\t\tmethod: 'addOAuthService',\n\t\t\taction: 'Adding_OAuth_Services',\n\t\t});\n\t}\n\n\tawait addOAuthService(name);\n};\n\nMeteor.methods<ServerMethods>({\n\tasync addOAuthService(name) {\n\t\tmethodDeprecationLogger.method('addOAuthService', '9.0.0', '/v1/settings.addCustomOAuth');\n\t\tcheck(name, String);\n\n\t\tconst userId = Meteor.userId();\n\n\t\tif (!userId) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'addOAuthService' });\n\t\t}","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/auth/addOAuthService.ts#L1-L36","documentation":"addOAuthServiceMethod() requires the caller to hold the 'add-oauth-service' permission before a custom OAuth service may be registered; otherwise error-action-not-allowed with action 'Adding_OAuth_Services'. The DDP wrapper 'addOAuthService' (deprecated in favor of POST /v1/settings.addCustomOAuth) resolves the current user and forwards to this check, so under-privileged or unauthenticated callers never reach the actual service setup.","triggerScenarios":"A user whose roles lack add-oauth-service calling Meteor.call('addOAuthService', name) or POST /api/v1/settings.addCustomOAuth; SSO setup automation using a personal token whose owner is not admin.","commonSituations":"Setting up SSO with a bot/service account never granted admin; customized permission sets where add-oauth-service was removed from the admin role; attempts from a logged-out session (surfaces after the invalid-user check).","solutions":["Perform the operation as a user whose role has 'add-oauth-service' (default: admin).","Grant the permission to the intended role via Authorization > Permissions.","For scripts, use an admin user's token against POST /api/v1/settings.addCustomOAuth."],"exampleFix":"// before: token belongs to a user without add-oauth-service -> error-action-not-allowed\nawait fetch('/api/v1/settings.addCustomOAuth', { method: 'POST', headers: nonAdminHeaders, body });\n\n// after: use an admin user's credentials (or grant add-oauth-service to the caller's role)\nawait fetch('/api/v1/settings.addCustomOAuth', { method: 'POST', headers: adminHeaders, body });","handlingStrategy":"try-catch","validationCode":"// Server-side pre-check mirroring the guard\nimport { hasPermissionAsync } from '../../lib/authorization/hasPermission';\n\nif ((await hasPermissionAsync(userId, 'add-oauth-service')) !== true) {\n  throw new Error('caller needs add-oauth-service permission');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await addOAuthServiceMethod(userId, name);\n} catch (err: any) {\n  if (err?.error === 'error-action-not-allowed' && err?.details?.action === 'Adding_OAuth_Services') {\n    // escalate: re-run with an admin session or grant the permission to the caller's role\n    return escalateToAdmin(() => addOAuthServiceMethod(adminUserId, name));\n  }\n  throw err;\n}","preventionTips":["Run admin-only setup steps with an admin session or admin token.","Check the role-permission matrix before automating settings changes.","Prefer the REST equivalent (/v1/settings.addCustomOAuth) for scripted setup — it returns clear 403s."],"tags":["permissions","oauth","authorization","configuration"],"backgroundTag":"permission-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}