June was a month of convergence. Over the past several months we had been building — in parallel — a general-purpose account-management plugin for RESTHeart and migrating RESTHeart Cloud's own authentication layer onto it. Both tracks landed at the same time, and we used the occasion to expose the result directly to RESTHeart Cloud users through a new configuration interface called Sign-up Mgmt.
restheart-accounts: Application-Level Auth in a Plugin
Building user registration is one of those tasks that looks simple from the outside — a form, an email, a token — but turns out to be an iceberg. Verification links expire. Passwords need strength checks. Invite flows for new and existing users behave differently. OAuth providers require secure state handling. Consent records must be persisted for compliance. Every project reinvents the same machinery, and it almost always carries subtle bugs.
restheart-accounts, available starting from RESTHeart 9.4, is our answer to that problem. It ships as a self-contained plugin and adds a complete set of HTTP endpoints to any RESTHeart deployment: POST /auth/register, GET /auth/verify, POST /auth/forgot-password, PATCH /auth/reset-password, POST /auth/invite, PATCH /auth/activate, GET /auth/oauth/authorize/{provider}, and more. All of them integrate transparently with the existing RESTHeart security pipeline and issue standard JWT cookies that every other part of the stack already understands.
The registration flow enforces password strength using zxcvbn with a configurable minimum score, checks email uniqueness with a 409 Conflict before writing anything, generates a cryptographically random 256-bit verification token, and sends the verification email in the same atomic step. Email enumeration on the forgot-password endpoint is prevented by always returning 202 Accepted regardless of whether the account exists. Token comparisons use constant-time functions throughout. These are not features that need to be designed and tested by each team separately — they come for free.
Team management is built around a MembershipProvider SPI that decouples the plugin from any particular data model. The built-in implementation stores teams in a MongoDB orgs collection and tracks memberships on the user document, but any deployment can plug in its own provider without touching the plugin. Inviting someone who doesn't have an account yet and inviting someone who already does follow different flows automatically: the plugin detects whether the user exists, branches accordingly, and stores all pending invitations in a dedicated auth_invitations collection so that a single user can hold open invitations from multiple teams simultaneously.
Social login via Google OAuth is included out of the box. The plugin handles the full authorization code flow server-side — CSRF state generation, code exchange, user upsert, JWT issuance — so the client only needs to redirect the browser to /auth/oauth/authorize/google and wait for the callback to land the user in the authenticated area. Invitation acceptance via OAuth is also supported: a pending invite token attached to the authorize URL is picked up at callback time and resolved transparently.
Multi-tenant deployments are supported through a per-request override mechanism. Two lightweight interceptors in the deployment layer — AuthDbResolver, which maps the incoming hostname to the correct MongoDB database, and TeamConfigInterceptor, which reads per-service configuration from MongoDB and attaches it as request attributes — allow the same plugin instance to serve hundreds of distinct tenants without any per-tenant configuration changes to the plugin itself.
RESTHeart Cloud Migrated to restheart-accounts
We didn't ship restheart-accounts as a standalone module and leave RESTHeart Cloud on its old auth code. We used it as the migration target for our own infrastructure.
RESTHeart Cloud's authentication and invitation system had grown organically over several years and had accumulated significant custom logic. The migration replaced that legacy code with restheart-accounts endpoints, adopted the standard MembershipProvider contract for all team operations, and removed a collection of ad-hoc interceptors that had handled invite tokens, role assignment, and OAuth state in separate, only loosely coordinated ways.
The benefit of doing it this way — eating our own cooking before shipping it to customers — is that the plugin arrived in production having already handled real traffic. Edge cases in the OAuth callback flow, subtleties in the consent-persistence interceptor pattern, the behavior of the auth_invitations collection under concurrent invite resends: all of these were exercised in our own environment before they became your problem.
Sign-up Mgmt: Configure Auth for Your Service from the Console
The third piece is the one most directly visible to RESTHeart Cloud users. Under each service in the console there is now a Sign-up Mgmt section where you can configure restheart-accounts for the users of your own application.
When you land on the page for the first time, the accounts plugin is not yet installed on your service. A single button installs it and creates the initial configuration. From that point forward the service exposes the full set of authentication endpoints under its own domain — /auth/register, /auth/verify, /auth/forgot-password, and all the rest — ready to be called by your frontend.
The configuration form lets you set the application name that appears in email subjects, the frontend base URL used to build links inside transactional emails, and the URL of the authenticated area where users are redirected after a successful auto-login. Feature toggles let you enable or disable individual capabilities independently: you might want registration and password reset but not team invitations, or you might want all flows active except OAuth while you're still setting up your Google credentials. Disabled endpoints return 403 to callers, so there's no ambiguity about what's available.
Email templates are the piece that makes the experience yours rather than ours. The default built-in templates are clean and functional, but they carry RESTHeart branding. The Sign-up Mgmt page lets you paste your own HTML for each of the three transactional emails — verification, password reset, and team invitation — and preview them in the browser before saving, so you can verify the layout and placeholder substitution before any real user sees them.
Google OAuth configuration lives in the same page. You enable the provider with a toggle, paste your Client ID and Client Secret from the Google Developer Console, and save. The credentials are stored server-side and never exposed to the browser. From that moment your service's /auth/oauth/authorize/google endpoint is live.
The page also serves as a reference for the REST API your service now exposes: a full list of available endpoints grouped by feature area, each with its HTTP method, path, and a short description, with a copy-to-clipboard button that assembles the full URL against your service's base address.
What This Means in Practice
The combination of these three things — the plugin, the cloud-server refactoring, and the console UI — means that adding a complete authentication system to a RESTHeart service is now a configuration task, not an implementation task.
You open the Sign-up Mgmt page, click Enable, set your app name and redirect URLs, upload your email templates, optionally connect Google OAuth, and save. Your MongoDB-backed backend now handles registration, email verification, password reset, social login, and team invitations for your users, secured, tested, and consistent with the same logic that runs RESTHeart Cloud itself. The time from zero to working auth flows is measured in minutes.
Ready to Build Something Great?
Focus on what makes your app unique. Your backend is ready in minutes. Start with our free tier - no credit card required.