HN user

kkajla

161 karma
Posts0
Comments33
View on HN
No posts found.
[GET] "/api/user/kkajla/stories?hitsPerPage=30&page=0": 500 Failed to fetch user stories

I prefer to have the entitlement itself just store the expiration date and the details about what entitlements the subscription grants during the time period it is active. The billing system can store the subscription and sync back to the entitlement as-needed. This makes both manual billing by human operators (not to mention debugging and patching around momentary issues) and something like a Stripe integration very easy.

Having worked with SaaS companies using our (Warrant) solution for customer entitlements [0] for the past couple years, this is the approach we arrived at as well (e.g customer stores entitlements in our system and checks against them when needed, adding rules/entitlements as subscriptions are updated/deleted with their payment provider). It makes it easier for companies to work with any (or multiple) payment providers, and there's a clear separation of concerns. Someone shared another blog post by OP about separating your billing and entitlement systems [1] below, but I'll share it here since it's more relevant within the context of this comment thread.

I think the ideal entitlement system is (1) dynamic (i.e. rules stored in a database), (2) can handle one off scenarios (for enterprise customers, etc.), and also has a policy layer built on top (so it supports almost any scenario a developer can throw at it -- e.g. pro plan supports <= 5 seats, growth plan supports X feature up to N times per day, etc). I think it's also a huge benefit to have a UI where non-technical folks can make changes for customers without needing to involve engineering (which was always a drag on engineering in my prior roles as an engineer).

[0] https://warrant.dev/use-cases/pricing-tiers-and-entitlements... [1] https://arnon.dk/why-you-should-separate-your-billing-from-e...

I would describe this debate more as Policy-as-Data (Zanzibar) vs Policy-as-Code (OPA et al).

In Zanzibar, all of the information required to make an authorization decision (namespaces, relationship tuples, etc.) is stored in Zanzibar, and the decision engine resolves access checks based on this data. This data can be scaled horizontally (and consistently) as needed for an application’s needs. This makes Zanzibar a centralized, unified solution for all of an application’s authorization needs. I’ve found this approach more purpose built / well suited for application authorization.

With OPA and other policy engines, the data required for performing access checks lives somewhere else (maybe the application’s database) and must be separately queried and included as part of the authorization check because OPA et al. are stateless decision engines. This makes it such that you need to piece together data from different sources in order to get your final decision, which IMO is something most developers don’t want to deal with.

On the flip side, Zanzibar’s “namespaces” are a very simple policy layer not well suited to querying against data outside of Zanzibar’s scope (e.g. geolocation, time, etc). For scenarios like this, a full fledged policy-as-code solution is great. However, it should be noted that some open source Zanzibar implementations like Warrant[1] and SpiceDB[2] (mentioned in the article) also offer a policy-as-code layer on top of Zanzibar’s graph-based/ReBAC approach to tackle these scenarios.

Disclaimer, I’m one of the founders of Warrant.

[1] https://github.com/warrant-dev/warrant

[2] https://github.com/authzed/spicedb

At Google, I believe some client applications build and maintain "permission-aware" search indexes based on the permissions in Zanzibar. In essence, Zanzibar can be queried to figure out the object ids a particular subject has access to. These object ids can then be hydrated via a database query or separate service call.

At Warrant, we're experimenting with allowing customers to maintain searchable metadata in Warrant and exposing a "query" API[1] that can automatically hydrate objects based on that metadata.

[1] https://docs.warrant.dev/warrants/query-warrants/

You've highlighted a very important part of the paper. A lot of the external consistency guarantees provided by Zanzibar are facilitated by Spanner and its TrueTime mechanism. Warrant doesn't currently support/use Spanner. However, for the databases we do support (MySQL and Postgres - which are both ACID compliant), we've implemented the zookie protocol using the incrementing transaction ids they provide. This approach works for single writer deployments of these databases, so know that write throughput and overall availability will be lower. We started with this approach because most teams still use MySQL/Postgres. Warrant is built to support running on different types of databases, so we will be working on support for Spanner and other multi-writer distributed databases like Cockroach and Yugabyte in the future. I hope that helps.

