Skip to content

Multi-tenancy

merido has an opt-in self-serve multi-tenant mode: users sign up with email + password, each gets an isolated org, and they bring their own provider credentials (BYOK). This turns a single deployment into a shared gateway many users can sign into.

It is off by default — the default local/single-user profile has no tenancy. Enable it explicitly.

Enabling it

bash
MERIDO_MULTI_TENANT=true

This is intended for the cloud profile (Postgres-backed). Pair it with the production hardening — a dashboard password hash and MERIDO_REQUIRE_API_KEY=true.

What you get

  • Email + password signup — public POST /api/auth/signup / login, with email verification and password reset.
  • Per-user org isolation — every user belongs to an org; all providers, keys, virtual models, usage, and live events are scoped to that org. One tenant never sees another's data or traffic.
  • BYOK — each user adds their own provider API keys / OAuth accounts, sealed under their org's key.
  • Admin tier — operators listed in MERIDO_ADMIN_EMAILS (comma-separated) get a verified-admin session and the cross-tenant /api/admin/* endpoints (list/suspend users, system usage).

Transactional email (Resend)

Verification and password-reset links are sent via Resend. Configure:

  • MERIDO_RESEND_API_KEY — your Resend API key (a bare RESEND_API_KEY is also accepted).
  • MERIDO_EMAIL_FROM — the From address for outbound mail.
  • MERIDO_PUBLIC_URL — the public base URL of your deployment, used to build the links in emails (verify / reset point back to /app).

Without these, signup still works but verification/reset emails can't be delivered, so set them before inviting real users.

Orgs, invites, and switching

Within multi-tenant mode, users can belong to multiple orgs and switch between them; org admins can invite others. These are exposed under /api/orgs/* (list, switch, invites). See API endpoints.

Creating an invite emails the invitee a link to <public_url>/app/accept-invite?token=…, valid for 7 days. Delivery needs MERIDO_PUBLIC_URL and the Resend pair above; without them the invite is still created and the dashboard shows the link for you to share by hand (it says so explicitly, and the raw token is displayed only once).

Redeeming requires a signed-in account, and the signed-in address must match the invited one — a forwarded link cannot seat someone else. A brand-new invitee is walked through sign-up first and returned to the link automatically; email verification is not required to accept.

Inviting an address that already has a pending invitation does not create a second one: the existing invitation is re-issued (new token, refreshed role and expiry) and the mail is sent again, so there is only ever one live link per invitee. That also makes a re-invite the way to kill a link you shouldn't have shared — the previous one stops working immediately. The audit log distinguishes the two as org.invite.create and org.invite.resend.

© merido. All rights reserved.