You can now create Microsoft Teams meetings as an application without a users needing to be present: here’s how to use Application Access Policy
The current GA graph endpoint (/v1.0) for creating a Microsoft Teams team requires you to use User-Delegated Permissions, not Application Permissions:
This is an issue for applications that wish to create Teams meetings when a user isn’t present. There are lots of scenarios where this might be true, such as back-end processes and API-driven services. There are some workarounds today, such as using a service-account, but they’re not great and don’t scale well, especially for multi-tenanted solutions (do you really want to keep logon creds for a service user for every customer?)
Application Permissions for meeting creation did exist on the /beta endpoint for a bit, but were deprecated in May 2020 and then removed in July 2020.
Now, though, they are back with a new permissions model that’s something of a Goldilocks solution. It’s not 100% Application Permissions, and it’s not fully User Delegated either. It’s Application Access Policy!
It was a single entry in the Microsoft Graph Changelog which brought this to my attention: Added support for application permissions to the onlineMeeting entity and associated methods.
Caveats & Disclaimers
- This blog post is based on the updated Create onlineMeeting documentation page, and also the linked explanation page: Allow applications to access online meetings on behalf of a user.
- The changes to this call are in Beta only right now. That means that they’re subject to change and use of these APIs in production applications is not supported.
How it works (as a developer)
As a developer, you can think of it just like Application Permissions. You’ll authenticate as an application and use that bearer token when creating a meeting. The only difference is that you don’t use /me/onlineMeetings to POST to, instead you POST to /users/{userId}/onlineMeetings. But, wait, what should you put for the userID? For now, with my developer hat on, I’m going to say that you get the userId from your tenant admin. If you’re the tenant admin, read on…
You also need to make sure your application is granted OnlineMeetings.ReadWrite.All in order to create meetings:
How it works (as a tenant admin)
Fundamentally, the meeting being created still needs to be owned by a user somewhere. That might still be a “service user” for auditing purposes, but you no longer need to provide credentials for the service user. Instead, you can authorise an Azure AD application to act “on behalf of” that user. That means that a developer can make an API call as that application, but for the service user.
To set this up, make sure you know the application ID you want to grant this policy to, and also have the user ID of the service user. Then, there’s a 2-step PowerShell process to enable this, thanks to 2 new PowerShell commands that have been added to the SkypeForBusiness module (which also covers Microsoft Teams):
New-CsApplicationAccessPolicy -Â Creates a new application access policy. Application access policy contains a list of application (client) IDs. When granted to a user, those applications will be authorized to access online meetings on behalf of that user.
Grant-CsApplicationAccessPolicy -Â Assigns a per-user application access policy to one or more users. After assigning an application access policy to a user, the applications configured in the policy will be authorized to access online meetings on behalf of that user.
To grant an application the access to create a meeting on behalf of a user, run each command in turn. First, create the policy for the application:
New-CsApplicationAccessPolicy -Identity MY-APP-POLICY -AppIds "APPLICATION-ID"-Description "MY APP POLICY DESCRIPTION"
(you can pass multiple application IDs if you wish, comma separated.)
Then, apply this policy to the service user. This will mean that the application will be able to issue the POST request shown above and create Teams that will look like they’ve been created by that user:
Grant-CsApplicationAccessPolicy -PolicyName MY-APP-POLICY -Identity "USER_ID"
Don’t get confused here with the fact the in the first PowerShell command, -Identity is the app policy name, but in the second it’s the user ID… ?
Of course, you don’t have to use a service account as the user: you could use any user account for this. Just be aware that the meeting that’s created will look like it’s come from that user. Conceptually, you could even use this for some convoluted delegation workflow where you want to produce meetings that look like they’ve been created by other people.
Great for Application Developers
This is really good to see. I was one of the grumbling voices when the functionality was removed from the /beta endpoint – I could understand why it was a problem, but equally not being able to create a Teams meeting without a user being present was a real pain.
This is a really nice half-way house. This means that a meeting can always be traced back to an owning user, but applications still have the freedom to create meetings when they want to. I’m excited to see how people will take this and enable new scenarios for embedding Teams meetings into application workflows.