top | item 43466221

Gatehouse – a composable, async-friendly authorization policy framework in Rust

76 points| hardbyte | 11 months ago |github.com

28 comments

order

jzelinskie|11 months ago

This project looks like a very nice lightweight way to implement policy in a Rust application; I really like the ergonomics of the builder. Despite being very different systems, the core permissions check being the same signature as a call to SpiceDB[0] (e.g. the subject, action, resource, and context) shows the beauty of the authorization problem-domain regardless of the implementation.

I would like to add some color that a policy engine is not all you need to implement authorization for your applications. Without data, there's nothing for a policy engine to execute a policy against and not all data is going to be conveniently in the request context to pass along. I'd like to see more policy engines take stances on how their users should get that data to their applications to improve the DX. Without doing so, you get the OPA[1] ecosystem where there are bunch of implementations filling the gap as an afterthought, which is great, but doesn't give a first-class experience.

[0] https://spicedb.io

[1] https://openpolicyagent.org

gneray|11 months ago

Agreed! But you're glossing over the Zanzibar point of view on this topic, which falls back to dual-writes. That approach has a lot of downsides: "Unfortunately, when making writes to multiple systems, there are no easy answers."[0]

Having spoken with the actual creators of Zanzibar, they lament the massive challenge this design presents and the heroics they undertook over 7+ years at Google to overcome them.

By contrast, we're seeing lots of the best tech companies opt for approaches that let them leave the data in their source database wherever and as much as possible [1]

[0] https://authzed.com/blog/the-dual-write-problem

[1] https://www.osohq.com/post/local-authorization

I'm founder of Oso btw.

Thaxll|11 months ago

Is it standard to have 2k+ loc in a lib.rs file? I'm looking at Rust code and it seems that everything goes in there. People usually don't break that down?

klysm|11 months ago

I used to think big files were a problem but I've come to like them more as the years go by. I don't have to wrap my head around some organization scheme which might be half baked - it's all right there.

hardbyte|11 months ago

Nah, I think your intuition is correct it should be broken up.

mdaniel|11 months ago

command-f "license" :-(

I do see <https://github.com/thepartly/gatehouse/blob/v0.1.2/Cargo.tom...> but my experience with package manager license declaration is that it is almost always "yeah, yeah, default, whatever" versus an explicit choice. They are also invisible to the GitHub license widget, which places the burden upon the user to go spelunking around in the code to know for sure

hardbyte|11 months ago

I did put licence = "Apache-2.0" in the Cargo.toml but Partly is okay with it being MIT. Update the repo to explicitly add the license text now. Thanks for the call out

rendaw|11 months ago

Does cargo have a default license?

codetrotter|11 months ago

What is the advantage of having the policy checking be an async function? From a brief look (framework itself and one of the examples provided in the examples directory) it seems that you’d typically be doing all I/O operations up front before invoking the policy checker, and that doing the policy check does not itself involve any I/O.

I only looked over the code quickly so I’m probably overlooking something.

It would be neat to get the motivation for each of the functions that are async being async instead of just “normal” functions.

vlovich123|11 months ago

The examples just don't show any I/O but you could easily imagine that the actual policy check is done by a different service which lives across an I/O boundary or involves DB lookups to validate if the action on the given resource by the subject within the given context is allowed.

mparis|11 months ago

Very cool project. I’ve used the cedar crate for similar use cases in the past but it’s always bugged me that it requires writing the policies in yet another language.

Will definitely check this out.

jzelinskie|11 months ago

A separate policy language is explicitly useful for those that want to be able to reuse policies in programs written in different languages. It's a part of the best practice (for larger orgs/products) for decoupling authorization logic and data from your application codebases.

When you're just hacking something together, you're totally right, it might as well be Rust!

hardbyte|11 months ago

Thanks! I'm a big fan of Cedar and DSLs such as CEL and gorules. Hopefully there is a place for a Rust solution as well.

esafak|11 months ago

What's the persistence layer?

klysm|11 months ago

I love that this _doesn't_ have a persistence layer. Authorization _should_ be just a library

hardbyte|11 months ago

BYO persistence

hardbyte|11 months ago

async-friendly Rust native library with decision traceability.