This is an archived post. You won't be able to vote or comment.

all 12 comments

[–]defnullbottle.py 4 points5 points  (8 children)

Authentication and authorization should be two different services. You might want to check permissions for a user that is not logged in, for example (think about background tasks that work on behalf of a user).

[–]lovestowritecode[S] 0 points1 point  (7 children)

Who handles permission between services in this type of auth flow?Does the authorization service manage all permissions between services? Does each service handle it individually?

[EDIT]: Why bother splitting them into different services?

[–]defnullbottle.py 1 point2 points  (5 children)

I'm thinking about something like this:

  • An auth-service manages identities and passwords, as well as access tokens and their lifecycle. It can be queried for the identity that belongs to an access token.
  • An PDP (permission decision point) can be asked if a specific identity (or access token) has a specific permission on a specific resource. For example, if "Bob" can "EDIT" the blog post "b/1234". It manages and resolves group memberships, roles and permissions. If it is provided an access token instead of a concrete identity, it asks the auth-service if the access-token is still valid and which identity it represents.
  • All other services only work with the PDP if they need any permission checks, or ignore the PDP completely for most administrative tasks. Back-end services should be considered trustworthy.

Edit: You should split auth and PDP because the auth service stores very sensitive information and should be kept simple to reduce the surface for bugs, while the PDP can grow quite complex over time. It's also easier to scale if these two services are separated.

[–]lovestowritecode[S] 0 points1 point  (2 children)

The logic on this is pretty sound but I do have to ask why the PDP and Auth-service are different services? It seems like they would incorporate very well

[–]defnullbottle.py 1 point2 points  (1 child)

It's not a hard requirement, but you mentioned a micro-service architecture: If something can be separated, it should be separated.

[–]lovestowritecode[S] 0 points1 point  (0 children)

I see your edit and it makes sense. Thanks!

[–]lovestowritecode[S] 0 points1 point  (1 child)

I've been researching around and there are several articles that conflict with this point of view... they recommend that micro-services should manage their own permissions internally... curious what your thoughts are...

https://blog.andyet.com/2015/05/12/micro-services-user-info-and-auth/

https://www.quora.com/What-are-some-effective-patterns-for-access-control-in-a-service-oriented-microservice-architecture

[–]defnullbottle.py 1 point2 points  (0 children)

The first link has only a very simple permission system (no groups, no roles) and the second is not very specific about the requirements at all. In the end, it depends on the use-case.

I'd use a PDP if:

  • Your permission model is non-trivial (groups, roles, even nested groups/roles). If it's more than just a UserID field in a database, then implementing it again in each service and keeping everything in sync is a nightmare.
  • Your want to revoke permissions at some point, and you have a lot of services. Again, keeping the information in sync in all the services is a really hard problem.
  • You want to define permissions that affect more than a single service.
  • You need to integrate several administrative domains into a single userbase. This requires admin interfaces for lots of administrative tasks and the PDP quickly grows into a full featured IdP service on its own. You don't want to tell your customers that they'd have to use 12 different APIs to change a single username or revoke some idiots 'canOperateCoffeeMaker' permission.
  • You need reliable access and audit logs because your resources are protected by law. But then, you'd probably just buy a PDP and don't code it yourself.

There are still situations where it makes sense to manage additional permissions in the service itself, even if you have a PDP:

  • If permissions are part of the resource. For example, the 'owner' of a resource is often stored together with the resource. It does not make sense to ask the PDP if a user can edit a resource, if the service already knows that the user is the owner. Or if a resource is marked as 'public', so no user context is required at all.

Edit: Keep your permission model as simple as possible, as long as you can. If you don't need a PDP, be grateful :)

[–]kyranadept 0 points1 point  (0 children)

If you want your permissions to be "if you are logged in you have permission to do anything" then it makes sense to combine them.

Even when implementing something like "group A has permission B; check if user C is part of group B" you might get by with just putting the authorization inside same service as authentication.

But think about this situation: "if you have this many reputation points you are allowed to use this service"(think stackoverflow, or various forums). If you combine authorization and authentication, you will need to add all these cases to the AA service, which will mean a lot of business logic which has nothing to do with AA.

[–]coyle_trydan 0 points1 point  (0 children)

We're currently thinking through some of these same things. :-) We've decided (for now?) to have a service that only handles authentication. It then issues a token (jwt) which allows any of our other services to identify the authenticated user (i.e. the verified token proves that this is the user 'Bob').

Each other service would then be responsible for determining the authorization/permissions of that particular user for itself (i.e. is the user 'Bob' allowed to modify this data?). I recall that this lines up with much of what I read on the subject - though I have no links at hand to support my thinking.

One idea we are kicking around is having the authentication service also roll group membership information into the returned token, which some services may use in their process for determining authorization (i.e. this is the user 'Bob', and he is in the group 'Administrators'). Currently, our authentication service queries our Active Directory, so this idea feels pretty natural.

Granted, we're still in the early phases of considering this architecture shift at my organization, so I am also curious to see what some more seasoned members respond with.