I think GraphQL might be a good example. Some might not consider it to be very niche, but its intention is to consolidate dependent API queries such that the client can fetch all the data it needs in a single request. In both Zanzibar and GraphQL, the idea behind the schema/modeling language is to provide a layer where logic specific to relationships between data (in the case of GraphQL) or logic specific to authorization (in the case of Zanzibar) can be specified such that neither the server nor the client need to worry about it and can instead query for data in a simpler way.

Google doesn't actually offer Zanzibar as a product/service (in GCP or otherwise) to customers. However, they do use it internally to manage permissions across their various products (Google Docs, Drive, YouTube, etc.) and have had a lot of success doing so. Because of that, there are many open source implementations of Zanzibar out there (as others have commented). Warrant also maintains our own open source implementation of Zanzibar[1] which powers our managed cloud offering, Warrant Cloud[2].

[1] https://github.com/warrant-dev/warrant

[2] https://warrant.dev

Another interesting feature of capability-based systems (that is outside Zanzibar's scope) is that capabilities can themselves be used to gain access to an object. This is because they are unforgeable tokens, meaning they essentially have authentication baked into them. Zanzibar leaves the authentication piece to an external service and focuses on providing the ability to define, store, and query access rights for subjects.

As I understand it, "capabilities" in capability-based schemes uniquely reference an object and specify a list of access rights on that object. This seems fairly similar to tuples in Zanzibar, which reference a unique object, an access right, and a unique subject whom the access right belongs to. You can think of Zanzibar as a layer used for defining, storing, and querying for capabilities.

That's definitely one of the more complicated problems. One way we've considered approaching it is to allow customers to attach metadata to resources they manage via Warrant and allow them to query (or search) against this metadata. This obviously has its trade-offs (requires duplicating/syncing of data with Warrant), so we're still exploring solutions.

Thanks! As a developer myself, I've loved seeing companies like Stripe, Plaid, Auth0, etc. build solutions to hairy technical problems catered to developers. In my experience, technical leaders (decision makers) always looked to their teams when evaluating core technical solutions. There's nothing better than letting your team work with the tools they love and get the job the done. We've spoken to many technical leaders across the industry who have echoed the same thinking.

Completely agree re: UI components. As a full stack engineer, I personally dealt with the pain of permissions on the frontend and want to make things much easier than they are today. We've already started working on this. Our first foray into the idea is our self-service dashboard.[0][1]

Re: self-hosting, we're definitely looking into it and plan to have a solution for it soon. Thanks for the feedback!

[0] https://warrant.dev/features/self-service-dashboard

[1] https://docs.warrant.dev/quickstart/self-service-dashboard

As others have mentioned, solutions like Cognito and Auth0 are primarily focused on providing authentication (authn) and stop at basic RBAC when it comes to authorization (authz). Many companies quickly outgrow RBAC or need more powerful authz models (fine grained, attribute based, etc.) to serve their business needs.

Warrant focuses on the authz piece, supporting RBAC (like Cognito & Auth0), but more importantly, allowing companies to define & enforce their own authz model.

Hi HN, the Warrant Self Service Dashboard is a Warrant-hosted permission management page that can be added to any application in a few lines of code and lets customers manage their own role and permission assignments (think Stripe Checkout for roles & permissions).

Many B2B SaaS companies spend significant resources building out self service access management as they grow, introducing potential security vulnerabilities and code complexity along the way. We built the Warrant Self Service Dashboard to give companies beautiful, intuitive permissions management for their customers with just a few lines of code.

I'm glad you got some value from my answer. Happy to help!

Thank you! We put a lot of effort into maintaining quality documentation, so I appreciate the compliment!

Our pricing is intended to scale with an application. $1 per 1,000 API requests / mo is expensive for an application with thousands of requests per second, but I would imagine an application with that kind of traffic would fall into our enterprise tier which provides volume discounts. We also have a nice free tier for testing out the product in some capacity at any stage and offer better deals for early stage startups.

Regarding rate limiting. It hasn't really been an issue for us yet. As an API product, the only users I would rate limit would be free tier customers who are generating tons of requests and degrading performance for paying customers (hasn't happened yet). For paying customers, I would probably want to scale our infrastructure to support the amount of traffic they're bringing in since they're paying.

