CodamAIDocs
Topicdone

Embedded and standalone compared

All differences between “CIAS in the same process” and “CIAS as a separate service” in one overview: artifacts, calls, database, failure behavior and the delay of a suspension.

Variants
embedded (a single unit)standalone (two services)CIAS reachable / not reachable

What this is about

CIAS can run next to CDMS in two ways. In the subject area, the result is always the same: same code, same rules, same rejections. The only difference is how CDMS and CIAS talk to each other.

The two pictures

flowchart LR
    subgraph E["Embedded: one process"]
        direction TB
        E_CDMS["CDMS / hub backend"]
        E_CIAS["CIAS modules<br/>(authentication, tenancy,<br/>user, authorization, …)"]
        E_CDMS <-->|method call| E_CIAS
    end
    E_DB[("System DB<br/>CDMS + CIAS tables")]
    E --> E_DB
    E --> KC1[(Keycloak)]
flowchart LR
    subgraph G1["Service 1"]
        G_CDMS["CDMS<br/>+ filter chain<br/>+ tenant client"]
    end
    subgraph G2["Service 2"]
        G_CIAS["CIAS service"]
    end
    G_CDMS -->|"HTTP: may tenant X<br/>be served?"| G_CIAS
    G_CIAS -->|"HTTP: GET /cias/fetch<br/>(roles, attributes)"| G_CDMS
    G_CDMS --> DB1[("System DB CDMS<br/>+ tenant DBs")]
    G_CIAS --> DB2[("CIAS DB")]
    G_CDMS --> KC2[(Keycloak)]
    G_CIAS --> KC2

All differences in one table

EmbeddedStandalone
Processesonetwo (or more)
What CDMS includesthe CIAS modules directly (with or without starter)only the CIAS filter chain and the CIAS tenant client
How CDMS asks: “May tenant X be served?”method call LocalTenantLookupAdapterHTTP GET /cias/lookup/tenants/{key}, timeout 2 s
Tenant-bound attributesmethod call into CIAS user managementHTTP GET /cias/lookup/users/{id}/attributes?tenantKey=…
How CIAS learns the roles of CDMSas a bean in the same processCIAS calls GET /cias/fetch on CDMS, with a reader realm role of its own (preset declaration-reader)
Database of CIASthe host's system DB; with the starter, one migration history per moduleits own
Token CDMS uses to ask CIASnone neededa service token of its own, fetched by the service itself from Keycloak, never the user token
Token check of the userthe filter chain in the same processthe filter chain in the CDMS process, against Keycloak
CIAS goes downgoes down together with CDMS, there is no “half” stateknown tenants keep running from the cache, unknown ones are rejected
Tenant is suspendedtakes effect after 30 s at most (cache of the tenant gate)takes effect after 30 s at most, from the point of view of each single service
Setting in the generatorthe project's CIAS module runs in the system's runtimethe project's CIAS module runs in another runtime

One request in both operating modes

The same request “list of customers” in both worlds:

GET of the customer list

When: CDMS and CIAS run in the same process, for example the hub backend.

sequenceDiagram
    participant B as Browser/BFF
    participant F as Filter chain (CIAS)
    participant T as Tenant gate (CIAS)
    participant C as CDMS
    participant DB as Tenant DB
    B->>F: POST /crm/customer/query + token
    F->>F: check token, exchange it, resolve tenant
    F->>T: may "kunde-a" be served?
    Note over F,T: method call in the same process
    T-->>F: yes (remembered for 30 s)
    F->>C: RequestContext filled
    C->>DB: SELECT … (only allowed rows)
    DB-->>C: rows
    C-->>B: data + meta

Result: One process, no network call between CDMS and CIAS.

When: CIAS runs as a separate service.

sequenceDiagram
    participant B as Browser/BFF
    participant F as Filter chain (in CDMS)
    participant R as Tenant client
    participant S as CIAS service
    participant C as CDMS
    participant DB as Tenant DB
    B->>F: POST /crm/customer/query + token
    F->>F: check token, exchange it, resolve tenant
    F->>R: may "kunde-a" be served?
    R->>S: GET /cias/lookup/tenants/kunde-a<br/>(service account token)
    S-->>R: served: true
    R-->>F: yes (remembered for 30 s)
    F->>C: RequestContext filled
    C->>DB: SELECT … (only allowed rows)
    DB-->>C: rows
    C-->>B: data + meta

Result: One extra HTTP call, but only when the tenant is not in the cache.

What happens when CIAS does not answer?

Only in standalone mode can CIAS go down on its own. Then the memory of the tenant gate decides:

Tenant gate in standalone mode
CIAS answers?Tenant in cache?Result for the request
yes–CIAS decides, the answer is remembered for 30 s
noyesthe last known answer still applies
nono403 tenant-not-served – when in doubt, reject

A 403 from the lookup or a timeout counts as an error, not as a “no”. That is why the cache is an availability buffer, not a speed trick.

Why both modes must behave the same in the subject area

The rule and its consequences
  1. 1
    CIAS
    No CIAS class activates itself. Every module sits behind a switch codamai.cias.<modul>.enabled with no default value
    Otherwise CDMS, which scans all com.codamai classes, would turn on CIAS in every application that only brings the jar along.
  2. 2
    CIAS
    Embedded and standalone run the same code with the same rules and rejections
  3. 3
    CIAS
    Only the adapters are swapped – tenant lookup, attribute lookup and declaration, local or over HTTP, plus the adapter to the identity provider
    Result: A bug that shows up in only one operating mode is, by definition, a bug

And CRMS?

CRMS knows the same two forms, and the hub derives them the same way, from the runtime of the CRMS module. But the decision is made separately from the one for CIAS. For CRMS the comparison looks like this:

CRMS embeddedCRMS as a service of its own
What the CDMS application includesstarter, the CRMS document archive, the format modules and the CRMS HTTP interfacestarter and crms-client
How CDMS calls CRMSmethod call ReportRenderPortHTTP POST /crms/render
Tokennone neededthe person’s token, never a service token
Databasethe application’sone of its own
Anchoring and retentionin the applicationin the CRMS service

The combinations with CIAS are under CRMS in the modes of operation.

Next

Search