Hacker News new | past | comments | ask | show | jobs | submit | samjs's comments login

Hey jdenquin, author/Oso cofounder here.

I'm obviously biased, but IMO the benefits of using a language over SQL is:

* Ability to write reusable logic (rules)

* Support for inline policy tests

* Abstracted from the data model, so easier for collaboration and distributing across multiple applications


Hey all!

I'm Sam, cofounder + CTO at Oso.

Thank you all for the great discussions going on here. If folks are interested in either learning more about the product or working on these kinds of problems, you can email me directly at sam [at] osohq.com.


Hey cratermoon, Oso CTO here.

I'm probably too close to it, so I'm not following: "a great many of the problems they are solving exist because of RBAC"

Oso supports authorization using any combination of RBAC/ReBAC/ABAC you want.

If anything, I would say that sticking with RBAC is the "easy way" to do it, but you push the complexity of managing it onto your end users (the ones who need to administer it). Whereas building authorization that uses attributes like you describe requires more implementation work, but can make the experience easier for users.

Am I understanding you correctly?


All of the examples given mention roles and users. There's no discussion about the attributes of the subjects and objects as first-class entities.


That's a really clean implementation. And the shares are used to resolve authorization here [1], right?

Two things that we're solving for at Oso is: making it easier for multiple teams to collaborate on permissions (which we solve by having a declarative language), and solving the list filtering problem (as talked about in the post).

If you don't need either of those two things and are happy with a DIY approach, what you've shared would work great IMO. If you packaged that up as a standalone solution, I could see a lot of people getting value from it!

There are not enough people sharing authz implementations out there, a blog post on this shares approach would be super cool.

[1] https://github.com/bottledcode/durable-php/blob/3ad509fcdbb3...


> And the shares are used to resolve authorization here [1], right?

That's correct!

> making it easier for multiple teams to collaborate on permissions (which we solve by having a declarative language), and solving the list filtering problem (as talked about in the post).

Those are pretty hard problems, so it's really cool to see someone solving it in a reusable way! For me, authz is always a chore ... making it something easy to specify in a way that "just works" is worth quite a bit in my mind!

> If you packaged that up as a standalone solution, I could see a lot of people getting value from it!

I don't really have much desire to get into maintaining an auth library; there's just not enough time in the day!

> a blog post on this shares approach would be super cool.

It's pending publish, actually! I've got a devlog (more like a book at this point) for something I've been working on for years now, but no posts are going to be published until I hit a milestone. I'm almost there... not much further.


> I don't really have much desire to get into maintaining an auth library; there's just not enough time in the day!

Haha, well in some ways I'm glad to hear that. That's why we exist :)

> It's pending publish, actually! I've got a devlog (more like a book at this point) for something I've been working on for years now, but no posts are going to be published until I hit a milestone. I'm almost there... not much further.

Send it over if you want another pair of eyes, and lmk when publishing so we can share with our community too. I'm sam [at] osohq.com


This sounds really elegant, I love it. Have you seen this deployed in a service-oriented architecture or primarily integrated as part of a single app/db?


Both. Usually the service has a table of "shares" and the owner(s) attached to the actual row. Thus determining if a user has a right to do something looks like this:

    select 1 from kites k 
    join shares s on (s.model = 'kites' and :operation in s.rights)
    where :user in k.owner or s.user = :user
or something like that.


(Oso CTO here). Out of curiosity what do you not like about CASL? It always seemed to have a similar goal in mind which I loved, but I suspect it hit similar challenges we had when replying on ORM integrations.


One big annoyance is including attributes beyond the target (which CASL calls the subject). There may be a plethora of environmental factors I want to evaluate in my rule. The two obvious options are:

1) build the rules programmatically, based on what you observe in the request context. This works fine until you want users to be able to create and assign custom policies and load them from a database.

2) put placeholders in the rule’s conditions, and swap them with the current contextual values when rehydrating the rules for a given request. Fine, except this obviates caching except for the raw rule from a database, and rehydrating dozens or hundreds of rules for every request starts to add up in terms of overhead.

I wish rule conditions could reference a “context” parameter (name not important) so I could create a condition like {userId: context.user.id} and at runtime I could pass the current context when I call can. That way I can rehydrate the rule once. I realize this creates all sorts of complications with serializing a rule to be stored in a database or sent over the wire, but that’s where some special placeholders could be understood natively by an Ability and hooked into a passed in context. However, that still creates an issue if I want to create a condition that is purely based on context ( e.g. {context.user.isTrialUser: false} )

The other thing I have been struggling with is that can with a subject name only (rather than an instance) will match a rule with no conditions along with rules that have matching conditions. I understand the author’s rationalization, but can potentially create unexpected results particularly when you offer a system that lets users build their own policies.

The last issue is CASL is nodejs only and I may need to support multiple platforms. I’ve looked at Casbin because of its multiplatform support and customizable model, but I’ve found it extraordinarily hard to use beyond simple RBAC or claims-based authorization, and it still doesn’t offer solutions like conditions-to-query filters or field-level authorizations.


Thanks for the extensive comment. I had similar experiences with CASL. I implemented the placeholders you described with support for arbitrary context. It also supported joins. It used a mongodb-like syntax that could be used with SQL, mongo, dynamodb or generate an in-memory filter function. Im glad to see others in this thread coming to similar conclusions. My design was similar to the OASIS model.


Ah got it, thanks for sharing! That's definitely context I'm missing from having never used it in an actual application.


Hey simon! Oso CTO here.

Definitely one of my favourite problems too! Some additional context for those who don't think about this all the time: in many cases, the solution is as simple as "write some SQL where clauses to do the filtering I care about". e.g. I suspect the vast majority of people have logic like `where tenant_id = ?` or similar and they pass in a tenant ID on every query.

