HNHacker News
TopNewBestAskShowJobs

jschorr

175 karma · joined March 14, 2012

submissionscomments
jschorr··on Better Auth is joining Vercel
The main pain points around using a Zanzibar-like approach (typically called Relationship-based access control) are:

(1) The need to write relationships and keep them updated in the permissions database. Often, this requires writing to both the application database and the permissions database, at the same time. On the SpiceDB side, we provide a Postgres FDW [1] to make this easy IF your application data lives in Postgres

(2) Representing complex permissions in ReBAC schema can be a challenge (at first) if you're coming from an ABAC system - you need a slightly different mental model for ReBAC, where (as its name implies), permissions are reachable via the relationships between objects, rather than attributes on objects.

(3) ACL-aware searching: this is a very hard problem in authz in general and gets slightly harder with ReBAC. The separation of the search index and the permissions database makes it harder to integrate and computing permissions, at scale, is incredibly complex. For SpiceDB, we have Materialize to help solve this problem [2].

[1] https://github.com/authzed/spicedb/tree/e9d636d2b58dd9e92c44...

[2] https://authzed.com/docs/authzed/concepts/authzed-materializ...

Disclaimer: I'm CTO and cofounder of AuthZed and we build SpiceDB (https://spicedb.io), the most scalable OSS implementation of Zanzibar

jschorr··on Permission Systems for Enterprise That Scale
Sweet! I'd love to see it, if you have a link, or throw it in our Discord [1]!

[1]: https://discord.com/invite/GBeT3R4k84

jschorr··on Permission Systems for Enterprise That Scale
Google's Zanzibar actually does both: for the vast majority of queries, it uses significant levels of caching and a permitted amount of staleness [1], allowing Spanner to return a (somewhat stale) copy of the relationship data from local nodes, rather than having to wait or coordinate with the other nodes.

However, some deeply recursive or wide relations can still be slow, so Zanzibar also has a pre-computation cache called Leopard that is used for a very specific subset of these relations [2]. For SpiceDB, we called our version of this cache Materialize and it is designed expressly for handling "Enterprise" levels of scale in a similar fashion, as sometimes it is simply too slow to walk these deep graphs in real-time.

[1]: https://zanzibar.tech/24uQOiQnVi:1T:4S [2]: https://zanzibar.tech/21tieegnDR:0.H1AowI3SG:2O

jschorr··on Permission Systems for Enterprise That Scale
We actually have users that synchronize their resources from various sources (AWS, Kubernetes, etc) into SpiceDB, explicitly so they can perform these kinds of queries!

One of the major benefits of a centralized authorization system is allowing for permissions queries across resources and subjects from multiple different services/sources (of course, with the need to synchronize the data in)

Happy to expand on how some users do so, if you're curious.

jschorr··on Permission Systems for Enterprise That Scale
In SpiceDB, this is known as the LookupResources [1] API, which returns all resources (of a particular type) that a particular subject (user in this case) has a particular permission on.

We have a guide on doing ACL-aware filtering and listing [2] with this API and describing other approaches for larger Enterprise scales

Disclaimer: I'm the co-founder and CTO of AuthZed, we develop SpiceDB, and I wrote our most recent implementation of LookupResources

[1]: https://buf.build/authzed/api/docs/main:authzed.api.v1#authz... [2]: https://authzed.com/docs/spicedb/modeling/protecting-a-list-...

jschorr··on Microservices should form a polytree
Dealing with lists is complicated with ReBAC, but possible. See my other comment on this: https://news.ycombinator.com/item?id=45662850
jschorr··on I built a faster Notion in Rust
I'd start with reading the Zanzibar Paper. We built an annotated version [1] that provides additional guidance on some of the denser sections and how we interpreted them.

Then, I'd take a look at the history of SpiceDB [2] for how we developed the system over time.

Finally, if you have any questions, feel free to jump into our Discord [3] and ask: we're happy to answer!

[1]: https://zanzibar.tech/ [2]: https://spicedb.io [3]: https://discord.gg/spicedb

