M365Con 2027 – free online conference · 11–22 Jan 2027 · 120 sessions→ m365con.net

2026-11-03

Microsoft Graph API Permissions - Simply Explained

Microsoft Graph API Permissions - Simply Explained
One Graph permission can hand an app every mailbox in your company. Most people never notice that line until a security review points at it, because the permission sits quietly inside an app somebody set up months ago. In this episode of Simply Explained you will learn: - The Checkpoint Every App…

Show notes

One Graph permission can hand an app every mailbox in your company. Most people never notice that line until a security review points at it, because the permission sits quietly inside an app somebody set up months ago. In this episode of Simply Explained you will learn:

  • The Checkpoint Every App Has to Pass
  • What a Graph Permission Actually Is
  • The Two Kinds of Permission Nobody Separates at First
  • How to Read a Permission Name Like a Sentence
  • Who Gets to Say Yes
  • The Trap of Asking for Too Much
  • Where This Breaks Down
  • How This Fits Into Your Microsoft 365 and Azure World
  • What to Take Away

Simply Explained by M365.FM breaks down Microsoft 365, Azure and modern IT topics in clear, jargon-free language. Hosted by Mirko Peters. Become a supporter of this podcast: https://www.spreaker.com/podcast/m365-fm-microsoft-365-azure-cloud-power-platform-ai--6704921/support. This episode includes AI-generated content.

Host: Mirko Peters

Guests

Transcript

Read the full transcript