Where things get challenging is when you want to decouple the logic (e.g. have an abstraction in your code, or centralize logic in a service). Because then you're in the world of what's the decoupled API that allows me to filter my database.

The easiest way to do that is just generate return a big list of IDs the user can see, and put `id in (... list of ids)` on the query. But that involves (a) syncing the data to the central service and (b) that list can get pretty long.

And so that's why you would even need to think about turning rules into WHERE clauses in the first place :)


> However: you seem to target developers. Why do you force me to leave my IDE and use your "rules editor"? Can I not write all those things in my IDE, with all the support it brings, and integrate this into my CICD flow? (yes, there is the .polar file, but why force me to jump through hoops?)

Hey valenterry! Oso CTO here. You can absolutely write policies locally and integrate this with CI/CD. We have vscode extension for the former, and CI tools for running local dev environments and CI for running this locally or in CI or whatever.

The UI is mostly nice for getting started development experience, e.g. it integrates directly with Oso Cloud without needing to configure credentials.

> Then, why did you create a new DSL and not a merely a (de-)serializable datastructure (which will indeed look like a dsl)? One, that is powerful enough to represent the capabilities you need. Then, I could in fact use any language (library) of my choice and create the rules from this language, which just has to create the datastructure.

We have a post on this coming soon! The short version is that Polar is a logic language based on Prolog/Datalog/miniKanren. And logic languages are a particularly good fit for representing the branching conditional logic you often see in authorization configurations.

And it made it easier for us to do custom work like add inline policy tests.

> Apart from that, I really like the `yes, if` idea! Would be nice to hear a bit more about that (unfortunately, the article pretty much ends there). Such as: how to deal with actions that change things and can (or must) potentially be run before the authorization is completed and such.

We typically recommend authorizing in two places: at the start of a request, and then when fetching data.

e.g. in our demo app, authorizing "can a user create an issue" involves authorizing a "create_issue" action against the repository itself: https://github.com/osohq/gitcloud/blob/sam/list-filtering/se...

Whereas anything listing issues calls the `list_local` method and does the `yes, if` style approach.


Hey, thx for your answer. I really like to see that you are building upon existing logic languages not totally inventing your own. I think you should market it as that, because many people (like me) have been burned by companies that thought it would be a good idea to invent a completely new language (or even DSL) from scratch.

I think you should also focus on making integration with existing code as easy as possible. I know there even is one of the more research-class PLs that has first-level support for running small prolog-like scripts within other more imperative code. Essentially that is exactly what you guys do, just natively built into the language (which obviously you guys can't do).

Essentially, if the language is simply enough, I'd like to define and build both the facts as well as the logic from within my own programming language, rather than having to use your web-editor or other tooling to get support for syntax and things like that. Then, if I have a usecase where my own language is insufficient or annoying, I can still write "plain" code in your language if needed.


> We have a post on this coming soon! The short version is that Polar is a logic language based on Prolog/Datalog/miniKanren. And logic languages are a particularly good fit for representing the branching conditional logic you often see in authorization configurations.

Ha, I've been playing around with Biscuits (https://www.biscuitsec.org/) and was writing up a blog post on using them in a git forge. When I saw the Polar data units described as "facts" and read your end to end example (https://www.osohq.com/docs/tutorials/end-to-end-example) I thought "Oh this looks very similar". I will say - I do like how Polar seems to type stuff and provide some concepts that Biscuits force you to build out on your own, that's pretty neat.

What is the proof of identity in Polar? Is it something like a token in Biscuits? I'm curious if you can do things like add caveats to reduce what the token is capable of as it gets handed off to different systems. I consider that one of the "killer use cases" of biscuits.


Biscuits are really cool, one day I plan to try and convince Geoffroy to integrate Polar for policies :)

Currently Biscuits + Polar are ideologically similar but with distinct use cases at the moment. Oso is a central service that your backend speaks to whereas biscuits are decentralized cryptographic tokens.

So Oso API calls are all done with service-specific API keys, and don't need a proof of identity beyond that.

My mental model for tokens like biscuits is that they work like a "decentralized cache". I.e. you can take an authentication/authorization decision, sign it, and provide it to a client. They can reuse that decision at services without the service needing to reach out to the authN/authZ provider again.

It would play _really_ nicely together with the Distributed Authorization concepts we're talking about here: a client could ask the authz service: "I want a token for managing issues". The authz service/Oso could respond with a partially evaluated policy, like: "this token grants the user access to issues that belong to repository 1, 2,3, or issues that they are the creator" (encoded as facts to check a la biscuits).

When receiving that token, the issues service would know what filtering to do locally, without having to reach out to Oso.

The information passed around between the services mostly stays the same, but rather than make an API call each time, the necessary authz information is encoded in the biscuit token.

And then next level: biscuits can cross federation boundaries and be attentuated, etc. So it really starts unlocking novel ways to integrate application-level authz with infrastructure-level authz.


Biscuit maintainer here o/

There's definitelt some cool use cases we could collaborate on. One thing I'm looking at more deeply right now is tokens carrying the necessary data as they go through the system,to make sure one call does not see some of it rights change dynamically when going from service to service


Quick addition: in practice everyone that I know uses Git + CI/CD for managing + deploying policy changes.


Hey all!

Here's a feature I worked on recently at Oso -- it's a little UI for building example policies combining different authorization features.

I thought folks here might like it. It feels like there's been some growing excitement around logic languages, and our language Polar is inspired by a combination of prolog, datalog, and miniKanren! The builder shows a few examples of what's possible with that approach. Happy to answer any questions.


Thanks epberry!


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: