What this is about
nordbau cancels as of 31 December. From 1 January nobody should be able to work any more, but the data should stay complete for now: for follow-up questions, for retention, for a possible change of mind.
Everything needed for this happens in CIAS, on the record of the tenant. CDMS learns nothing about it: on every request it asks the tenant gate whether this tenant is served today, and goes by the answer.
Three ways to end the operation
POST …/{id}/validity- “valid until 31 Dec”, the date takes effect by itself
- the tenant stays
ACTIVEbut is no longer served - the right way when the end is fixed
- can be opened again with a new window
POST …/{id}/suspend- out of operation at once, standing
SUSPENDED - the right way for an open invoice or an incident
- reversible: resuming (
…/resume) puts it back into operation - only resuming lifts the suspension, activating refuses with 409
POST …/{id}/close- final, standing
CLOSED - afterwards activating, resuming and suspending refuse with 409
- the key stays taken and is not available for a new customer
- the record stays so the audit knows whom old entries belong to
The timeline
gantt
dateFormat YYYY-MM-DD
axisFormat %d.%m.
section nordbau
served (ACTIVE, inside the window) :active, 2026-11-01, 2026-12-31
no longer served (window is over) :crit, 2026-12-31, 2027-02-01
closed (CLOSED) :crit, 2027-02-01, 2027-03-01
On 31 December it is still served: both bounds of the window are days and count. On 1 January the gate answers “not served”, without anybody having to do anything. Closing comes later, once it is certain the customer will not come back.
-
1Admin→CIASsets the validity window to
validUntil = 2026-12-31The call always replaces the whole window: an empty value means “open”, not “as before”. -
2CIASFrom 1 January the gate answers “not served”, everywhere at the latest 30 seconds after the date
-
3Admin→CIAScloses the tenant:
POST /cias/admin/tenants/{id}/close -
4CIASStanding
CLOSED, eventClosedin the auditResult: The customer's database, his files, his accounts and the audit stay untouched.
The {id} is the technical id, not the key. GET /cias/admin/tenants/by-key?key=nordbau returns it.
What happens in the second after
The gate remembers every answer for a short while, by default 30 seconds (codamai.cias.tenant-gate.ttl), and it does so per node of the application. So operation does not stop all at once:
sequenceDiagram
participant A as Admin
participant C as CIAS
participant G as Tenant gate
participant K as Client of nordbau
K->>G: request (0 s)
G->>C: Is nordbau served?
C-->>G: yes, remembered for 30 s
A->>C: suspend nordbau (10 s)
K->>G: request (20 s)
G-->>K: remembered: yes, goes through
K->>G: request (35 s)
G->>C: Is nordbau served?
C-->>G: no
G-->>K: 403 tenant-not-served
| What | Effect |
|---|---|
| requests that already passed the gate | run to the very end, including the write and the transaction |
| new requests | admitted from the cache for up to 30 seconds, then 403 cias.authentication.tenant-not-served |
| logging in at Keycloak | still works. Keycloak knows nothing about the suspension, the accounts are unchanged |
requests to CIAS itself, for example /cias/me | 403 as well: the gate stands in front of every request whose token names this tenant |
| timers and message listeners | no longer work for this tenant, provided they run through TenantScope as intended: that asks the same gate |
| other tenants | not affected at all |
That makes the cache time a security setting: it decides how long a customer who was just suspended keeps working.
-
CIAScheck the tokenAre signature and expiry valid?↳ no 401
-
CIASdetermine the tenantWhich tenant is meant?↳ no 403
tenant-unresolved -
CIAStenant gateIs
nordbauserved today?↳ no 403cias.authentication.tenant-not-served– this is where everything ends now - does not reach CDMS at all any more
There is only this one key for all refusals: suspended, closed, expired and unknown look the same from outside. Otherwise anybody with a valid token could try out company names and read off the customer list.
What stays and what is gone
- the database of the tenant with all tables, rows and revisions
- every file in the file storage
- the people's accounts in Keycloak, active, including membership in the organization
- the user records and role assignments in CIAS
- the CIAS audit in the system database, with
SuspendedandClosed - the tenant record including its key
- every request that names this tenant
- every piece of work without a request for this tenant
- after a while without access, the connection pool and the Hibernate objects CDMS kept ready for him
The last point is pure housekeeping: CDMS sweeps a tenant that has not been needed for a while out of its cache (by default after 1800 seconds). The database itself is untouched by that — CDMS never deletes a database. Removing it is a separate, deliberate step outside the API.
The customer’s people
A suspended tenant takes nobody’s account away. The people of nordbau can still log in, get tokens and run into the gate on every request. If their accounts should end as well, that is a separate handle per person:
| Goal | Handle |
|---|---|
| The customer should not be able to work any more | suspend the tenant. Takes effect for everybody after at most 30 seconds |
| Nobody of the customer should be able to log in any more | additionally suspend or close every account, see A person leaves the company |
| The customer might come back | suspend instead of closing, or just set the validity window |
| The customer is gone for good | close. After that there is no way back |
Traps
Next
- Suspend and close tenants, validity and The lifecycle of a tenant
- Admit the tenant (tenant gate), both operating modes: The tenant check
- Working for a tenant without a request
- Databases, pools, migration
- The case of a single person: A person leaves the company