Skip to content
TDACorpIDENTITYSign in

Pairwise subjects

What a pairwise client sees as the person's sub, the registration rules, which surfaces carry the pairwise value and which keep the real one.

On this page

Status: Available

The subject type is chosen when an administrator registers the client. It needs no flag and defaults to public.

By default every client sees the same sub for a person, so two applications that compare their user lists can tell that two accounts are one person. A pairwise client sees a different sub, one per sector, so they cannot. It is a privacy choice for a client, not a security control: the person's real identifier is still what identity and the SDK's resource-server checks use.

How it works#

The pairwise sub is 256 random bits, generated the first time a sector needs it and stored against the person. There is no key and no derivation: nothing can recompute it, and erasing a person deletes it. Two clients in one sector get the same value, clients in different sectors never do, and the value is stable for a person within a sector. A deactivated, suspended or erased person is never given a new one.

The discovery document lists subject_types_supported as public and pairwise.

Registering one#

subject_type is public (the default) or pairwise, set once at registration. It cannot be changed afterwards, because a different sub would orphan every account your application keyed on the old one. The rules are in validateSubjectScheme:

  • The client must be third-party. A first-party client is always public.
  • A public client has no sector.
  • The sector is a host. Unless one is given, it is the host that all the client's redirect addresses share, and every redirect address must be on it. A client whose addresses are on several hosts cannot be pairwise: identity does not fetch a sector document.
  • A private-use scheme address has no host, so a native client that uses one cannot be pairwise.
  • A loopback host cannot be the sector, because every such client would share it and the scheme would protect no one.

An administrator sets it on the create-client form, as Subject type and an optional Sector identifier, or through the Admin API or the operator tool. See Register a client for how to ask for one. A client that is defined by a metadata document is always public.

Which surfaces carry which sub#

Surfacesub a pairwise client sees
ID token, from a code redemption or a refreshPairwise.
UserinfoPairwise.
Back-channel logout tokenPairwise. If the person is no longer active and the client never had a value, the logout token is skipped.
Security event to the client's streamPairwise.
Access tokenReal.
Token introspectionReal.
act.sub in an exchanged tokenReal.

The access token keeps the real sub because resource servers and the decision API identify the person by it, and a pairwise value there would break them. So a pairwise client must not compare an access token's sub with its ID token's, and a resource server that gets the same person from several pairwise clients sees one sub. That is a correlation channel for an application that is both a pairwise client and holds an access token for the person; the design accepts it. The session id sid is also the same for every client in one browser session.

Also withheld from a pairwise client is picture, because its address is built from the real sub.

What your application should do#

  • Key your own accounts on the ID token sub and nothing else, as for any client. See ID token.
  • Do not store the access token's sub as the account key. It is the person's real identifier, which is what your authorization calls use. See Protect your API.
  • A back-channel logout token's sub matches your ID tokens' sub, so Back-channel logout works with no change.

Verified against commit ca46b57