diff --git a/changelogs/unreleased/sh-update-mailroom-config.yml b/changelogs/unreleased/sh-update-mailroom-config.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0b3f9d4c61fde5a662c6cd61e5c4653aa4a6b24a
--- /dev/null
+++ b/changelogs/unreleased/sh-update-mailroom-config.yml
@@ -0,0 +1,5 @@
+---
+title: Add config support for using Microsoft Graph with MailRoom
+merge_request: 58250
+author:
+type: added
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 57ece521301607a4538652a6a352f79f420e479d..a6395460f67adea6ee132c489340bd7e8e33fc00 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -210,6 +210,13 @@ production: &base
     # Whether to expunge (permanently remove) messages from the mailbox when they are deleted after delivery
     expunge_deleted: false
 
+    # For Microsoft Graph support
+    # inbox_method: microsoft_graph
+    # inbox_options:
+    #   tenant_id: "YOUR-TENANT-ID"
+    #   client_id: "YOUR-CLIENT-ID"
+    #   client_secret: "YOUR-CLIENT-SECRET"
+
   ## Consolidated object store config
   ## This will only take effect if the object_store sections are not defined
   ## within the types (e.g. artifacts, lfs, etc.).
diff --git a/config/mail_room.yml b/config/mail_room.yml
index 23170acbf655703a9e463b4b0422eb6bbe2c3a86..25bda294a137d49a29bb84f3560bb5b65eeb1a1c 100644
--- a/config/mail_room.yml
+++ b/config/mail_room.yml
@@ -19,6 +19,13 @@
       :delete_after_delivery: true
       :expunge_deleted: <%= config[:expunge_deleted].to_json %>
 
+      <% if config[:inbox_method] %>
+      :inbox_method: <%= config[:inbox_method] %>
+      <% end %>
+      <% if config[:inbox_options].is_a?(Hash) %>
+      <%= config.slice(:inbox_options).to_yaml(indentation: 8).gsub(/^---\n/, '') %>
+      <% end %>
+
       :delivery_method: sidekiq
       :delivery_options:
         :redis_url: <%= config[:redis_url].to_json %>
diff --git a/spec/config/mail_room_spec.rb b/spec/config/mail_room_spec.rb
index 289e18be0d7480a537de93723ffd147e7b0c0919..6265b54931a71fd154f11f115556f06e67204a59 100644
--- a/spec/config/mail_room_spec.rb
+++ b/spec/config/mail_room_spec.rb
@@ -16,7 +16,9 @@
     }
     cmd = "puts ERB.new(File.read(#{absolute_path(mailroom_config_path).inspect})).result"
 
-    output, status = Gitlab::Popen.popen(%W(ruby -rerb -e #{cmd}), absolute_path('config'), vars)
+    result = Gitlab::Popen.popen_with_detail(%W(ruby -rerb -e #{cmd}), absolute_path('config'), vars)
+    output = result.stdout
+    status = result.status
     raise "Error interpreting #{mailroom_config_path}: #{output}" unless status == 0
 
     YAML.load(output)
@@ -68,6 +70,39 @@
     end
   end
 
+  context 'when both incoming email and service desk email are enabled for Microsoft Graph' do
+    let(:gitlab_config_path) { 'spec/fixtures/config/mail_room_enabled_ms_graph.yml' }
+    let(:queues_config_path) { 'spec/fixtures/config/redis_queues_new_format_host.yml' }
+    let(:gitlab_redis_queues) { Gitlab::Redis::Queues.new(Rails.env) }
+
+    it 'contains the intended configuration' do
+      expected_mailbox = {
+        email: 'gitlab-incoming@gmail.com',
+        name: 'inbox',
+        idle_timeout: 60,
+        expunge_deleted: true
+      }
+      expected_options = {
+        redis_url: gitlab_redis_queues.url,
+        sentinels: gitlab_redis_queues.sentinels
+      }
+      expected_inbox_options = {
+        tenant_id: '12345',
+        client_id: 'MY-CLIENT-ID',
+        client_secret: 'MY-CLIENT-SECRET',
+        poll_interval: 60
+      }
+
+      expect(configuration[:mailboxes].length).to eq(2)
+      expect(configuration[:mailboxes]).to all(include(expected_mailbox))
+      expect(configuration[:mailboxes].map { |m| m[:inbox_method] }).to all(eq('microsoft_graph'))
+      expect(configuration[:mailboxes].map { |m| m[:inbox_options] }).to all(eq(expected_inbox_options))
+      expect(configuration[:mailboxes].map { |m| m[:delivery_options] }).to all(include(expected_options))
+      expect(configuration[:mailboxes].map { |m| m[:delivery_options] }).to all(include(expected_options))
+      expect(configuration[:mailboxes].map { |m| m[:arbitration_options] }).to all(include(expected_options))
+    end
+  end
+
   def clear_queues_raw_config
     Gitlab::Redis::Queues.remove_instance_variable(:@_raw_config)
   rescue NameError
diff --git a/spec/fixtures/config/mail_room_enabled_ms_graph.yml b/spec/fixtures/config/mail_room_enabled_ms_graph.yml
new file mode 100644
index 0000000000000000000000000000000000000000..791760e1dfdc4a90e18b8d6bc68eb4677e58c7c9
--- /dev/null
+++ b/spec/fixtures/config/mail_room_enabled_ms_graph.yml
@@ -0,0 +1,26 @@
+test:
+  incoming_email:
+    enabled: true
+    address: "gitlab-incoming+%{key}@gmail.com"
+    user: "gitlab-incoming@gmail.com"
+    mailbox: "inbox"
+    expunge_deleted: true
+    inbox_method: "microsoft_graph"
+    inbox_options:
+      tenant_id: "12345"
+      client_id: "MY-CLIENT-ID"
+      client_secret: "MY-CLIENT-SECRET"
+      poll_interval: 60
+
+  service_desk_email:
+    enabled: true
+    address: "gitlab-incoming+%{key}@gmail.com"
+    user: "gitlab-incoming@gmail.com"
+    mailbox: "inbox"
+    expunge_deleted: true
+    inbox_method: "microsoft_graph"
+    inbox_options:
+      tenant_id: "12345"
+      client_id: "MY-CLIENT-ID"
+      client_secret: "MY-CLIENT-SECRET"
+      poll_interval: 60