[HN Gopher] Authorization in a Microservices World
___________________________________________________________________
Authorization in a Microservices World
Author : zaplin
Score : 147 points
Date : 2022-04-01 15:11 UTC (7 hours ago)
(HTM) web link (www.alexanderlolis.com)
(TXT) w3m dump (www.alexanderlolis.com)
| xvinci wrote:
| > "Direct DB reads, outside the domain of each service, is a bad
| idea and it will be obvious to you why on the first schema
| change. Please don't be lazy and just say no to this."
|
| Good read, but I am not really a fan of that stance. The
| "separate schema per ms" pattern is an overhead which has to be
| justified and even paid for by customers (small 50k projects and
| enterprise grade projects of million $). First and foremost the
| db is a shared data structure which CAN be used for communication
| and in a one actor writes and 1..n actors read scenario
| (especially when all connecting services are controlled by the
| same team) is typically the simpler and better approach as a
| start. Schema evolution will also hit you with messaging and APIs
| which can be done properly in smaller databases as well.
| mixedCase wrote:
| A single database instance can host multiple independent
| schemas. No need to pay for more. Treating a database as an API
| is more than doable, but the whole team needs to be on point
| with the necessary shift in expectations, as well as the shift
| in tooling and best practices.
| dboreham wrote:
| You certainly can have a monolith database, but typically
| you'll find that many of the Conway benefits of services will
| be lost as a result.
| emreb wrote:
| Disclaimer: I am the co-founder of Cerbos.
|
| Thanks for explaining the problem space so well and referring to
| Cerbos[1] as contextual solution.
|
| We had to build these systems in the past so many times and we
| were tired of reinventing the wheel. With Cerbos we aim to turn
| this problem space into configuration rather than code and enable
| enterprise-grade access management for any application.
|
| [1] https://cerbos.dev
| tored wrote:
| To handle direct database read by multiple micro services you can
| create views for the different type of authorization checks you
| need to do.
|
| If schema need to change you just update the view.
| DIVx0 wrote:
| I've been using Open Policy Agent for this scenario with great
| success. You can either use it in a AZ as a service setup or
| embed it into middle ware for a sort of "decision making"
| library.
| mkdirp wrote:
| As in OPA determines if a user has access to a resource? Do you
| have some resources on how to do this?
| ogazitt wrote:
| You do need to have a strategy for how to load the resource
| mappings into the OPA engine. If they don't change very much
| you could embed them in the data.json file of the OPA policy
| itself. But more often than not, that data is changed often
| (e.g. when someone grants someone else access to a resource).
| In that case, you'll need the OPA engine to query an external
| data store via an HTTP request. Or you can use a resource
| cache, the way we do at Aserto.
|
| Here's a blog post [0] about the challenges we faced when
| using OPA for application authorization.
|
| [0] https://www.aserto.com/blog/the-challenges-of-using-opa-
| for-...
| qbasic_forever wrote:
| OPA has a whole policy language to define how people have
| access to resources however you please. See details here:
| https://www.openpolicyagent.org/docs/latest/policy-language/
| samjs wrote:
| Love this article. My favourite part is:
|
| > "So the logical thing to do is to implement an authorization
| service and everybody would be able to use that and keep your
| precious service boundaries, right? WRONG. Your hell, has just
| begun!
|
| Drawing the right boundary for authorization is near impossible.
| If I want to check whether the user is allowed to see who left an
| emoji reaction on a comment response to an issue inside a
| repository belonging to an organization -- do I store that entire
| hierarchy in my authorization service? Or do I leave some of that
| in the application? I've yet to see a good heuristic for the
| latter.
|
| Also, thank you to the author for referencing us :) I'm Sam,
| Cofounder/CTO at Oso where we've been working on authorization
| through our open source library for the past couple of years.
| Authorization for microservices has been a recurrent theme over
| that time, and we've been furiously writing on the topic (e.g.
| [1], [2], [3]).
|
| We'd be interested in talking to anyone who is currently facing
| the challenges of authorization for microservices (or really just
| multiple services). We're building authorization as a service,
| which you can learn more about here: https://www.osohq.com/oso-
| cloud. It's currently in private beta, but if you would rather
| _not_ speak with us first, there's also a free sandbox to try out
| the product linked from that page.
|
| [1]: https://www.osohq.com/post/why-authorization-is-hard
|
| [2]: https://www.osohq.com/post/microservices-authorization-
| patte...
|
| [3]: https://www.osohq.com/academy/microservices-authorization
| jkaptur wrote:
| What an evocative example! Before reading your links (sorry!
| They're long. I added them to Pocket), I just don't see how
| "allowed to leave an emoji reaction to an issue inside a
| repository belonging to an organization" could be anything but
| _application logic_. That is, _all_ of the logic should be in
| the application (except authentication). Every noun in the
| sentence is application-specific! Perhaps the organization has
| repository-specific blocked-users lists, and disallowed-emoji
| lists, and (in the application) repo owners can modify the
| disallowed-emoji list (subject to approval from the
| organization owners, of course!).
|
| It seems like building a service that tries to abstract all
| that (the emoji is an "attribute" of the "action" to a "object"
| that has an "owner" that has "rules") is doomed to succumb to
| the inner platform effect. The only solution I can see is to
| build a general rules engine, but, in my experience, those tend
| to just be complicated, hard-to-read ways to implement logic
| that should just be code.
| samjs wrote:
| > I just don't see how "allowed to leave an emoji reaction to
| an issue inside a repository belonging to an organization"
| could be anything but application logic.
|
| I think it's absolutely fair to say that authorization logic
| is a subset of application logic! The question is whether
| it's possible to separate any of the authorization logic from
| the application.
|
| There are two reasons you might want to do that:
|
| 1. Separation of concerns (true whether monolith or
| microservices) 2. You have authorization logic shared across
| multiple services.
|
| (1) is still a hard problem, but you can be a little less
| rigorous about it. (2) is where it gets really fun.
|
| Continuing the example, that repository-specific blocked-
| users lists is _probably_ going to be needed across every
| other service.
|
| I don't think any of that contradicts what you're saying,
| just clarifying that "in the application" might still mean
| you want to extract the shared logic into a service.
|
| But to get to your last paragraph: yes it's definitely hard
| to build a service that's both sufficiently generic to handle
| all the kinds of authorization use cases people typically
| need to do.
|
| You'd be surprised though at how many use cases fall into
| very similar patterns. We have some internal (soon to be
| external) documentation where we managed to get to about 20
| distinct patterns -- from the common one like roles, and
| groups, to less common ones like impersonation and approval
| flows. And most of these share the same 2 or 3 distinct
| primitives (user is in a list of blocked users for a
| repository, emoji is in the disallowed-emoji list, etc.).
|
| So you can build something less abstract than a general rules
| engine, but that still saves you the work of building from
| scratch for the nth time a roles system or a deny list.
| jagged-chisel wrote:
| But that's the difference between authentication and
| authorization - sure, you've logged in, and we can verify
| that, but now we need to know if you're permitted to do what
| you're trying to do. And yes, authorization will then have
| awareness of some amount of application/business logic.
| jsiaajdsdaa wrote:
| In the enterprise system I design/implement/maintain, I
| currently have a (!)limited set of roles for my main business
| logic service.
|
| Each task in that system has an accompanying set of roles that
| are authorized to execute it, and essentially that
| authorization happens at the controller level and is "at the
| edge" of the application instead of in the business logic
| itself.
|
| Is there a benefit I could gain from Oso? I will read what
| you've provided.
| samjs wrote:
| Honestly, if your authorization needs are coarse enough that
| you can (a) handle it as middleware at the controller level,
| and (b) mostly just rely on roles, then you're probably in a
| good place to keep going with that! It avoids a lot of the
| complexity of centralization.
|
| Where we normally see people considering Oso is when the
| model gets more complex, or the data requirements get larger.
| E.g. when you introduce new features like user groups,
| projects, or sharing, then the amount of logic + data you
| need to share between the services grows beyond what's
| sustainable.
|
| If you're current system is working for you, I'm not going to
| try and tell you otherwise! If that changes though, let me
| know ;)
| maskaler wrote:
| The best I've ever had it is using an API gateway that
| destructured a token into headers. Back end services used MTLS.
| This meant testing Auth was as simple as adding headers. No
| server needed to be up, no jwt nonsense needed to be mocked. I
| can't recommend enough keeping this nonsense at the boundaries.
| stingraycharles wrote:
| So if I understand it correctly, a service would respond with
| http headers that describe the claim necessary for the
| action? Which begs the question, how would that work with
| side effects.
|
| Or would the acquired claim be communicated towards the
| service in the request? Which begs the question, how does the
| service communicate which claim is required.
|
| Not trying to be critical by the way, genuinely curious.
| arcbyte wrote:
| I really need to write more extensively about this, but I've
| dealt extensively with authorization as a topic.
|
| The concepts are simple but the implementation can be very
| difficult.
|
| Authorization and Business Logic are two entirely separate
| domains. You have to start there. They are orthogonal.
|
| From that follows that requirements involving who you are get
| implemented in the authorization logic/service/etc, and other
| requirements get divided up into the appropriate domain
| logic/services/etc.
|
| If there are requirements around access to emojis then that
| involves the authorization service.
|
| Sometimes data needs to get duplicated across service
| boundaries and that's when you need application concepts like
| sagas to manage this. That's where the implementation starts to
| get difficult.
| samjs wrote:
| Please let me know if you do write something. I would love to
| read it!
| lukeramsden wrote:
| The way it's done at my current company is that services do
| their own minimal authorisation based on their own business
| logic, if any at all, and the rest is done by a dedicated
| "policy service" that is called by the request composer (which
| is the only service the FE calls) to do very advanced checks on
| what individual users are and aren't allowed to do, with the
| policy service being configurable through YAML "policy
| documents". It seems to work very well for the colleagues of
| mine that work on it.
| samjs wrote:
| Nice!
|
| Is the request composer responsible for checking the
| authorization data? Like what roles/permissions the user has?
| gedy wrote:
| Not the OP but we did similar and this front end
| gateway/"backend for front end" would do the roles checks,
| yes. Back end services could do course grained checks if
| needed.
| damethos wrote:
| Author here. First of all thank you for making this article
| appear in the HN frontpage. I read some interesting comments and
| approaches but I feel that a piece is always missing (or maybe I
| did not understood). The piece of how the authorization fetches
| the necessary application data it needs in order to decide what
| to do. If you do not need this piece then you can get really
| creative on how to solve authorization and use an approach that
| fits best to the needs of your system. But if you do, then I
| would love to hear more details about this part.
| kitd wrote:
| If your architecture contains Kafka, you can use Kafka ACLs to
| authorize access to any resource, not just Kafka ones. Based on a
| principal, a named resource (derived from, eg, a URL path) and
| the requested operation, the Kafka admin client can tell you
| whether there is a matching ACL that permits the request.
|
| I've had success doing this.
| avereveard wrote:
| I think this glosses on a very important part, which is just
| named in passing: "how do you actually know that bob is bob, and
| how do you trust that?"
|
| article answer is 'user role [..] attached to a JWT' but that
| only really applies if you control your distributed microservice
| system, if you need to scale to etherogeneus identities you need
| to get into the magic world of federated authorities
|
| and that is where the pain really is.
| wackget wrote:
| Am I the only one who thinks the initial PHP example is just
| fine?
|
| Seriously, you're claiming to "solve" one "problem" by building
| an entire new system which is inevitably massively more complex
| and difficult to manage than the "problem" you're trying to
| solve.
|
| Then again, I don't work in enterprise-level environments but to
| be honest if this is what it's like, I'm glad I don't.
| nycdotnet wrote:
| An interesting and well written article. I appreciated that they
| got into horizontal trimming aka field trimming, but vertical
| trimming like "this person can see all things for all objects
| except those with property X==1" is a whole separate issue with
| significant performance issues, particularly around list
| endpoints. It's hard to make a one size fits all solution here
| because sometimes the perf issue is on the frontend (which items
| can they see) and sometimes on the back end (now for a fragmented
| set of entities, fetch and return the appropriate information)
| epberry wrote:
| https://www.osohq.com/ is a very interesting company in this
| space. They have an open source authorization library, and a
| great blog.
| samjs wrote:
| Thanks epberry!
| pachico wrote:
| Please, stop posting this every 2 days.
| ryanklee wrote:
| This seems like an unfair comment. I looked at the poster's
| submission history, and it does not show what you are claiming.
| jessaustin wrote:
| TFA has been posted three times since it was published 12
| days ago. Which seems OK? I'll be more concerned if it gets
| published at a similar rate going forward, but since it got
| some upvotes and discussion this time around the submissions
| might stop. No other piece from this blog has been submitted.
|
| https://news.ycombinator.com/from?site=alexanderlolis.com
| damethos wrote:
| I was the one who posted it two times. The second one was
| an honest mistake. This third time wasn't me but I am glad
| that someone did.
| jessaustin wrote:
| Yes, TFA is definitely what we want on HN. There's
| nothing wrong with reasonable reposting. In years past, I
| had been encouraged by the actual HN moderators to
| repost.
| cyberpunk wrote:
| Which is why I wont be able to find true love and I'll die alone.
| I'll die alone, without ever knowing it's my birthday... [0]
|
| 0: https://youtu.be/y8OnoxKotPQ
| prionassembly wrote:
| It says something about the power of branding that my first eye
| scan parsed this as "Authorization in Microsoft Word".
| kache_ wrote:
| I've been working as an IAM engineer for my entire career. This
| is a really good write up on a few ways on how you could handle
| authorization, but I think it also highlights the challenges with
| it
|
| The more I come across different systems, the more I realize
| authorization in large distributed systems isn't ever one
| approach: it has to be tailored for each use case with different
| tradeoffs in mind. It's often directly coupled to the problem
| domain you're trying to solve for. It has to be integrated with
| the data access pathways, _and_ also has to be tailored to the
| authentication system it deals with, _and_ it has to be tailored
| for the data-locality model of the overall system.
|
| The more authorization problems I solve, the more I realize that
| my dream of coming up with a generalized authz SaaS service that
| helps me grease out VC money & a billion dollars probably doesn't
| really exist. It's different from authentication, because
| authentication has less dimensions of coupling, and less
| tradeoffs (Auth0 sold for 6b, Okta worth 18b, both authentication
| offerings)
|
| Maybe I'll figure it out one day. Or maybe this is one of those
| problem domains that is only solved by an army of engineers
| samjs wrote:
| Well, I potentially have some good news for you :)
|
| There are a bunch of companies who popped up in the last few
| years to solve this problem. We're one of them -- Oso (I'm the
| CTO).
|
| It's definitely a fun/challenging problem to work on. So if
| building a generalized authz SaaS is the dream, come join us!
| flutas wrote:
| Just a heads up, looks like markdown formatting got into your
| "go get" command for the golang page.
|
| https://www.osohq.com/learn/rbac-go
| samjs wrote:
| Good catch, thanks!
___________________________________________________________________
(page generated 2022-04-01 23:00 UTC)