Implementing Delegated Graph API Access for an Azure Function Writing to SharePoint Site

Fred Wong 5 Reputation points
2026-07-23T19:45:40.2166667+00:00

Need some advice on a timer triggered Azure Function (.NET Isolated / C#) I'm working on. The purpose of the Function App is to get some data from an Azure SQL db every month and then write an Excel file as a report of sorts to my team SharePoint site. I had the code/approach sort of in mind, but as a first step I had to and am currently talking to our IT dept. for getting the Graph API access for Sites.Selected, and then a SP admin to grant access to our particular SP site. The following is where I'm now a bit confused.

We have an Enterprise Application/Service Principal for the Function App (pre-existing setup; I'm basically adding another Azure Function to our Function App resource) and I thought that it's on the Service Principal Azure resource where we would add the API access (like on the Security -> Permissions page). Our IT person said that they can only grant me Delegated type permission, but I thought something like a Service Principal can't actually use delegated permissions (as compared to Application type permission) nor would a timer triggered Azure function be able to "sign in" so to speak.

If it is actually Delegated, what would the authentication look like in the code? I originally envisioned it as if it were Application permissions so I would just do something like

var credential = new DefaultAzureCredential();

when configuring the builder.Services registrations but that probably wouldn't work for Delegated, right?

Total novice when it comes to how all these Azure resources connect and authenticate with each other; I'm not even sure if I paraphrased what I was told about the Service Principal/Managed Identity stuff correctly. Any help would be appreciated!

Azure Functions
Azure Functions

An Azure service that provides an event-driven serverless compute platform.


3 answers

Sort by: Most helpful
  1. Mohammad Altaf 190 Reputation points Microsoft External Staff Moderator
    2026-07-24T16:42:20.82+00:00

    Hello @Fred Wong

    Welcome to Microsoft Q&A.

    For a timer-triggered Azure Function, the function runs as an unattended background process without a signed-in user. Because of this, Delegated permissions are generally not the appropriate authentication model, as delegated permissions require a user context.

    For this scenario, the recommended approach is to use Application permissions with either a Managed Identity or Service Principal, allowing the Function App to authenticate as itself rather than on behalf of a user.

    If the goal is to restrict access to only a specific SharePoint site, Sites.Selected is a good option because it does not automatically grant access to all SharePoint sites. In addition to granting the Graph API permission, the application must also be explicitly assigned access to the target SharePoint site. Microsoft Graph documentation states that Sites.Selected supports both delegated and application permission models and requires explicit assignment to the target resource before access is granted.

    Based on the scenario described, your original approach using DefaultAzureCredential() with a Managed Identity aligns well with the authentication model commonly used for unattended Azure Functions accessing Microsoft Graph.

    The concern raised by the IT department may relate to your organization's internal security and governance policies around application permissions rather than the behavior of Sites.Selected itself. When configured correctly, Sites.Selected provides more granular access than broader permissions such as Sites.Read.All or Sites.ReadWrite.All.

    I hope this helps clarify the authentication model for your solution. Please let us know if you have any further questions.

    Thank you.

    Was this answer helpful?

    1 person found this answer helpful.
    0 comments No comments

  2. Sina Salam 31,216 Reputation points Volunteer Moderator
    2026-07-28T16:51:51.3633333+00:00

    Hello Fred Wong,

    Welcome to the Microsoft Q&A and thank you for posting your questions here.

    I understand that you are Implementing Delegated Graph API Access for an Azure Function Writing to SharePoint Site.

    AI answer is mostly correct and @Mohammad Altaf technically yes. However, there is a missing point. The issue is Delegated Microsoft Graph permissions require a signed-in user context, whereas a Timer-triggered Azure Function is an unattended background process that authenticates using its own identity. Consequently, DefaultAzureCredential and Managed Identity can only obtain Application (app-only) access tokens and cannot authenticate using Delegated permissions.

    The supported method for implementation is to:

    • Grant the Function App's Managed Identity (or Service Principal) the Microsoft Graph Application permission Sites.Selected.
    • Grant admin consent for the permission in Microsoft Entra ID.
    • Have a SharePoint administrator assign the application's required access (write, manage, or fullcontrol, as appropriate) only to the target SharePoint site.
    • Authenticate the Azure Function using DefaultAzureCredential and Microsoft Graph to upload the report.

    If organizational policy prohibits Application permissions, there is no supported code change or Microsoft Graph authentication flow that enables Delegated permissions for a Timer-triggered Azure Function. In that case, the organization must either approve the documented Sites.Selected Application model or redesign the solution to use an interactive application where Delegated authentication is supported.

    For more information, and implementation steps see:

    I hope this is helpful. Please! Do not hesitate to let me know if you have any other questions, steps or clarifications.


    Please do not close the thread by upvoting and accepting the answer if any part of it is helpful.

    Was this answer helpful?

    0 comments No comments

  3. AI answer

    2026-07-23T19:46:08.09+00:00

    A timer-triggered Azure Function should use app-only access, not delegated access, for this scenario.

    Key points:

    1. Delegated permissions require a signed-in user Delegated access means the app calls Microsoft Graph on behalf of a user. The effective permissions are the intersection of the signed-in user and the app permissions, and delegated permissions require user or admin consent depending on scope.
    2. App-only access uses the app’s own identity For noninteractive workloads, the app calls the API with its own identity and no signed-in user. That matches a timer-triggered Azure Function.
    3. DefaultAzureCredential with managed identity is the expected pattern for an Azure Function For a Function App running in Azure, DefaultAzureCredential uses the Function App’s managed identity. The SharePoint webhook guidance explicitly uses DefaultAzureCredential and states that, in Azure, it authenticates with the managed identity of the Function App.
    4. Sites.Selected is an application permission model that still requires site-level assignment Assigning Sites.Selected alone is not enough. After that permission is granted and consented, explicit permission must still be granted on the target SharePoint site. The site-level role can be read, write, manage, or fullcontrol.
    5. To grant site permissions, elevated permission is required for the grant operation Managing site permission assignments through Microsoft Graph requires high privilege for the caller performing the grant. The selected-permissions overview states that managing access at the site level requires Sites.FullControl.All. A Microsoft Q&A answer in the context also states that to create the permission entry on the site, Sites.FullControl.All is required, and if delegated is used for that grant operation, the user must be a site collection admin.

    What this means for the design:

    • The Function App identity should have application permission Sites.Selected.
    • A SharePoint admin or sufficiently privileged app/admin process must then grant that identity access to the specific site.
    • The Function code should use managed identity authentication, for example via DefaultAzureCredential.
    • A purely delegated model does not fit a monthly timer-triggered background job, because there is no interactive signed-in user for the function to act on behalf of.

    For the SharePoint site grant, the documented flow is:

    1. In Azure portal, open the Function App.
    2. Go to Identity and note the system-assigned managed identity Object (principal) ID.
    3. Grant that managed identity the SharePoint API Sites.Selected app-only permission.
    4. In Enterprise applications, find that managed identity and note its Application ID.
    5. Grant that application effective access to the specific SharePoint site, such as write or manage depending on what is needed.

    For writing a report file to a site, write is the role that allows reading and modifying metadata and contents. manage is broader and is noted as the minimum required to register a webhook, which is more than this file-write scenario appears to need.

    If IT is insisting they can only grant delegated permission to the Function App’s service principal, that does not align with the documented app-only managed identity pattern for Azure Functions. In that case, the request to IT should be reframed as:

    • grant application permission Sites.Selected to the Function App managed identity or app identity
    • then have a SharePoint admin grant that identity access to the specific site

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.