jschorr··on I built a faster Notion in Rust
It is actually slightly worse than even that: while New Enemy [1] is the primary concern, caching like this can also introduce a staleness issue from the other direction: let's say a user adds a new row or document, and immediately sends the link to their coworker... who tries to load that piece of data, but the (stale) access control dataset is cached and they are not in it... they get a "no access" error. While certainly fail safe (vs fail dangerous for New Enemy), it can be a fairly important UX concern as well.

Generally, the solution is to keep a timestamp of when the data changed (Zookies as you mentioned) or you can proactively reload or recompute the cache when the underlying data changes (sometimes in very smart ways), but yeah: it adds significant complications over a "simplified" approach to Zanzibar.

Disclaimer: I'm the cofounder and CTO of AuthZed and we develop the SpiceDB [2] and Materialize [3], which have quite a bit of logic around these exact problems

[1]: https://authzed.com/blog/new-enemies#the-new-enemy-problem [2]: https://spicedb.io [3]: https://authzed.com/docs/authzed/concepts/authzed-materializ...

jschorr··on We rewrote OpenFGA in pure Postgres
Happy to answer any other questions :D
jschorr··on We rewrote OpenFGA in pure Postgres
> I remember building a project where we kept a mapping table of users to permissions for quick lookups, but man, it got messy with data updates.

Yep, as I mentioned above, its not an easy problem but once it is solved for you, it becomes "just" watching the events and performing the JOINs.

> especially if we could create an extension for other databases

See my video I linked above about the Postgres FDW: It does exactly this for SpiceDB and works seamlessly as-if there is a denormalized permissions table sitting in your Postgres, while still supporting the full array of complex authorization rules found in ReBAC.

jschorr··on We rewrote OpenFGA in pure Postgres
Reconciling externalized authz with search is actually quite a challenging problem. For standard externalized authz, the recommendation is some form of pre-filtering or post-filtering [1], for which we actually built LookupResources (pre-filtering) and CheckBulkPermission (post-filtering) into SpiceDB.

However, as you mentioned, life is easier when the main database can handle everything, so we actually built a solution in that space called Materialize [2], which heavily denormalizes the authorization data and allows for joining within application databases such as Postgres. My colleague Evan actually put together a really cool video about using it with Gitea [3].

Recognizing that even with Materialize, however, the need to consume events can be a bit annoying, I've been doing some work to allow Postgres itself to do native JOINs against SpiceDB (and other operations). I demo it briefly in our recent announcements video [4] and I think it effectively solves this problem within Postgres, while still allowing for all the benefits (scale, performance, redundancy, distribution) of externalized authz.

[1]: https://authzed.com/docs/spicedb/modeling/protecting-a-list-...

[2]: https://authzed.com/products/authzed-materialize

[3]: https://www.youtube.com/live/u3i1SEd9Ll8?si=mCz5mZterxthoEwj

[4]: https://www.youtube.com/live/uz_gxz3whS0?si=g4NUZAIltYVyFzYj...

Disclaimer: I'm cofounder and CTO at AuthZed and we build SpiceDB and Materialize

jschorr··on Docker Hub Is Down
We actually originally pronounced it as "kway" (the American pronunciation we had heard) but then had a saying we'd tell customers (when asked) of "pronounce it however you please, so long as you're happy using it!" :)

Source: I co-founded Quay.io

jschorr··on The Day Benjamin Franklin Broke Our CI
An amusing story of how I spent my Monday afternoon debugging a failure in our CI that mysteriously appeared over the weekend
jschorr··on Open sourcing the SpiceDB Playground: model authz in-browser, powered by WASM
Hi HN, I'm happy to announce the open sourcing of the SpiceDB Playground [1], our in-browser playground for developing and testing authorization systems for SpiceDB, our open source implementation of Google Zanzibar.

In a previous HN post [2], we discussed how we moved the playground to use WASM for running SpiceDB, massively improving performance. Today, we're happy to open source the frontend side of the playground, so that everyone can see how it works and make improvements!

