CodamAIDocs
Topicdone

A new customer is set up

A company registers itself, gets approved, receives its tenant and its first administrator, who immediately creates data.

Variants
with approvalwithout approvalMULTI: own databaseSINGLE: no own databaseaddress already knownkey already takenprovisioning fails

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

WhoWhat they do in this case
Anna Bergfills in the form, clicks the link, sets her password, creates the first data
CIASruns the registration, creates tenant and organization, grants the initial roles
Keycloakholds the account, the organization and later the token
Platform administratorapproves the registration
Persistence (CDMS)creates the tenant’s database and migrates its schema
CDMSreturns 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

From the form to the click
  1. 1
    User→CIAS
    submits the form. email and company are mandatory, there is no password field
  2. 2
    CIAS
    checks the throttle: at most 10 attempts per address in 10 minutes
  3. 3
    CIAS
    derives the tenant key from company. "Nordbau GmbH" becomes nordbau-gmbh
  4. 4
    CIAS→Keycloak
    creates the account disabled and unverified
  5. 5
    CIAS→Email
    sends the confirmation mail. Only the hash of the link is stored
  6. 6
    CIAS→User
    answers 202 { "status": "accepted" } – the same answer whether or not the address is new
  7. 7
    User→CIAS
    clicks the link. In cias-runtime it is valid for 24 hours and only once
    Result: Registration VERIFIED. 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).

The approval
  1. 1
    CIAS
    registration → PENDING_APPROVAL, the person gets the mail APPROVAL_PENDING
  2. 2
    Admin→CIAS
    finds the registration through GET /cias/admin/registrations?state=PENDING_APPROVAL
  3. 3
    CIAS
    checks that the caller is a platform administrator
    A tenant administrator may not approve
  4. 4
    Admin→CIAS
    approve – and provisioning starts in the same call
    Result: 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

Provisioning, in this order
  1. 1
    CIAS
    determines the initial roles for the situation TENANT_FOUNDER and checks that each one exists
    a missing role: FAILED
  2. 2
    CIAS→Keycloak
    mark the address verified, enable the account, require "set a password"
  3. 3
    CIAS→Keycloak
    create the organization: alias nordbau-gmbh, name "Nordbau GmbH"
  4. 4
    CIAS→Database
    create the tenant nordbau-gmbh, type DYNAMIC, pointing at the organization. In MULTI the tenant's database is provisioned here
  5. 5
    CIAS→Keycloak
    Anna becomes a member of the organization
  6. 6
    CIAS→Keycloak
    set the attributes tenant and allowedTenants on the account to nordbau-gmbh
  7. 7
    CIAS→Keycloak
    grant the initial roles, inside the organization, on this installation's client
  8. 8
    Hook
    CIAS records the user and sets it to ACTIVE, then your own hooks run
  9. 9
    CIAS→Email
    welcome mail, with a password link where possible
    Result: 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.

MomentRegistrationTenant: standingTenant: rollout
form submittedPENDING_VERIFICATIONdoes not exist yet–
link clickedVERIFIEDdoes not exist yet–
waiting for approvalPENDING_APPROVALdoes not exist yet–
approvedAPPROVED → PROVISIONINGdoes not exist yet–
record writtenPROVISIONINGPENDINGIN_PROGRESS
database provisionedPROVISIONINGACTIVEPROVISIONED
roles, user record, mailCOMPLETEDACTIVEPROVISIONED

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.

From the password to the token
  1. 1
    User→Keycloak
    sets the password on Keycloak's own page
  2. 2
    User→Keycloak
    signs in
  3. 3
    Keycloak→Client
    issues the token: claim organization with nordbau-gmbh, the attributes tenant and allowedTenants, the initial roles inside the organization
    Result: 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

Anna's first list
  1. CIAS
    Check the token
    Is the token valid and not expired?
    ↳ no 401
  2. CIAS
    Resolve the tenant
    Exactly one organization in the token → nordbau-gmbh
    ↳ no 403 cias.authentication.tenant-unresolved
  3. CIAS
    Tenant gate
    Is nordbau-gmbh served, that is ACTIVE and inside its validity window?
    ↳ no 403 cias.authentication.tenant-not-served
  4. CIAS
    Effective roles
    Does Anna have roles in the organization? Then only those apply
  5. CDMS
    Model role
    Does one of her effective roles allow reading this model?
    ↳ no 403
  6. CDMS
    Database
    In MULTI: the database of nordbau-gmbh
  7. 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 the founder can do
What she wants to doWhat it depends onWhat it takes
sign in and work in her tenantmembership in the organizationcreated during provisioning, so it is there
read and create data in CDMSmodel roles of CDMSThe installation's initial-role rule has to name them. The shipped default grants only tenant-owner, tenant-admin and tenant-user
invite a colleaguethe roles in required-caller-roles of the flow TENANT_ADMINshipped that is tenant-admin, and the founder gets it with her initial roles
grant a colleague a roledelegation in the role catalog and the ceilingShipped: 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 tenantsa platform roleonly 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

How the case can deviate

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.

Watch out

Next

Sources in the code and the knowledge base
  • CIAS/cias-registration – RegistrationService (register, verify, approve, provision, assignTenant, writeTenantAttributes, grantRoles), RegistrationState, RegistrationSituation, SlugTenantKeyFactory
  • CIAS/cias-registration – RegistrationController (/self, /verify), RegistrationAdminController (approve, retry, discard)
  • CIAS/cias-tenancy – TenantService (createTenant, rollOut), Tenant (TenantStatus, ProvisioningState)
  • CIAS/cias-user – RegistrationUserHook, UserService.record/activate
  • CIAS/cias-authentication – TokenParser.admit, OrganizationTenantResolver, TenantGate, EffectiveRoles
  • CIAS/cias-runtime – application.yml (flows.SELF_SERVICE, flows.TENANT_ADMIN), CiasRegistrationRoleConfiguration, CiasIdentityRegistry
  • commons-persistence – TenantProvisioningPort, DatabaseTenantProvisioningAdapter
Search