Multi-Tenant Architecture Question - Admin Hierarc...
# support
s
Hi team! Looking for architectural guidance on a multi-tenant setup. I've reviewed the multi-tenant docs (Multi-tenant Access Policy) and MSO blog post (Multi-tenant MSO), but they don't address my specific admin hierarchy issue. Our Structure: Me (Project Super Admin): Creates bots, access policies, global config, manages entire project Org Admins: MUST be restricted to their organization only - can invite/manage their own team members but cannot see other orgs Regular Users: Organization employees with restricted access What the Docs Don't Cover: The multi-tenant examples show non-admin users with AccessPolicies, but don't address how to handle organization administrators who need elevated permissions within their org scope but must remain isolated from other organizations. Current Issue: Org admins with "admin": true bypass all AccessPolicy restrictions and see admin resources across ALL organizations. This breaks tenant isolation entirely. What Works: Organization resources properly compartmentalized ✅ AccessPolicy resources properly restricted ✅ Other resources respect _compartment filtering ✅ What Doesn't Work: ProjectMembership with _compartment=%current_organization - admin users ignore this completely ❌ Critical Problem: Admin users get unrestricted access to: PasswordChangeRequest, UserSecurityRequest, Project, ProjectMembership, User. This means org admins can see all users across organizations and access project-level settings. Question: How do I create organization administrators who have admin-level permissions within their organization scope but are completely isolated from other organizations? The current admin flag is all-or-nothing and breaks multi-tenancy. Thanks! 🙏
@rahul1 , any help is greatly appreciated .
f
Hey @snowhey , I can help you out here. Quick preliminary question before digging deeper: In your self hosted setup, are you using your single super-admin Project for all of this, a single separate non-super-admin project, or multiple projects?
Your intended behavior is definitely doable. A User can be an admin but they will still be constrained by their AccessPolicy. From a high level, Admin status is separate from access policies. > "Admin users get unrestricted access to: PasswordChangeRequest, UserSecurityRequest, Project, ProjectMembership, User. " This is only the case if they are admins in your Super Admin Project. Instead, I would suggest doing this all in a new project that is not super admin. If you want your "Org Admins" to be able to invite new Users, you are correct that they need to be an admin, but if your access policies are configured correctly, they won't have unrestricted access to resource outside of their Organization
In general, I would try to do as little as possible from Super Admin, and you should follow [User Management](https://www.medplum.com/docs/auth/user-management-guide) best practices with a "Staging" Project and "Production" project. Also, I would take a look at [Project and Server scoped Users](https://www.medplum.com/docs/auth/project-vs-server-scoped-users). My recommendation would be to only have your employees that need to access non-prod environments configured a Server Scoped Users. And everyone else, should be Project Scoped.
s
Hey @finnbergquist , thanks for your response. here’s our setup: we’re using a single non–super-admin project with one main project admin. That project admin adds Org Admins for each tenant/org. The issue is that as soon as those Org Admins have ProjectMembership.admin = true, their AccessPolicy is ignored(https://github.com/medplum/medplum/blob/main/packages/server/src/fhir/accesspolicy.ts#L215). When they query the ProjectMembership endpoint, they see all users from all orgs, not just their own — which breaks tenant isolation. What we’d like is for Org Admins to only manage their own org’s users (invite/manage within their compartment) without gaining project-wide visibility or control. Right now the only workaround we see is to keep one true project admin, make Org Admins non-admin users scoped by AccessPolicy, and handle invites via bots/ClientApps. Is that the right pattern, or is there a cleaner way to achieve proper org-level admin isolation?
f
Ahh, I gotcha. Yea, you are correct that admin Users get unrestricted access to
Copy code
{
      resourceType: 'ProjectMembership',
      readonlyFields: ['project', 'user'],
    },

    {
      resourceType: 'PasswordChangeRequest',
      readonly: true,
    },

    {
      resourceType: 'UserSecurityRequest',
      readonly: true,
    },

    {
      resourceType: 'User',
      hiddenFields: ['passwordHash', 'mfaSecret'],
      readonlyFields: ['email', 'emailVerified', 'mfaEnrolled', 'project'],
    }
The pattern that I have seen is creating your own invite endpoint(authing with ClientApplication) or bot, that has a ProjectMembership.admin = true. But still keeping your "Org Admins" as non-admins.
93 Views