CodamAIDocs
Topicdone

A customer cancels

The tenant is suspended and later closed. What happens to logins, running requests and the database.

Variants
validity window for the end of the contractsuspend nowclosethe customer's peoplethe customer comes back

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

Which handle fits which occasion
Validity window
POST …/{id}/validity
  • “valid until 31 Dec”, the date takes effect by itself
  • the tenant stays ACTIVE but is no longer served
  • the right way when the end is fixed
  • can be opened again with a new window
Suspend
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
Close
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.

The stations of a cancelled contract
  1. 1
    Admin→CIAS
    sets the validity window to validUntil = 2026-12-31
    The call always replaces the whole window: an empty value means “open”, not “as before”.
  2. 2
    CIAS
    From 1 January the gate answers “not served”, everywhere at the latest 30 seconds after the date
  3. 3
    Admin→CIAS
    closes the tenant: POST /cias/admin/tenants/{id}/close
  4. 4
    CIAS
    Standing CLOSED, event Closed in the audit
    Result: 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
WhatEffect
requests that already passed the gaterun to the very end, including the write and the transaction
new requestsadmitted from the cache for up to 30 seconds, then 403 cias.authentication.tenant-not-served
logging in at Keycloakstill works. Keycloak knows nothing about the suspension, the accounts are unchanged
requests to CIAS itself, for example /cias/me403 as well: the gate stands in front of every request whose token names this tenant
timers and message listenersno longer work for this tenant, provided they run through TenantScope as intended: that asks the same gate
other tenantsnot affected at all

That makes the cache time a security setting: it decides how long a customer who was just suspended keeps working.

A request from nordbau after the suspension
  1. CIAS
    check the token
    Are signature and expiry valid?
    ↳ no 401
  2. CIAS
    determine the tenant
    Which tenant is meant?
    ↳ no 403 tenant-unresolved
  3. CIAS
    tenant gate
    Is nordbau served today?
    ↳ no 403 cias.authentication.tenant-not-served – this is where everything ends now
  4. 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

After closing nordbau
Stays
unchanged
  • 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 Suspended and Closed
  • the tenant record including its key
Is gone
only the access
  • 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:

How far should it go?
GoalHandle
The customer should not be able to work any moresuspend the tenant. Takes effect for everybody after at most 30 seconds
Nobody of the customer should be able to log in any moreadditionally suspend or close every account, see A person leaves the company
The customer might come backsuspend instead of closing, or just set the validity window
The customer is gone for goodclose. After that there is no way back

Traps

Next

Sources in the code and the knowledge base
  • CIAS/cias-tenancy – TenantAdminController (/{id}/suspend, /{id}/close, /{id}/validity, /by-key; no DELETE), TenantService (suspend, resume, close, changeValidity), Tenant (isServedOn, resume, activate only with PROVISIONED and not from SUSPENDED), TenantStatus, TenantEvent (Suspended, Resumed, Closed)
  • CIAS/cias-authentication – TenantGate (admit, cache), TenantGateProperties (codamai.cias.tenant-gate.ttl 30s, max-entries 10000), TokenParser.admit, RequestAdmission.TENANT_NOT_SERVED, JwtSessionFilter (/cias/** not exempt)
  • CIAS/cias-kernel – TenantScope (work without a request asks the same gate)
  • commons-persistence – DataSourceManager, TenantEntityManagerFactory (sweepIdle, never deletes a database), PersistenceProperties (factory cache 100 / 1800 s)
  • CIAS/cias-audit – AuditEntry (entries stay in the system database)
  • CIAS/cias-tenancy/docs/adr – ADR-016, ADR-020; CIAS/cias-authentication/docs/adr – ADR-021
Search