[1]: https://github.com/authzed/playground [2]: https://news.ycombinator.com/item?id=32595310

jschorr··on Pains of building your own billing system
Definitely! We ourselves, in fact, use SpiceDB for our own dynamic feature flags internally.
jschorr··on Pains of building your own billing system
"Can I [action]?" is the exact question that Zanzibar[0] was designed to answer in a highly performant and scalable way.

With multiple data sources reading and writing to SpiceDB [1] (our OSS implementation of Zanzibar), those questions can further be extended into "Can [subject] [action] on [resource]", which allows for supporting not just permissions, but (as you suggested) feature flags, entitlements, role-based access control and even billing-based entitlements (if the billing system's information is supplied in as relationships or dynamically via caveat context [2]).

As a concrete example, feature flags can be represented as a straightforward permission:

  definition user {}
  
  definition featureflag {
    relation enabled: user
    permission is_enabled = enabled
  }
They can then be checked directly:

  check featureflag:somefeature is_enabled user:{currentuserid}

The real power comes into play when different aspects of the system are combined, such as only allowing a feature flag to be enabled if, say, the user also has another permission:

  definition organization {
    relation member: user
  }
 
  definition featureflag {
    relation enabled: user
    relation org: organization
    permission is_enabled = enabled & org->member
  }
In the above example [3], a feature flag is only enabled for the specific user if they were granted the flag and they are a member of the organization for which the flag was created. While this is somewhat of a constructed example, it demonstrates how combining the models can be used to grant more capabilities.

With caveats [2], these kinds of questions can even depend on dynamic data, such as the time of day, whether the user's account balance is positive, or even be random based on some distribution (to enabled, for example, partial enablement of feature flags)

[0]: https://zanzibar.tech/ [1]: https://spicedb.io [2]: https://authzed.com/docs/spicedb/concepts/caveats [3]: https://play.authzed.com/s/eML6cLz9ByAZ/schema

Disclaimer: I'm CTO and a cofounder at AuthZed, and we build SpiceDB

jschorr··on AWS Creates New Policy-Based Access Control Language Cedar
Indeed it is! :)
jschorr··on AWS Creates New Policy-Based Access Control Language Cedar
Zanzibar is an authorization system Google built and describes in a paper [1], which uses relationships to make authorization decisions (aka ReBAC): if there exists a path of such relationships between a resource's permission and, say, a user, then the user is considered to have that permission on the resource. This structural approach to permission checking allows for high levels of scaling and low latency on checks.

Disclaimer: I am the cofounder of AuthZed, where we are building an open source version of Zanzibar known as SpiceDB [2]

[1] https://zanzibar.tech [2] https://github.com/authzed/spicedb

jschorr··on Google Zanzibar Through Our Eyes
If you're curious to see a Postgres-based implementation, SpiceDB has a Postgres driver: https://github.com/authzed/spicedb/tree/main/internal/datast...
jschorr··on Google Zanzibar Through Our Eyes
Exclusion (and intersection as well) provide for some very powerful computation primitives, with only a slight overhead in performance.

In addition, there is `tupleset_to_userset` [0], which can be thought of as an arrow (which is also how its defined in SpiceDB [1]).

[0]: https://zanzibar.tech/2D0HKhvxH0:0.IoJK1g_7i:4L~ses~0~1 [1]: https://docs.authzed.com/reference/schema-lang#--arrow

jschorr··on Google Zanzibar Through Our Eyes
All custom but fully open source! Code can be found at https://github.com/authzed/zanzibar-annotated
jschorr··on Google Zanzibar Through Our Eyes
Yep! Groups can be easily nested under one another by simply creating a relationship between the group's members and the members of another group.

In SpiceDB [0] schema this can be represented like so:

  definition group {
    relation member: user | group#member
  }

Here `member` allows a relationship to itself, which allows writing a relationship saying that every member of one group is a member of the containing group.

I threw together an example in our playground [1], if you'd like to try it out!

