Can you delete mailbox items on hold via the Graph API?

Yesterday, I has a short debate with regards to how the Recoverable items structure works in Exchange, and whether one will be able to delete items that fall under the scope of a lithold via the Graph API. The answer is of course NO, but I took this opportunity to brush up my /mailbox skills. So here’s how one can go about testing this.

First, a quick refresher on how the Recoverable items subtree and the folders therein behave is due. The details are in the official documentation, and for the purposes of this article we only need to know that items that are on (lit)hold will end up in the Purges folder, and be kept there for the duration of the hold. If the mailbox has an Online Archive enabled, another location to look in would be the RecoverableItems\Purges folder in the Online Archive mailbox.

While the official documentation clearly states that users cannot delete items while the mailbox is on hold, we have in fact seen this not hold true in the past. It’s been almost 7 years now since we uncovered that simple OWA bug that allowed bypassing hold controls, and one can only hope that Microsoft will not make the same mistakes again. All the more reason to check for yourself 🙂

Anyway, the first challenge you might run into when testing this via the Graph API is getting to the Purges folder and its content. You might try browsing the set of results returned by the /mailFolders endpoint, to no avail. Adding a $filter query will not help either, nor will using the includeHiddenFolders=true parameter. You will still be getting results only from the “Top of information store”, whilst the Purges folder we are interested in resides in the RecoverableItemsRoot store. In other words, what you need to do switch the context to said store, as follows:

GET https://graph.microsoft.com/v1.0/me/mailFolders('RecoverableItemsRoot')?$filter=displayName+eq+'Purges'

This will give you the id of the Purges folder, which you can then use to browse its content (no need to provide the store id from here on):

GET https://graph.microsoft.com/v1.0/me/MailFolders/AQMkAGU2MWM5NzU0LWY3MmQtNGI3OS1hNDVlLTBkMzI3OWVlADViM2YALgAAA6EpIkCGWdRMge0pKyjfROEBAEg98MzHI-9FiFjwzzGYA9UAAAIBJAAAAA==/messages

After that, we can select a random message and test our scenario:

GET https://graph.microsoft.com/v1.0/me/MailFolders/AQMkAGU2MWM5NzU0LWY3MmQtNGI3OS1hNDVlLTBkMzI3OWVlADViM2YALgAAA6EpIkCGWdRMge0pKyjfROEBAEg98MzHI-9FiFjwzzGYA9UAAAIBJAAAAA==/messages/AAMkAGU2MWM5NzU0LWY3MmQtNGI3OS1hNDVlLTBkMzI3OWVlNWIzZgBGAAAAAAChKSJAhlnUTIHtKSso30ThBwBIPfDMxyP-RYhY8M8xmAPVAAAAAAEkAABIPfDMxyP-RYhY8M8xmAPVAAfhX6YxAAA=

DELETE https://graph.microsoft.com/v1.0/me/MailFolders/AQMkAGU2MWM5NzU0LWY3MmQtNGI3OS1hNDVlLTBkMzI3OWVlADViM2YALgAAA6EpIkCGWdRMge0pKyjfROEBAEg98MzHI-9FiFjwzzGYA9UAAAIBJAAAAA==/messages/AAMkAGU2MWM5NzU0LWY3MmQtNGI3OS1hNDVlLTBkMzI3OWVlNWIzZgBGAAAAAAChKSJAhlnUTIHtKSso30ThBwBIPfDMxyP-RYhY8M8xmAPVAAAAAAEkAABIPfDMxyP-RYhY8M8xmAPVAAfhX6YxAAA=

As expected, the DELETE operation didn’t go through, and instead resulted in a 403 Forbidden response. Rest assured, Graph API operations cannot bypass the compliance controls within the service. In fact, the documentation does hint about this, albeit in a bit of misleading/incomplete manner:

Note You may not be able to delete items in the recoverable items deletions folder (represented by the well-known folder name recoverableitemsdeletions). See Deleted item retention and Clean up deleted items for more information.

Exercise completed.

This entry was posted in Exchange Online, Graph API, Microsoft 365, Office 365. Bookmark the permalink.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.