What this is about
Nordbau GmbH wants to use the application. Nobody sets anything up for them by hand: Anna Berg fills in a public form, and at the end there is a tenant nordbau-gmbh, an organization in Keycloak, a database and an account that can work in it.
This page plays the case through once, from front to back. For the details it links to the pages that describe each step on its own.
The parties
| Who | What they do in this case |
|---|---|
| Anna Berg | fills in the form, clicks the link, sets her password, creates the first data |
| CIAS | runs the registration, creates tenant and organization, grants the initial roles |
| Keycloak | holds the account, the organization and later the token |
| Platform administrator | approves the registration |
| Persistence (CDMS) | creates the tenant’s database and migrates its schema |
| CDMS | returns the data once Anna is signed in |
Who has which color is on The parties in a request.
The whole path
sequenceDiagram
participant B as Anna
participant C as CIAS
participant K as Keycloak
participant M as Email
participant A as Platform admin
participant P as Persistence
B->>C: POST /cias/registration/self<br/>email, first name, last name, company "Nordbau GmbH"
C->>C: throttle, validate fields, derive key nordbau-gmbh
C->>K: create account disabled and unverified
C->>M: confirmation mail with one-time link
C-->>B: 202 accepted
M-->>B: mail
B->>C: clicks the link (POST /cias/registration/verify)
C->>M: "your registration is being reviewed"
Note over C,A: registration waits in PENDING_APPROVAL
A->>C: POST /cias/admin/registrations/{id}/approve
C->>K: mark address verified, enable account, require password
C->>K: create organization nordbau-gmbh
C->>P: create tenant, provision database
P-->>C: done
C->>K: Anna becomes a member of the organization
C->>K: set attributes tenant and allowedTenants
C->>K: grant initial roles in the organization
C->>C: record the user, registration COMPLETED
C->>M: welcome mail, with a password link where possible
Block 1: the person proves her address
-
1User→CIASsubmits the form.
emailandcompanyare mandatory, there is no password field -
2CIASchecks the throttle: at most 10 attempts per address in 10 minutes
-
3CIASderives the tenant key from
company. "Nordbau GmbH" becomesnordbau-gmbh -
4CIAS→Keycloakcreates the account disabled and unverified
-
5CIAS→Emailsends the confirmation mail. Only the hash of the link is stored
-
6CIAS→Useranswers
202 { "status": "accepted" }– the same answer whether or not the address is new -
7User→CIASclicks the link. In
cias-runtimeit is valid for 24 hours and only onceResult: RegistrationVERIFIED. There is still no tenant and no roles
Details: Self-registration, Verify the email, The tenant key.
Block 2: a human approves
A public form that creates tenants creates them at whatever rate it is called. That is why cias-runtime ships with approval switched on (CIAS_SELF_SERVICE_APPROVAL).
-
1CIASregistration →
PENDING_APPROVAL, the person gets the mailAPPROVAL_PENDING -
2Admin→CIASfinds the registration through
GET /cias/admin/registrations?state=PENDING_APPROVAL -
3CIASchecks that the caller is a platform administratorA tenant administrator may not approve
-
4Admin→CIAS
approve– and provisioning starts in the same callResult:APPROVED→PROVISIONING
CIAS does not mail administrators when something is waiting for approval. The administration screen polls the list. Details: Approval by an administrator.
Block 3: everything comes into being at once
-
1CIASdetermines the initial roles for the situation
TENANT_FOUNDERand checks that each one existsa missing role:FAILED -
2CIAS→Keycloakmark the address verified, enable the account, require "set a password"
-
3CIAS→Keycloakcreate the organization: alias
nordbau-gmbh, name "Nordbau GmbH" -
4CIAS→Databasecreate the tenant
nordbau-gmbh, typeDYNAMIC, pointing at the organization. In MULTI the tenant's database is provisioned here -
5CIAS→KeycloakAnna becomes a member of the organization
-
6CIAS→Keycloakset the attributes
tenantandallowedTenantson the account tonordbau-gmbh -
7CIAS→Keycloakgrant the initial roles, inside the organization, on this installation's client
-
8HookCIAS records the user and sets it to
ACTIVE, then your own hooks run -
9CIAS→Emailwelcome mail, with a password link where possibleResult: Registration
COMPLETED. Anna can sign in
If one of these steps fails, the registration ends in FAILED. A platform administrator then repeats it with retry or discards it with discard. Details: What happens on completion.
The two state sequences side by side
Registration and tenant have their own states. They are connected, but they are not the same thing. A registration is a process that ends; a tenant is a customer that stays.
| Moment | Registration | Tenant: standing | Tenant: rollout |
|---|---|---|---|
| form submitted | PENDING_VERIFICATION | does not exist yet | – |
| link clicked | VERIFIED | does not exist yet | – |
| waiting for approval | PENDING_APPROVAL | does not exist yet | – |
| approved | APPROVED → PROVISIONING | does not exist yet | – |
| record written | PROVISIONING | PENDING | IN_PROGRESS |
| database provisioned | PROVISIONING | ACTIVE | PROVISIONED |
| roles, user record, mail | COMPLETED | ACTIVE | PROVISIONED |
So the tenant comes into being only in the last block and is ACTIVE moments later. It is served as soon as its standing is ACTIVE and today’s date is inside its validity window. Every state on its own: The states of a registration and The lifecycle of a tenant.
The password and the first login
CIAS never sees a password. The welcome mail carries a link to Keycloak’s own password page; where no link can be issued, the mail points at the login instead and Anna uses “forgot password” there.
-
1User→Keycloaksets the password on Keycloak's own page
-
2User→Keycloaksigns in
-
3Keycloak→Clientissues the token: claim
organizationwithnordbau-gmbh, the attributestenantandallowedTenants, the initial roles inside the organizationResult: The BFF holds the token and sends it with every request
Details: Set the password, Sign in in the browser, Resend the password setup link.
The first request to CDMS
-
CIASCheck the tokenIs the token valid and not expired?↳ no 401
-
CIASResolve the tenantExactly one organization in the token →
nordbau-gmbh↳ no 403cias.authentication.tenant-unresolved -
CIASTenant gateIs
nordbau-gmbhserved, that isACTIVEand inside its validity window?↳ no 403cias.authentication.tenant-not-served -
CIASEffective rolesDoes Anna have roles in the organization? Then only those apply
-
CDMSModel roleDoes one of her effective roles allow reading this model?↳ no 403
-
CDMSDatabaseIn MULTI: the database of
nordbau-gmbh - The list comes back – empty, because the tenant is new
The full path is described by From login to the data.
What the founder can do – and what the installation has to set up for it
The initial roles are not fixed code, they are a rule set. What the founder can do on day one therefore depends on what the installation wrote into that rule set.
| What she wants to do | What it depends on | What it takes |
|---|---|---|
| sign in and work in her tenant | membership in the organization | created during provisioning, so it is there |
| read and create data in CDMS | model roles of CDMS | The installation's initial-role rule has to name them. The shipped default grants only tenant-owner, tenant-admin and tenant-user |
| invite a colleague | the roles in required-caller-roles of the flow TENANT_ADMIN | shipped that is tenant-admin, and the founder gets it with her initial roles |
| grant a colleague a role | delegation in the role catalog and the ceiling | Shipped: she can grant tenant-user and tenant-admin, because both are delegated to her roles and she holds them herself. Only a platform administrator grants tenant-owner. For further roles, for example from CDMS, the installation has to set up delegation and initial roles |
| create or suspend tenants | a platform role | only a platform administrator may, never a tenant administration |
So the founder can run her tenant on her own from day one. If she should also work with the data, the installation writes an installation rule for the situation TENANT_FOUNDER with the model roles and records the matching delegations in the role catalog. Both are deliberate decisions of the platform, not a side effect of the registration.
Details: Initial roles as a rule set, Grant a role, The role catalog, The ceiling.
The variants
When: The installation sets approval-required: false, as the hub does.
Block 2 falls away. After the click on the link provisioning starts immediately, and the welcome mail arrives seconds later.
Result: Whoever works this way needs another guard against tenants created in bulk, for example a front end that works only with an invite code.
When: CDMS_TENANT_MODE=MULTI and the CDMS persistence runs in the same process.
Creating the tenant creates the database nordbau-gmbh and migrates its schema. That takes seconds to minutes and happens before the welcome mail.
Result: The customer's first request meets a finished database. See Databases, pools, migration.
When: CDMS_TENANT_MODE=SINGLE, or CIAS runs as its own service without CDMS persistence.
Provisioning has nothing to do and reports success at once. With a standalone CIAS, CDMS creates the database later, on the first request.
Result: The tenant is ACTIVE immediately. In SINGLE it plays no part in requests, see In SINGLE the tenant in the token does not count.
When: Anna's address already has an account, with another customer for instance.
CIAS creates no second account and changes nothing about the existing one, not even the password. Instead of the confirmation mail she gets a mail that leads to joining. When she redeems the link, the new tenant comes into being and her existing account becomes its founder. The answer to the form is the same as for a new address.
Result: See The email is the account.
When: A tenant nordbau-gmbh already exists.
Already when the form is submitted, CIAS tries nordbau-gmbh-2 through -20. The display name stays "Nordbau GmbH".
Result: See The tenant key.
When: Keycloak is unreachable, an initial role is missing, or one of your own hooks throws.
The registration goes to FAILED. The person gets no mail. The error hits the request that triggered provisioning – here the administrator's approve call.
Result: A platform administrator fixes the cause and calls retry, or discards the registration with discard.
When: An installation sets tenant-assignment: NONE.
No tenant and no organization come into being. The person gets the roles of the situation TENANTLESS. The field company is then not needed.
Result: Useful only where a human assigns the tenant afterwards.