From 891740e18084ef67c177c230bade290e14713c92 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 29 May 2026 17:23:57 +0800 Subject: [PATCH] Document admin Remove from tenant and shadow Id migration requirement - Clarify that Delete is host-only for the global account while Remove from tenant is the tenant-level soft removal available to tenant admins - Note in the migration guide that host-side shadow rows must use a new primary key Id different from the tenant user's Id --- .../2026-03-17-Shared-User-Accounts-in-ABP/POST.md | 2 ++ docs/en/modules/account/shared-user-accounts.md | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/docs/en/Community-Articles/2026-03-17-Shared-User-Accounts-in-ABP/POST.md b/docs/en/Community-Articles/2026-03-17-Shared-User-Accounts-in-ABP/POST.md index dcb69c289d..4dc27218c0 100644 --- a/docs/en/Community-Articles/2026-03-17-Shared-User-Accounts-in-ABP/POST.md +++ b/docs/en/Community-Articles/2026-03-17-Shared-User-Accounts-in-ABP/POST.md @@ -50,6 +50,8 @@ After signing into a tenant, a tenant switcher appears in the user menu — clic Users can also leave a tenant. Leaving doesn't delete the association record — it marks it as inactive. This preserves foreign key relationships with other entities. If the user is invited back later, the association is simply reactivated instead of recreated. +The same soft removal is available to a tenant admin from the user list — a **Remove from tenant** action that takes a user off the tenant without touching the global account. Useful for the obvious case: an employee leaves the company, the admin removes them from the tenant, but their account (and any other tenant they belong to) stays intact. + Back to our earlier scenario: the financial consultant now has one account, one password. She picks which company to work in at login, switches between them during the day. The system knows it's the same person, and the audit log can trace her actions across every tenant. ## Invitations diff --git a/docs/en/modules/account/shared-user-accounts.md b/docs/en/modules/account/shared-user-accounts.md index 6f028238c6..908b342de2 100644 --- a/docs/en/modules/account/shared-user-accounts.md +++ b/docs/en/modules/account/shared-user-accounts.md @@ -56,6 +56,8 @@ Users can leave a tenant. After leaving, the user is no longer a member of that > When a user leaves and later re-joins the same tenant, the `UserId` does not change and tenant-related data (roles, permissions, etc.) is preserved. +Tenant administrators with the `Identity.Users.Delete` permission can also remove a member from the tenant via the **Remove from tenant** action on the user list. This is a soft removal — the global account stays and the user can be re-invited later, exactly like the self-service Leave. + ## Inviting Users to a Tenant Tenant administrators can invite existing or not-yet-registered users to join a tenant. The invited user receives an email; clicking the link completes the join process. If the user doesn't have an account yet, they can register and join through the same flow. @@ -156,9 +158,12 @@ The following operations can only be performed by a host administrator when Shar - Enable or disable two-factor authentication - Change `LockoutEnabled` or `ShouldChangePasswordOnNextLogin` +> `Delete` here means deleting the **global user account**, not removing a user from a single tenant. Removing a member from one tenant is a tenant-level soft operation and is available to tenant administrators — see **Remove from tenant** below. + ### What tenant admins can do - Invite users to the tenant (see the Invitation flow above) +- Remove users from the tenant (soft removal; the global account stays) - Manage role and organization-unit assignments within the tenant - View audit / security logs scoped to the tenant @@ -172,4 +177,5 @@ If you plan to migrate an existing multi-tenant application from an isolated str 1. **Uniqueness check**: Before enabling Shared, ensure all existing usernames and emails are unique globally. ABP performs this check when you switch the strategy and reports conflicts. 2. **Tenants with separate databases**: If some tenants use separate databases, you must ensure the Host database contains matching user records in the `AbpUsers` table (and, if you use social login / passkeys, also sync `AbpUserLogins` and `AbpUserPasskeys`) so the Host-side records match the tenant-side data. After that, the framework can create/manage the user-to-tenant associations. + - **Important — each host-side shadow row must have a new primary key (`Id`) different from the tenant user's `Id`.** Generate a fresh `Guid` for every shadow row instead of reusing the tenant user's primary key. The framework relies on this to distinguish a separate-database tenant from a shared-database one; reusing the Id can mask "Leave Tenant" and external login / passkey synchronization on legacy data. The other identifying fields (`UserName`, `Email`, `PasswordHash`, `TenantId`, etc.) should still match the tenant-side row.