---
title: "Identity Management"
url: "https://effect-auth.itsbroly.com/authentication/identity-management/"
description: "Opt-in current-user identity availability, listing, addition, replacement, revocation, and primary-login selection."
---



An identity locates a stable user; it is not the user, a password credential, or necessarily a contact destination. `IdentityManagement` provides the current-user lifecycle for global email and global or tenant-scoped username/custom identities. It is opt-in: mount `IdentityHttpApiGroupLive` or bind `IdentityHttpOperations` only when your product exposes account-identity settings.

## Security boundary [#security-boundary]

The built-in HTTP handlers read `userId` from the validated session. Mutation payloads never choose their owner. They pass that session to `IdentityMutationPolicy`, so the application can deny an operation or require fresh step-up based on operation, current identity, proposed identity, user, and session evidence.

`IdentityMutationPolicyAllow` is convenient but deliberately permissive. For account settings, provide a policy that requires the assurance and freshness appropriate to add, replace, revoke, and primary changes. Keep CSRF/origin controls and route exposure at the application boundary.

Replace, revoke, and primary selection require the `updatedAt` returned by `list` as `expectedUpdatedAt`. This is a compare-and-set token: stale tabs and concurrent requests fail rather than overwriting a newer identity state. The service also rejects revocation of the user's last login-eligible identity.

## Service and HTTP surface [#service-and-http-surface]

| Operation                       | Behavior                                                                                                                               |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `availability`                  | Normalizes a proposed identity and reports whether no active row currently owns it. This is advisory; atomic uniqueness decides races. |
| `list`                          | Returns the user's active and historical identity rows as safe `IdentityInfo` values.                                                  |
| `add`                           | Adds an identity after policy authorization. Email starts unverified; username/custom kinds are locally verified.                      |
| `replace`                       | Atomically revokes the current row and inserts its replacement when `expectedUpdatedAt` still matches.                                 |
| `revoke`                        | Revokes the row when it is owned, active, current, and not the last login identity.                                                    |
| `setPrimary` / client `primary` | Selects an active login-eligible identity as primary with CAS protection.                                                              |

Revoked and replaced normalized values are immediately reusable. If your product needs username quarantine or a cooldown, enforce it in application policy and storage rather than assuming a core tombstone reservation.

## Browser client [#browser-client]

The unified client exposes `auth.identities`; the standalone client is `createIdentityClient` from `@effect-auth/core/Client`.

```ts
import { createIdentityClient } from "@effect-auth/core/Client";

const identities = createIdentityClient();
const current = await identities.list();

await identities.replace({
  identityId: current.identities[0].id,
  expectedUpdatedAt: current.identities[0].updatedAt,
  scope: { type: "global" },
  kind: "username",
  value: "new-name",
});
```

Do not treat a successful availability response as a reservation. Submit the mutation and handle an identity conflict. After adding or replacing an email, start the email-verification flow for the returned identity; core does not mark a user-supplied email verified.

## Direct service composition [#direct-service-composition]

Import `IdentityManagement`, `IdentityManagementLive`, `IdentityManagementWithEmailAcceptanceLive`, `IdentityMutationPolicy`, and `makeIdentityManagementAudit` from `@effect-auth/core/IdentityManagement`. Use `IdentityManagementWithEmailAcceptanceLive` when the provided `EmailAcceptancePolicy` must protect email add and replace operations. The audit wrapper emits safe identity lifecycle events after successful mutations. Direct service calls must still receive a trusted `userId`; they do not authenticate requests for you.

The maintained Effect-QB SQLite/D1 storage implements atomic replace, revoke, and primary transitions. Custom stores must preserve ownership, eligibility, last-login, uniqueness, and `expectedUpdatedAt` in the mutation transaction or predicate.