[0]: https://github.com/authzed/spicedb [1]: https://play.authzed.com/s/9D5h9I7mE9mK/schema

jschorr··on Dropping playground latency by porting SpiceDB to WASM
Author of the post :)

I did actually briefly look into it! I was hoping it would work for us, but the first time I tried to perform the compilation with it, it failed due to issues with support for at least one of the dependencies we bring in. I don't remember the exact failure as its been a few weeks, but since the bundle size went to down a manageable (but still largish) 5MB once we enabled aggressive caching, fixing our code to work with TinyGo was deemed less critical.

I very much hope to get back to it soon and see if we can move over to it.

jschorr··on Show HN: Permify – Open-source authorization service based on Google Zanzibar
The problem you're describing is sometimes called the "ACL Aware Indexing" problem [1]. In a permissions service based on Zanzibar, this can partially be solved by walking the permissions graph in a reverse fashion: SpiceDB exposes this API as the LookupResource API [2]. However, even this approach has performance implications for very large datasets, so we're also working on improving resource lookup via a LookupWatch API [3], which can be used by consumers to actively cache the available set of resources as access changes over time.

[1]: https://authzed.com/blog/acl-filtering-in-authzed/

[2]: https://buf.build/authzed/api/docs/main:authzed.api.v1#authz...

[3]: https://github.com/authzed/spicedb/issues/207

jschorr··on SpiceDB Is Open Source
Disclosure: I'm also a founder of Authzed

The information you are describing can be retrieved via the Expand API [0], which returns a tree containing all of the relationships that are reachable from a permission, as well as how they were reached.

For example, if you have a schema with a permission like so:

    definition resource {
      relation parent: resource

      relation writer: user
      relation reader: user

      permission view = reader + writer + parent->view
    }
An ExpandPermissionTree call for the permission `view` on a resource will return a tree that contains the users with view access to that resource, each set of users placed under `reader` or `writer` with a reference to the containing resource, so you know how a user was granted the `view` permission.

[0]: https://buf.build/authzed/api/docs/main/authzed.api.v1#Expan...

jschorr··on Ory Keto, open source authorization server based on Google Zanzibar
Hi Nick,

In the case of Authzed, we provide a gRPC API [0] which can be used from any application or language that supports gRPC, as well as designed client libraries for specific languages [1] to make integration even easier.

Applications primarily integrate by making Check requests [2] at any point in which a protected resource is being accessed and Write requests [3] at any point in which permissions are granted or removed.

Source: I am the third cofounder at https://authzed.com :)

[0]: https://docs.authzed.com/api/overview

[1]: https://docs.authzed.com/lang/lib-index

[2]: https://docs.authzed.com/api/check

[3]: https://docs.authzed.com/api/write

jschorr··on Launch HN: ShareWith (YC W21) – Easily share internal websites securely
In theory, you could provide an auth header representing your incoming user to our API and verify that way, yes. You'd still need to perform authentication (using Auth0 right now, as that is what ShareWith uses) to identify which user is hitting your application, but then the authorization check could be done via the API.
jschorr··on Launch HN: ShareWith (YC W21) – Easily share internal websites securely
For now, some form of proxy is required (unless your application supports OIDC already, in which case, you can just point it to our OIDC endpoint), but we are currently investigating ways to streamline this process even further. Stay tuned!

Edit: We provide copyable instructions in-app for running OAuth Proxy via Docker, so that should reduce the initial setup time down a bit

jschorr··on Launch HN: ShareWith (YC W21) – Easily share internal websites securely
We've actually integrated with our Kubernetes ingress to protect our own dashboards via ShareWith. Right now, our "Usage" tab shows how to setup oauth proxy or use via OIDC directly, but we're looking into expanding the examples for Kubernetes and other common use cases
jschorr··on Docker update ToS: Image retention limits imposed on free accounts
Not at all!

I thought I'd just give some interesting background info and not so subtly ask people to contribute to the project :D

Page 1 of 2Next →