Delegated Permissions
EnterpriseBacula Enterprise Only
This solution is only available for Bacula Enterprise. For subscription inquiries, please reach out to sales@baculasystems.com.
The great majority of services of the Bacula Enterprise M365 plugin use Application permissions. With this model, the plugin application can directly access the implied services once a tenant admin has approved it.
Some workloads still require Delegated permissions, where the plugin needs to impersonate a user in order to access or restore data in a supported way.
The current behavior by module is:
- Calendar:
User calendars: Application permissions
Group calendars: Delegated permissions
- Chat:
Backup: Application permissions
Restore to M365 chat conversations: Delegated permissions
- Tasks:
To-Do (user tasks): Delegated permissions
- Planner:
Backup: Application permissions
Restore: Delegated permissions
- OneNote:
Backup/restore use delegated permissions
Alternative protection path for binary notebook artifacts: OneDrive service
- Teams:
Backup and most restore operations: Application permissions
Restore of private channel messages in
team_private_channels_mode=DELEGATED: Delegated permissionsRestore of guest members (
team_guest_members_enable=yes): Delegated permissions
Scope by entity
To avoid over-generalization, delegated requirements should be read together with the protected entity kind:
calendarservice: -user=*scope: application-based -group=*scope: delegatedtasksservice: - User To-Do (user=*): delegated - Group Planner backup (group=*): application-based - Group Planner restore (group=*): delegatedchatservice: - Backup of user chats: application-based - Restore of chats/messages into M365: delegatedteamsservice: - Group/team backup and most restore flows: application-based - Only selected restore actions require delegated permissions (private channels in delegated mode, guest member restore)
Note
Starting from Bacula Enterprise 18.2.5, delegated permission logins can be completed with a tenant Global Admin account for eligible delegated flows.
Note
Starting from Bacula Enterprise 18.2.5, Planner backup runs with application permissions.
Delegated permissions or application permissions are automatically applied when they are needed. However, delegated permissions need user interaction the first time they are invoked, or if the local information about access tokens has been lost for some reason.
General strategy
The recommended operating model is:
Keep protection application-based wherever Microsoft allows it.
Use delegated permissions only for workloads that still require user-context access.
For group-based delegated scenarios (for example group calendars and planner restores), centralize operations with one dedicated backup user and add it as owner/member where required.
Trigger delegated login before backup windows (
parameter=login:[entity]) to avoid interactive waits during jobs.Keep and protect the token cache file so the plugin can refresh tokens automatically without repeated user interaction.
For user To-Do tasks, delegated permissions are currently required by Microsoft APIs, so they cannot be fully avoided when that workload must be protected.
The user interaction can be manually triggered with a special query command that may be run as follows:
.query plugin="m365: tenant=e421f055-748a-4a80-90da-bf48b66fa166 objectid=9017f87a-c164-488e-8f93-47139bcd6d47" client=127.0.0.1-fd parameter=login:peter@bacula.onmicrosoft.com
info=Connected through: bacula-m365-plugin-standalone
info=We don't have a valid token for peter@bacula.onmicrosoft.com. It's needed to sign in
info=To sign in; use a web browser to open the page https://microsoft.com/devicelogin and enter the code LXSZGLY3F to authenticate. Please do it with peter@bacula.onmicrosoft.com
Note the format of the parameter, that is parameter=login:[usermail].
Additionally, it is possible to log in using a group with the format: parameter=login:[groupname] or a site, using exactly the same format and the site name.
.query plugin="m365: tenant=e421f055-748a-4a80-90da-bf48b66fa166 objectid=9017f87a-c164-488e-8f93-47139bcd6d47" client=127.0.0.1-fd parameter=login:Dev/Team/1
info=Connected through: bacula-m365-plugin-standalone
info=We don't have a valid token for any group owner of Dev/Team/1. It's needed to sign in
info=To sign in; use a web browser to open the page https://microsoft.com/devicelogin and enter the code LYZF9EC6Q to authenticate. Please do it with some owner of the group Dev/Team/1
info=Owners found: jorge@bacula.onmicrosoft.com;AdeleV@bacula.onmicrosoft.com
info=We have a valid token got from account:
user=jorge@bacula.onmicrosoft.com
info=It will be automatically refreshed when needed. But the current expiration date is: 2025-06-27T12:33:49Z
info=Backups using services with delegated permissions around jorge@bacula.onmicrosoft.com won't ask for intervention
We only need to follow the instructions, open a browser, enter the code and use the correct user to login (which means a user with access to the resource we want to backup).
For example, if we are working with the calendar of a group, we will need a user with access to that calendar (in general, to protect calendars associated to groups, it will be necessary to create a special backup user with access to all of them and perform the login with, which will avoid the need of performing the login process for every different group).
Here, if any MFA mechanism is enabled, it will be normally required and the user must complete the associated process. Finally Microsoft will ask to confirm if we want the plugin app to proceed with the operation, and we need to confirm:
Once the login is complete, the plugin will automatically end the operation and show something like:
info=We have a valid token got from account: johndoe@johndoe.onmicrosoft.com
info=It will be automatically refreshed when needed. But the current expiration date is: 2021-06-16T16:18:16Z
info=Backups using services with delegated permissions won't ask for intervention
It will also store token information locally in a special file located in the working directory inside a folder with the tenant name. For example:
/opt/bacula/working/m365/tenantname/[appid]-token_cache.json
This file is also backed up in the backup operation itself, so it can be restored manually, in case it was lost and you don’t want to run login operations again.
In case the query method is not invoked prior to any job needing it, the job itself will show the message in the joblog and it will be blocked until a user performs the needed interaction described above. Once this happens, the job will automatically continue.
To verify the users currently logged into the system, we can use another query call using the logged-users parameter:
.query plugin="m365: tenant=e421f055-748a-4a80-90da-bf48b66fa166 objectid=9017f87a-c164-488e-8f93-47139bcd6d47" client=127.0.0.1-fd parameter=login:logged-users
info=Connected through: bacula-m365-plugin-standalone
user=AlexW@bacula.onmicrosoft.com
user=jorge@bacula.onmicrosoft.com
Note
Starting with version 14.0 of Bacula Enterprise you can also see logged in users directly using BWeb, where you can also manually add logged-in users. In order to see more details, please go to section: BWeb Console<./m365-bweb-console>.
Below are additional technical details regarding delegated permissions:
The mechanism relies on AccessTokens and RefreshTokens, which have different lifetimes
controlled by Microsoft. As of the time this document was written, these tokens could not be
configured. However, Microsoft is now offering this feature in “preview”, indicating that it
should be available soon. For further information on AccessTokens and RefreshTokens,
refer to the following links:
Attention
Third party URL, may become outdated:
The default lifetime of an access token is variable. When issued, the Microsoft identity platform assigns a random value ranging between 60-90 minutes (75 minutes on average) as the default lifetime of an access token.
RefreshTokens have a lifespan of 90 days by default, if not revoked for any of the
reasons stated in the shared links. As long as any operation involving it is re-run,
it will be automatically renewed without requiring user intervention.
The retry time is by default 15 minutes. It is dependent on the parameter
graph_read_timeout (which is three times that value), meaning extending this variable
will also prolong the retry time for delegated permissions.
The default number of retry attempts is 5 and is linked to the overall retry configuration: graph_retries.
See also
Previous articles:
Next articles:
Go back to: Microsoft 365 (M365) Plugin.