Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG/Question] Example use cases for scopes #186

Open
dom-gunstone opened this issue Mar 11, 2024 · 6 comments
Open

[BUG/Question] Example use cases for scopes #186

dom-gunstone opened this issue Mar 11, 2024 · 6 comments
Labels
question Further information is requested

Comments

@dom-gunstone
Copy link

Hi,

Firstly, thanks for the work on this project. It's going to be really useful.

Would you be able to describe some examples for where and why you would use scopes, please? The documentation describes the creation of a user_impersonation scope that allows users to consent to the application using the API as the user, but I can't think of any more use cases.

The Entra docs are particularly confusing on scopes...

Thanks.

@dom-gunstone dom-gunstone added the question Further information is requested label Mar 11, 2024
@bmoore
Copy link
Contributor

bmoore commented Mar 11, 2024

The way scopes ( https://oauth.net/2/scope/ ) are used by entra is as delegated access. By granting a client the scope on an API, it's saying that when the client application passes a user access token to an API, the user consented the client application access to the user's data regarding that scope on that API.

An example is Mail.Read in entra. If a client had the Mail.Read scope, then the client would only have permissions to get the signed in user's mail messages when passing a user access toke (read more about on-behalf-of flow https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-on-behalf-of-flow ).

This is contrary to the Application Role Mail.Read which gives the client (client credential flow https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow ) access to all Mail in the entra tenant.

Your API may act differently, but the concept would be scopes allow access to just the user's data related to the scope of access.

I'm writing from my phone and will follow up with some links.

A lot of this comes down to how you define the flow in your code

@dom-gunstone
Copy link
Author

Thanks @bmoore, that's really helpful. I think I'm struggling to apply the scope mechanism to a "real world" FastAPI example.

This is probably a terrible example (this is all in my head), but, if I had a Book API with basic CRUD operations I would create roles in Entra e.g.:

  • Reader
  • Editor
  • Admin

I can then give roles to users/groups etc. and have the FastAPI app check for roles.

For scopes would I define them like this?:

  • Books.Read - Allow the app to read books
  • Books.ReadWrite - Allow the app to read and write books
  • Books.Write - All the app to write books

Is this correct?: The scopes define what the user has consented the application to do on their behalf. The roles are what "Entra admins" have decided a user has access to. Scopes are a subset of permissions, a user may have many but only allow one.

Does using scopes in the Book API example even make sense? Consenting to user personal information intuitively makes sense, but consenting to reading/writing book information doesn't since it's not necessarily the user's data?

@bmoore
Copy link
Contributor

bmoore commented Mar 11, 2024

To answer your questions, yes it makes sense to me, if the books are "owned" or "shared".

A quick way to think about it: Roles for a user on an api can play a part in defining what permissions a user has on that API. Scopes are the consenting piece from the user to share the users API permission with the client.

In your case, a user with the Reader Role on the API might only be allowed to read 2 books in the whole collection with licensing policies.

Some book reading UI client that works with your Book API could be granted Book.Read by the user. The, when the UI client goes to fetch books, the API sees the consented scope, parses the user token, sees the role, gets books where the user is licensed to read, and returns the books.

Consider a change from "Book" to "Document".

Quick response from top of my head. User roles can be seen more like application roles where it provides RBAC authorization to resources at large. Scopes would likely have more specific names, if you wanted to grant granular access (read vs readwrite) but the difference, from my understanding, comes down to checking whether the user is authorized to access a given resource.

Consider a Document. If a client makes a read call to an API's document endpoint on behalf of the user, the API checks roles and scopes. The API can(read should) check whether a Document scope exists on the token before getting documents. If there's a document.read scope, then when processing the request, the API should make sure the user owns (or otherwise has) access to the document by some policy you define.

Part of that policy could be checking for a user role, maybe something like Document Admin that allows the user to read and write all documents. But on the case that their role is just User, the API would check for owner / share rights.

I hope that's a decent example. Just spinning from the top of my head

@dom-gunstone
Copy link
Author

That's great information, thank you! It's much clearer in my head now.

I think the docs example through me off a bit with user_impersonation. In you opinion, is there a need for this if I have more granular scopes?

@bmoore
Copy link
Contributor

bmoore commented Mar 11, 2024

If someone knows the details, please chime in, but from my experience, you don't need that scope if you plan on using others.

user_impersonation to me represents all possible scopes the API can offer. So if you had lots of scopes that would overload the token, and you had a super client (i.e Azure Portal) that uses all of them, maybe user_impersonation would be a useful scope.

@sstorey-bma
Copy link

sstorey-bma commented May 22, 2024

Is it possible to use the library to authenticate, BUT then inject the scopes allowed for an user (post authentication from Azure). If possible, we would want to manage user roles/groups/scopes outside of Entra (and stored within our application so we can segment this across environments etc), but authenticate the user with Entra. Any thoughts/ideas on how we could achieve this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants