---
title: Privacy & pairwise identity
description: How Sudomimus stops applications from correlating the same user
  across products — purpose-scoped pairwise identifiers, an internal account ID
  that never leaves the system, user-controlled rotation, and per-application
  claim sharing.
editUrl: true
head: []
template: doc
sidebar:
  order: 4
  hidden: false
  attrs: {}
pagefind: true
draft: false
---

Sudomimus is built so that **the applications a user signs in to cannot quietly link that person across products**, and so that the user — not the application — stays in control of the identity they hand out. This page explains the identity model that makes that true.

## The core promise

When a user authenticates, an application never receives a global, stable account ID. Instead it receives a **purpose-scoped identifier** that is meaningful only to that application — or to that one developer's family of applications. Three principles hold:

- **The real account identifier never leaves the system.** Internally every account has a primary key, but it is a pure internal foreign key: it is never minted into a token, never shown to an application, and never shown to the signing-in user. There is nothing to leak.
- **No cross-application correlation by default.** Two unrelated applications receive *different* identifiers for the same person. Two owners who compare notes cannot tell that their two users are the same human.
- **The user can rotate their identifiers.** Identity continuity is a choice the user can revoke.

## Sectors: the unit of isolation

Every application belongs to exactly one **sector**. A sector is the boundary that decides who shares a user's identity:

- Within a sector, a user has exactly **one** identifier, so two applications placed in the same sector see the **same** identifier for that user. This is deliberate — it lets one developer run a family of related products as a single identity (a game launcher and its companion app, say).
- Applications in **different** sectors see **unrelated** identifiers for the same user. No amount of comparing those identifiers reveals the shared person behind them.

By default each application gets its own fresh sector — **maximum isolation**. A developer who genuinely wants two of their applications to share a user's identity opts in by placing both in one sector; nothing is shared until they ask for it. Sectors live inside an organization alongside your applications — see [Organizations and sectors](/en-us/concepts/organizations-and-sectors/).

:::note
Because the per-user identifier is a function of *(user, sector)*, moving an application between sectors changes the identifier every one of its users presents. It is a deliberate, identity-severing operation — not a routine config tweak.
:::

## The identifiers a user actually has

| Identifier | Who sees it | Rotatable | What it's for |
|---|---|---|---|
| **Account alias** | The user, in their account portal. **Never the application.** | ✅ | A handle the user shares out of band with whoever configures an allow-list — so an operator can permit "this specific person" without the application ever learning the handle. |
| **Sector subject** | The application — it **is** the `sub` claim in the token. | ✅ | The application's key for that user, and the value a developer allow-lists against in their own rules. Unique per *(user, sector)*. |

Both are **opaque, human-readable tokens** — a sector subject looks like `sub_9SQ5535CRWNDDM2T`, an account alias like `quiet-meadow-7h2k-9m4p-3fnp-falcon`. Applications are expected to treat them as opaque strings: never parse them, never assume a format. That is exactly what lets the format evolve later without breaking anyone.

### Rotation, and what it means

- **Rotating the account alias** changes the handle the user hands out for allow-listing. The application never saw the old one and never sees the new one — only out-of-band allow-list configuration is affected.
- **Rotating the sector subject** changes the `sub` an application sees for that user. The previous subject stops resolving, so the application now sees what looks like a brand-new user. This is the user's "forget my continuity with this product" control, exercised from their account portal.

## The other half: claim sharing

A pairwise identifier only buys privacy up to the **strongest stable claim** an application still receives. If every application is also handed the same real email address, it can correlate on the email instead — and the pseudonymous `sub` was beside the point.

So identity claims are a **separate, user-controlled layer**. Per application, the user decides whether their **email**, **first name**, and **last name** are minted into that application's tokens at all:

- A developer declares, per claim, whether the application requests it: **off**, **optional**, or **required**.
- The user makes the final call on the optional ones at login, and can **revoke a previously granted claim at any time** from their account portal. Revocation takes effect on the very next token issued — the decision is read live at each issue, never from a cached copy baked into an old token.
- An application that was never granted a claim simply never receives it; the field is absent from the token.

Together these two layers — pairwise identifiers plus per-application claim control — mean an application receives exactly the identity surface the user chose to give it, and nothing it can use to quietly find that same user somewhere else.

See [Identity claims and sharing](/en-us/concepts/identity-claims/) for the full model — the policy levels, the consent screen, and how OIDC scopes gate what reaches a token.