Which service to use for billing will depend on how you plan to charge your customers (flat monthly rate, usage based, etc.), so it's worth thinking about pricing first and then exploring the options available on the market. Even though they don't have a specific usage based billing product, my default recommendation is Stripe because it's so easy to setup and manage, and they really have the best product/experience.

Rate limiting is something that's not too difficult to implement and would probably make sense to build yourself. However, it's probably not something worth spending time on until it becomes a necessity (i.e. when you have enough customers that it becomes an issue). Don't waste time on it this early.

For authentication, there are several open and closed source options like Auth0, supertokens, etc. Any of them should work really well depending on how well they integrate with your programming language of choice. Some newer ones like Stytch offer more modern authentication flows (passwordless, magic link, etc). As an API product, you might want to look into a service that helps with generating and managing API keys for API authentication instead.

Depending on the complexity of your product's access control, I would recommend using an authorization-as-a-service product to handle authorization. Warrant (https://warrant.dev/ -- disclaimer: I'm the founder) is an end-to-end authorization service that helps you add authorization at any layer of your stack (API, UI, etc.) without much code and provides a dashboard for managing your access model/access rules.

Aside from these problems, I would recommend spending some time thinking about how you'll manage API versioning and infrastructure/deployments. These are really important for giving your customers a seamless experience as API consumers.

I hope this helps!

Thanks for your response! A lot of the issues and solutions you mentioned remind me of my time in past roles. More companies deal with authz related issues than we think, yet there aren't many products available that solve these long-term operational problems (UI, managing existing/new permissions over time, etc). Most solutions are just basic DIY libraries, although services like Warrant (https://warrant.dev/) are now becoming popular as engineering teams realize the complexity of solving/maintaining authz for the life of a software product.

To your point, authz is rarely a business's core product, so many in-house solutions don't get enough attention, and tend to become a big source of friction for engineering and product teams as they age. In my experience, this can slow down teams considerably or reduce code quality over time, which is why I'm excited to help devs find & build better solutions.

I'm glad you enjoyed my post, and I look forward to sharing more about building robust authz!

A great introductory read on such an expansive topic. Authz is a long-standing problem without a real standardized solution yet. I think improving everyone's understanding of the core problems that authz presents is a nice first step to building better standards/best practices.

Whether you're building something in-house or evaluating a third party library/service, I've found that OWASP has great content, guidelines, and best practices around authz[0] and access control[1]. They've been a go-to reference for me throughout my software engineering career.

We also followed a lot of OWASP's guidelines/best practices while building Warrant[2] (YC S21 - I'm one of the co-founders), so that developers don't need to think about it and can follow best practices just by integrating our authz service into their application.

[0] https://cheatsheetseries.owasp.org/cheatsheets/Authorization...

[1] https://cheatsheetseries.owasp.org/cheatsheets/Access_Contro...

[2] https://warrant.dev/

Thanks for the response! It is interesting to see the surge in popularity of Zanzibar. Completely agree that Zanzibar itself isn't too difficult to implement (especially since Google published a paper on it). It does provide great flexibility though.

I don't agree with your point that it requires developers to re-architect their systems or that it doesn't handle attribute-based controls well. If anything, I think Zanzibar actually helps developers enforce the best authz practices in their system. This becomes increasingly helpful as an application changes or grows in complexity.

To be clear, Warrant isn't just a Zanzibar implementation. We're building Authz as a service with devxp as the central focus.

Keto + Oathkeeper together seem to be similar to what Warrant provides. One of our main focuses is providing great developer experience. We're continuing to build out the tooling around this, so stay tuned!

That’s correct, Warrant would act as your authorization service, where you can store access rules for your system and check against them at runtime to protect access to your application. Roles are a common access control model, but you can model much more complex use-cases like fine-grained access control as well.