Linked identities¶
A linked identity says that a user of this tenant is a given subject at a named upstream provider. Whoever presents that subject at that provider is that user, and nobody else: it is what keeps a person from being created again every time they arrive by another door, and the one way a subject an upstream provider names becomes a person of this tenant at all. Nothing infers one. A row is written by a sign-in through the provider, or by an operator, and by nothing else.
What one holds¶
| Field | What it holds |
|---|---|
| Provider | The upstream provider, named as the federation knows it: the entity ID of an upstream SAML identity provider, or the identity_provider of a trusted issuer |
| Subject | The value that provider gives the person, compared byte for byte. It is not the sub this provider issues |
| Claims | The last snapshot of what the provider said of the person, empty when it said nothing |
| Linked at, last seen at | When the link was written, and when it was last written again |
The pair names one person of the tenant. The store holds one row per provider and subject, and linking a pair to a second person is refused, naming the person it already names. Linking it again to the same person is what a second run of an import does: the snapshot is replaced and the date it was last seen moves, the row keeps its person.
It is sealed. The provider, the subject and the snapshot are personal data, sealed under the data key of the tenant like every column of a person. A lookup matches two blind indexes beside them, keyed tags of the provider and of the subject, and the uniqueness of the pair is held on those tags. The tag of the provider is the one of the model on a column with few distinct values: it says which rows share a provider, which is the price of the uniqueness of the pair. Personal data says what that means.
Federation writes them¶
At the first sign-in through an upstream identity provider, the person and their linked identity are created together, in one unit, all of it kept or none of it. The snapshot holds the claims the provider said, by the names of OIDC Core §5.1, the address, and the telephone number when it said one. At the next sign-ins, nothing is created: the snapshot is refreshed, and what the provider fills is written again for a person it created.
A person is found by their link and never by their address. An address is given again to somebody else when its holder leaves; a subject is not. So an address that another person of the tenant holds, as a mailbox or as a username, refuses a first sign-in rather than linking that person on its own.
An operator writes one by hand¶
For a person who exists already and is to sign in through a provider, or be named by the assertions of a trusted issuer:
bin/console beffroi:user:link alice 'https://idp.example.org/saml/metadata' 'the-subject-it-gives-alice'
| Argument | What it says |
|---|---|
username |
The user of this tenant |
provider |
The upstream provider, as the configuration that trusts it names it |
subject |
The subject that provider gives this user, compared byte for byte |
The command prints the username, the provider, the subject, the identifier of the row and the slug of the tenant. Run again, it refreshes the link with an empty snapshot. A person linked that way signs in through the provider under the link, with none of the rules of a first sign-in: the provider did not create them, so nothing it fills is written of them, and only the snapshot of the link is refreshed.
No command removes a link.
What reads them¶
| Reader | What it asks |
|---|---|
| Signing in through an organisation | The person a SAML assertion names: the link of that provider and that subject, created with the person at the first sign-in |
| The JWT bearer grant, RFC 7523 §3 | The user an assertion of a trusted issuer is about: the link of the identity_provider that issuer is declared with and of the subject of the assertion. An assertion about somebody no link resolves, or about a disabled user, is refused as an assertion of an unknown issuer is, and no user is ever created there |
The person reads their links in the archive they ask for: one line per link, with the provider, the subject, the snapshot and the two dates.