I'm left with the sense that this is a sort of solution that's trying to do auth permissions via the billing process, without calling it auth. Any access token you'd set up for auth with roles or permissions can give you access to both a customerId and whatever access grants you'd want to give.
What we were exploring is whether there's a way to do this securely from the frontend (eg on a pricing page) without needing to open up backend routes.
You're also correct that our niche is trying to control feature permissions, so that we can decouple pricing logic from an application (which makes it easier to handle pricing changes, custom plans etc). We are moving more towards a solution that just uses the JWTs to handle this instead of a customer_id.
This will not give you clean easy to understand reporting if you make bundles willy-nilly (N product line makes $ dollars, if bundled products exist), but to me, it gives accurate data that matches up with the pricing complexity that the business is designing.
Technically speaking, billing and payments are two separate things.
For example: OpenAI needs to calculate how much you need to pay for the tokens you consumed across all of its models. That usage aggregation, calculation and then issuing of an invoice is billing—payments is only the transfer of money.
1. This is also why we've built plugins for popular auth providers like Clerk, Better Auth and Supabase, which are called on the backend to fetch the user / org ID.
2. The encrypted customer ID is more of an experiment atm, and down the line if we continue working on it we might even build an auth system involving JWTs -- though that'd be reinventing the wheel and not something we're keen on
3. We are actually now working more on a framework agnostic pattern where users register a middleware on their backend which will spin up routes for Autumn, and the frontend provider contains a client which simply calls these routes
I am mostly an embedded/Linux driver engineer, but I think I know the basics of HTTP, REST APIs, Docker containers, how the web works overall etc.
But, like. What are we doing?
What do you mean make the billing backendless? Obviously there has to be a backend to process the payment. What are you even saying? You are presumably not building a distributed blockchain - and even that requires permanent nodes.
Same with serverless (which are just Edge Functions and could just be called that, or serviceless, if you really wanted to define it negatively).
If these people named NoSQL, it would be called databaseless.
That will be $6.62607015e-34 please.
My problem is when you know that workflow, and that integration... you actually don't need it, its just nice to have. Its just a way for Stripe to send you updates to an endpoint with the status, like if say a card has declined as the charge is closing. But you can just poll.
This is just billing as a service.
Lmao, this is way too good. I'm going to steal this.
Why can't they be authenticated? That seems like the obvious fix. Otherwise how you are handing out the correct customer_id unless you authenticate somehow?
This scheme also complicates API key rotation, although you can work around it by trying to decrypt with both the old and new key if you use e.g. authenticated encryption.
This also has no mechanism for expiration (besides API key rotation). If you add an expiration time and sign it, then you essentially created an authentication token that you use as the customer_id.
Authentication is definitely possible, but we were trying to brainstorm a way where users could have protected routes with as little set up as possible, the ideal being they just pass in customerId into a Provider component
We also did think about things like registering an auth function but felt that being able to just pass in customerId would be a magical experience!
Definitely acknowledge that the current mechanism has flaws though -- it's really more of an experiment at the moment, and if it does indeed become very popular with users we would implement auth mechanisms like JWT and what not -- though that would kinda be reinventing the wheel
Your encrypted customer ID has the exact same semantics as the original customer ID for an attacker, and is insecure.
The real issue seems to be that they're trying to make billing "feel frontendish" when it's inherently a backend concern. The encryption approach in Part 3 is essentially recreating auth tokens but with extra steps, as others have noted - they're basically reinventing JWTs.
What struck me most was the security vulnerability they discovered with server actions. If you can make calls with any customer_id without verification, that's a textbook IDOR vulnerability. A simple curl request with a different customer_id would let you upgrade/downgrade other accounts! No amount of client-side magic can fix fundamentally flawed authorization.
Their conclusion is telling, sometimes the "boring" approach (proper backend routes with auth) exists for good reasons. I appreciate their transparency about the journey though, we learn more from these explorations than from pretending everything works perfectly from day one.
What's stopping me from opening the console and calling the "addMoreCredits" function? Why can't I just edit the code to remove any mention of consuming credits?
I think you're about to discover why most multiplayer games have moved authoritative simulation to the server.
robertlagrant•6h ago
A JWT with the customer_id (or surrogate) in would let you do that in serverless function.
ayushrodrigues•4h ago
robertlagrant•3h ago