Super interesting. Auth and Payments seem like things you don't want to or can't build yourself. (I'm waiting for the day when I can just use BTC or UDSC for everything.)
Have you thought about supporting additional auth providers? Or providing a way for other auth services to add support for their products?
Thanks! On auth providers — Corral already supports 9 OAuth providers out of the box (Google, GitHub, Apple, Discord, Microsoft, Twitter, Facebook, GitLab, LinkedIn) plus email/password, magic links, and email OTP. Adding a new one is one command:
corral add provider github
Under the hood, Corral is built on Better Auth, which has a plugin architecture. Any Better Auth plugin works with Corral — so if someone builds a provider plugin for Better Auth, it automatically works here too. We're not reinventing auth crypto, just making it agent-installable.
On the crypto payments front — that's actually a great use case for Corral's plugin model. The billing layer is modular (Stripe today, but the gating/metering layer doesn't care where the payment event comes from). A BTC/USDC payment plugin that fires the same "user upgraded to plan X" event would slot right in. Interesting idea.
It 100% runs locally, is easy to deploy, and it wires it right into your app - even cooler, if you have a JS backend, no extra server, if you have python, go, ruby, etc, it will have your agent create a tiny side-car so you don't need an extra container, etc.
This validates something we keep seeing-the bottleneck for AI agents isn't intelligence, it's that tooling isn't yet built for how they actually work. Structured specs and parseable errors > docs written for humans. Really cool to see this ship.
webhooks are the part where most agent-built auth falls apart. Here's how Corral handles it:
The server-express.ts template generates the webhook route with the raw body parser before express.json() (Stripe requires the raw body for signature verification — agents almost always get this wrong). The route handles checkout.session.completed, customer.subscription.updated, and customer.subscription.deleted events and auto-updates the user's plan in your database.
So when your agent runs corral init, the webhook endpoint is already in your server at /api/corral/webhook, with Stripe signature verification wired in. Your agent just needs to:
corral stripe sync — creates the products/prices in Stripe
Set STRIPE_WEBHOOK_SECRET in .env
For local dev: stripe listen --forward-to localhost:3000/api/corral/webhook
That's it. The agent doesn't have to figure out raw body parsing, event routing, or idempotency — the template handles all of it. And since corral doctor checks for the webhook secret in your env, the agent gets told if it's missing.
The worst Stripe webhook bugs I found during testing were (1) express.json() parsing the body before the webhook route sees it, and (2) agents putting the webhook route after auth middleware that rejects unsigned requests. Both are baked into the template ordering now.
Super interesting. Auth and Payments seem like things you don't want to or can't build yourself. (I'm waiting for the day when I can just use BTC or UDSC for everything.)
Have you thought about supporting additional auth providers? Or providing a way for other auth services to add support for their products?
Thanks! On auth providers — Corral already supports 9 OAuth providers out of the box (Google, GitHub, Apple, Discord, Microsoft, Twitter, Facebook, GitLab, LinkedIn) plus email/password, magic links, and email OTP. Adding a new one is one command:
corral add provider github Under the hood, Corral is built on Better Auth, which has a plugin architecture. Any Better Auth plugin works with Corral — so if someone builds a provider plugin for Better Auth, it automatically works here too. We're not reinventing auth crypto, just making it agent-installable.
On the crypto payments front — that's actually a great use case for Corral's plugin model. The billing layer is modular (Stripe today, but the gating/metering layer doesn't care where the payment event comes from). A BTC/USDC payment plugin that fires the same "user upgraded to plan X" event would slot right in. Interesting idea.
It 100% runs locally, is easy to deploy, and it wires it right into your app - even cooler, if you have a JS backend, no extra server, if you have python, go, ruby, etc, it will have your agent create a tiny side-car so you don't need an extra container, etc.
Let me know what you think!
This validates something we keep seeing-the bottleneck for AI agents isn't intelligence, it's that tooling isn't yet built for how they actually work. Structured specs and parseable errors > docs written for humans. Really cool to see this ship.
Thanks for following along since day 1!
How do agents handle the Stripe webhook setup? That's always been the gnarliest part for me manually.
webhooks are the part where most agent-built auth falls apart. Here's how Corral handles it:
The server-express.ts template generates the webhook route with the raw body parser before express.json() (Stripe requires the raw body for signature verification — agents almost always get this wrong). The route handles checkout.session.completed, customer.subscription.updated, and customer.subscription.deleted events and auto-updates the user's plan in your database.
So when your agent runs corral init, the webhook endpoint is already in your server at /api/corral/webhook, with Stripe signature verification wired in. Your agent just needs to:
corral stripe sync — creates the products/prices in Stripe Set STRIPE_WEBHOOK_SECRET in .env For local dev: stripe listen --forward-to localhost:3000/api/corral/webhook That's it. The agent doesn't have to figure out raw body parsing, event routing, or idempotency — the template handles all of it. And since corral doctor checks for the webhook secret in your env, the agent gets told if it's missing.
The worst Stripe webhook bugs I found during testing were (1) express.json() parsing the body before the webhook route sees it, and (2) agents putting the webhook route after auth middleware that rejects unsigned requests. Both are baked into the template ordering now.
ah makes sense, excited to hook it up to a project
That is pretty cool. Simple and useful.