Welcome to the M365 FM podcast, where we explore the people, ideas and technologies shaping the future of work. The checkpoint every app has to pass one graph. Permission can hand an app every mailbox in your company. Most people never notice that line until a security review points at it because the permission sits quietly inside an app somebody set up months ago. Microsoft Graph is the single doorway apps used to reach your mail, your files, your teams messages, and the people in your directory. And it won't open for anything that wasn't granted permission. First, an app can ask in two ways acting as a signed in person or acting as itself with nobody in the room. And that choice decides whether it touches one person's data or the whole organization. Most graph projects don't fall apart because of code, and when they do fall apart, it's usually at consent because somebody asked for far more access than the job needed. By the end of this, you'll be able to read any permission name and know exactly what it lets an app do. What a graph permission actually is. Microsoft Graph is one doorway into almost everything your organization keeps in the cloud. Mail sits behind it. So do files and folders. So do teams conversations. And so does the directory that lists every account your company manages. Rather than learning a separate door for each service, an app learns this one and asks for the specific things it needs. A permission is the privilege an app has been granted before graph hands over anything at all. When an app asks for data, it wasn't granted. Graph refuses the request and returns an error instead of the answer. The permission name is what's printed on the key card, and that card decides which doors open for that app. Being signed in and being permitted are two separate gates, and beginners blur them together all the time. A person can be signed in and still see nothing, because the app was never granted the permission that matches the request, and no amount of logging in again will fix it. What makes this one model worth learning is how far it reaches. The same permission system covers exchange, mail, SharePoint, and OneDrive files, teams, and the users and groups. In Microsoft Entra ID, that means a single permission name can decide how far an app travels across all of it. It's also why the name deserves a second look. Say you build a small app that greets people by name when they sign in. It needs to read a bit of the signed in user's profile and nothing more. So it asks for one narrow permission that covers exactly that. If it instead asks for permission to change every profile in the company, the request would still work. And that gap between what the app needs and what it asked for is where trouble lives. Microsoft doesn't make you guess at any of this. Every permission in graph is documented, named in a consistent way and grouped by the resource it touches. So you can look one up and read what it allows before you ever approve it. The vocabulary is smaller than it looks, too. There are permissions for mail, calendars, files, groups, users, and the apps themselves, and they all follow the same shape. So learning one teaches you how to read the rest. The other thing worth knowing early is that a permission is attached to an app, rather than to a person or a device. Two people using the same app share the app's permissions, and when the app was granted something broad, both of them inherit that reach the moment they sign in. There's one small word inside these names that decides whether an app touches a single person's data or everyone's, and we'll come back to it in a moment. The two kinds of permission. Nobody separates at first graph gives an AB two completely different ways to ask, and almost everything else about permissions flows from that one split. The first way is called delegated access, and it means the app calls graph on behalf of a signed in user. The app borrows that person's identity for the moment of the request, and it can never reach past what that person can already reach on their own. If your account can't open a particular folder, an app acting as you can't open it either, no matter which permissions it holds. The second way is called Application Access. And here the app calls graph as itself. With nobody signed in at all. There's no person to borrow an identity from, so the app's own permissions are the only limit, and that limit can stretch across the whole organization. Microsoft's own documentation gives a blunt example, because an app holding the files read all application permission can read any file in the organization, not one person's files. All of them. What surprises people here is the overlap in the delegated model. The app's real access is the intersection of two things the permissions it was granted, and whatever the signed in user already had. Both limits apply at the same time, so a generous permission handed to an app doesn't widen what the person can see. That overlap is the reason delegated access is treated as the safer default, and Microsoft says so, directly calling it the recommended approach whenever it meets the app's needs. The instinct that flips here is worth naming. You might think asking for more is the safe move, but the app only model is actually the one that reaches your entire company, and it's the one that triggers the loudest consent prompt. Asking for everything points straight at the riskiest option. The better question is never how much access makes this easy. It's how little access makes this work. This split also answers something you may have wondered about, which is why the same app sometimes asks you to sign in and sometimes asks an administrator instead. The model it chose decides who gets asked. The practical version of the split comes down to one question. If a person has to be present for the work to happen, delegated access usually fits if the work has to happen while everyone is asleep, application access is the only option, and that's the moment to slow down and ask what the smallest version of it looks like. How to read a permission name like a sentence. Every graph permission name follows the same three part shape, and once you see it, you can't unsee it. The first part names the resource, the thing being touched. The second part names the operation usually read or read and write. The third part is the constraint and it's optional, which is the detail that matters most. Read a few out loud and the patent shows up fast. User dot read lets an app read the signed in user's own profile. Group A create is for making new groups, though not changing or deleting them. Application. Read. Write all reaches every app in the tenant while application read write owned by shrinks that to only the apps the app itself created or owns. The constraint is where the reach lives, and it comes in a small set of words. All means the whole organization owned by narrows things to what the app owns. Selected, shared, hidden and app folder each tighten the scope in their own way. The payoff of that flagged word arrives right here. When a permission carries no constraint at all. The default is that one person's own data. That's why user read reads u while user read all reads everyone. And the missing word is doing an enormous amount of work on a screen that's easy to skim. One honest limit belongs here because names describe intent, and intent isn't always the whole story. Microsoft's own materials note that names like mail, read, write, and sites dot full control all imply broad reach, and the practical advice is to test in a safe tenant rather than trusting the label alone. This is the skill that changes how you read a consent screen. Instead of seeing a wall of unfamiliar names, you start seeing sentences and the sentence tells you who is affected and how far the app can go. The name stay consistent across the whole service, so the effort you spend learning this shape pays off everywhere, and none of it asks you to memorize a separate dictionary. You'll also notice the names are specific enough to argue with which is the point. A permission that says all is telling you in plain language that it crosses every part of the organization, so nobody can claim the reach came as a surprise. If a name feels too broad for the job, it usually is, and there's almost always a smaller one nearby who gets to say yes. Reading the name tells you what an app wants. It doesn't tell you who's allowed to hand it over. And that second question has its own set of rules for delegated permissions. The answer is fairly forgiving. A person can consent for their own data, which is why a small app can ask you to approve a narrow permission the moment you sign in. An administrator can also consent on behalf of everyone at once, which helps when you'd rather not make every colleague click through the same prompt for application permissions, the door narrows sharply. Only an administrator can consent, and Microsoft is specific about which ones privileged role administrator and global administrator are the two roles that can grant an app. The app only permissions it's asking for. If you've ever watched a rollout stall while everyone waited on one person, this is usually why there's also a convenience feature that's easy to overlook, called tenant wide admin consent. An administrator approves an app once for everyone, and after that, people aren't nagged with prompts when they sign in, it removes friction, and it also means the approval decision gets made far away from the people who'll actually use the thing. One more gate sits on top of all of this, and it belongs to your own organization. Even when a permission technically allows a user to consent, your tenant's app, consent policies can restrict or block that, and plenty of organizations do exactly that. A permission can be perfectly valid on paper and still stop at a policy someone set deliberately. The moment of consent is worth watching closely, because it's the clearest view you'll ever get of what an app can do. The prompt lists the permissions in plain language, and a delegated request reads like a request to act as you. While an application request reads like a request to act across everyone reading that screen instead of clicking past. It is the cheapest security habit there is. This is why the same app can install smoothly in a test tenant and grind to a halt in a real one. Test tenants tend to leave consent open, and production tenants tend to close it, so the app's success has less to do with the app than with the rules around it. Once the approval is in hand, the next question is how big that approval should be. And that's where most projects get themselves into trouble. The trap of asking for too much. Everything so far leads to one habit that separates a smooth rollout from a painful one, and Microsoft states it plainly grant the app the minimum permission it needs for the operation, and nothing beyond that. Microsoft's own examples make the Gap concrete. An app that reads the signed in user's profile, needs only user read and handing it. User read write makes it overprivileged because the app never needs to change anything. Reading groups without a signed in user needs only group member read all. A calendar that's only ever read needs calendars read while calendars. Read write belongs to apps that actually schedule something. The real tension here is what happens when you ignore it because the cost is documented rather than theoretical. Granting an app more privileges than it needs is a poor security practice, in Microsoft's words, because it raises the app's exposure to unauthorized and unintended access. The same overreach carries a second cost that hits adoption. Since asking for more than necessary makes people refuse to consent, and a refused consent screen ends the rollout right there. There's a hard ceiling to which surprises people who assume permissions are unlimited. Microsoft Entry ID caps an app at four hundred permissions, and no more than four hundred of those can be graph permissions for work and school apps. Personal Microsoft Account apps are capped at thirty. If you are picturing an endless menu, it isn't one picture how this plays out in practice. A team wants SharePoint data for a quarterly report and asks for access to every site and the request lands in security review and stops. They trim the list down to the sites they actually read. Attach a short note explaining why each one is needed, and the approval moves in a fraction of the time. The permission list was the whole problem, and it was the one part they controlled. The lesson is unglamorous and it works. Ask for what the app does today rather than for what it might do someday. Because every extra permission is a question somebody has to answer before you're allowed to ship. There's a simple test you can run on any permissionless before you send it for approval. For each permission, name the exact feature that breaks without it. If you can't name one, that permission is a wish rather than a requirement, and it's the first thing a reviewer will ask you to justify. Where this breaks down. Careful permission choices get you most of the way, and they don't remove every wall. Some limits belong to the system itself, and knowing them early saves a confusing afternoon later. The first of them is easy to misread, and it wastes the most time when an app asks for the members of a group graph, can answer with a success code and still hand back almost nothing. Members whose type the app isn't permitted to read come back with little more than an identifier and their real properties arrive as empty values. The request succeeded, and the data simply isn't there, which is why the failure is so easy to miss. Then there are the permissions that carry the most weight directory access as user, all is the highest privilege. Delegated permission in graph, and it reaches nearly every operation across Microsoft entra ID directory. Read write all ranked second and directory read all is the strongest. Read only permission in that same space. Microsoft's guidance on all three is to use them only when nothing smaller will do. A narrower option exists for some situations, and it deserves a name. Resource specific consent grants an app access to one instance of a resource, like a single team or a single chat, instead of every instance in the tenant. It's supported for a subset of features such as teams, chats, and messages, and it's the closest thing to a scalpel in a model that often feels like a hammer. Scale brings its own pushback because graph slows you down when you ask to fast. When an app exceeds the limits, graph returns a throttling error instead of the data, and the global ceiling is one hundred and thirty thousand requests per 10s per app across all tenants with tighter limits underneath for individual services. The fix is to read the retry after header, wait the amount of time it names and slow down rather than hammering the endpoint. The newest wrinkle points in a promising direction for Microsoft Entra Agent ID some high risk graph permissions are blocked outright and can't be granted to agent identities at all, which tells you the platform is moving toward tighter defaults rather than looser ones. None of these limits are reasons to avoid graph, and they're the reasons so much of this gets documented rather than discovered the hard way the system tells you when it throttles, it documents its privilege rankings, and it flags the permissions it considers risky. So most of the surprises are avoidable. If you read first how this fits into your Microsoft three hundred sixty five and Azure World. All of this lives in a place you may already recognize. The app itself is registered in Microsoft Entra ID, and the consent it received is recorded there as a grant. While the mail files and team's data sit behind the door in the Microsoft three hundred sixty five and Azure services you use every day. When someone asks who approved an app, entra ID holds the answer with that picture in place. A few habits turn the theory into something workable. Keep user facing data on delegated permissions wherever you can. Reserve the app only model for the jobs that genuinely run unattended, like a nightly sync with nobody at the keyboard. Map out the permissions your project needs before you build, because discovering them during a security review is the slowest possible time to learn them. Staging helps to pilot with a small group of people first, show them what each permission does and what the app can never see. Then widen the audience once the first group is comfortable. That approach builds advocates instead of objections, and it gives you a chance to catch an overbroad request while it's still cheap to change. Write down why each permission is required in one plain sentence. That short justification is often the difference between an approval that moves and one that sits. And it's also the thing you'll want when the app gets reviewed six months later. The plumbing underneath is more familiar than it sounds. The same permission model sits under the Power Automate flows. You build the power apps connectors you add, and the copilot agents you're starting to spin up. So the habit travels with you across every tool in the platform. The order you do this in matters more than the individual steps. Decide what the app needs, write it down, get the approval conversation started, and only then build the part that depends on the access. Teams that build first and ask later spend their best weeks waiting on a consent screen instead of shipping. Governance is what keeps the habit alive through a busy quarter. Pre-Approval workflows. Clear tags on each app. Audit logs that record who consented to what, and a periodic review of permissions that are no longer needed or keep an environment from drifting slowly into over permission. What to take away. That's the whole picture. In plain terms, a permission is the privilege Microsoft Graph demands before an app can touch your data. Delegated access acts as a person, and application access acts as the app itself. The name on the permission tells you exactly how far it can reach, and an administrator holds the final yes. One question is worth sitting with for a moment. If you opened your own tenant today, which apps permissions would you want to double check first? If this made the topic feel less intimidating, subscribe to M365 FM to master the tools and the mindset shaping the future of work.