Until now the Kladde had one office, and that office was the Entra directory its people sign in from. In this lesson the Kladde gets a registry of offices. An office is registered and receives a tenant ID of its own. Every request finds its office through the token, and an office can be suspended and in the end removed completely. At the end, two invented offices work in your Kladde at the same time, office North and office South, and a test proves that neither sees the other's contacts.
The office gets an ID of its own
Since lesson 4.3.5, ClaimsCurrentUser reads the directory ID tid from the token and turns it into the TenantId. That was right and
simple for one office. For several offices it is not enough:
- A directory is not yet an office. Since 4.7.3 the sign-in accepts tokens from several Entra directories. But whoever can sign in is not yet a customer. The Kladde has to know which directories belong to a registered office.
- An office can have several directories, for example after two offices merge. And it can change its directory. If
tidwere the key of all data, every row, every event and every grain state would then have to move. - An office has a status. Active, suspended, being removed: none of that is in a token.
The Kladde therefore separates two IDs. The directory ID (tid) says where a person comes from. The tenant ID (TenantId) says
who the data belongs to, and it is part of every key. In between sits the registry of offices in the Tenants context.
One question remains that you noted as a risk in lesson 4.9.1: the first office has quotes, events and grain states under its
existing TenantId, and that was its tid. The solution is plain: the first office keeps this ID. It is registered with
TenantId = its existing tid, and no stored key changes. Every further office gets a new ID that has nothing to do with any
directory. That the first ID happens to equal a tid is meaningless from then on. Record the decision as an ADR:
# 0027: Own tenant ID instead of tid
- Status: accepted
- Confidence: high
## Context
The Kladde accepts sign-ins from several Entra directories (ADR 0015). So far the TenantId is the tid from the
token. But an office can have several directories or change its directory, and a directory without a contract
must not see anything.
## Options
### Option 1: tid stays the TenantId, plus a list of enabled directories
### Option 2: a TenantId of its own per office, the registry of offices maps tid → office
## Decision
Option 2. The Tenants context assigns every directory to at most one office. The first office keeps its existing tid
as its TenantId, so no stored key moves.
## Trade-offs
Data no longer hangs on the sign-in; directories can be assigned and changed. In return, every request needs a
lookup in the registry of offices, cached for 30 seconds.
## Consequences
New Tenants context with an operations API (POST /ops/tenants), middleware for the resolution, ClaimsCurrentUser
reads the office from CurrentTenant.
## Security and privacy consequences
A directory without an office gets 403 and sees nothing. A suspension takes effect only after up to 30 seconds on
every replica; if a suspension has to take effect immediately after a break-in, operations restarts the replicas.
## Revisit when
- an office invites guests from foreign directories (B2B) and their tid does not belong to its office,
- the lookup in the registry of offices becomes visible in response times (p95).
The ADR follows the template from lesson 4.1.3, and the ADR test from the same lesson checks its form. The numbers are examples; your ADRs have their own.