CodamAIDocs
Topicdone

A colleague is invited

The administrator invites a colleague. The colleague confirms, sets her password and sees the data of her tenant, but only the data her roles allow.

Variants
colleague is newcolleague already has an account with another customerlink expiredclicked twicecaller without the role or without a tenant

What this is about

Anna administers the tenant nordbau. She wants to bring Bea in. CIAS has no separate mechanism for that: an invitation is an ordinary registration, only in the variant TENANT_ADMIN – the administrator starts it, and the invited person finishes it.

Who may invite

ConditionWhere it comes from
The variant TENANT_ADMIN is switched onthe installation’s configuration
The caller holds every role in required-caller-rolesconfiguration; in cias-runtime that is tenant-admin
The caller has a tenant in the tokenthe token itself

The tenant of the invitation is the caller’s tenant. A tenantKey in the payload is discarded without being checked. That way nobody can invite into somebody else’s tenant.

The flow

sequenceDiagram
    participant A as Anna (tenant-admin, nordbau)
    participant C as CIAS
    participant K as Keycloak
    participant M as Email
    participant B as Bea
    A->>C: POST /cias/tenant/registrations<br/>email, firstName, lastName
    C->>C: check the role, tenant from the token: nordbau
    C->>C: is there already an account for that address?
    C->>K: only if not: create the account disabled
    C->>M: mail with a one-time link to /registration/verify
    C-->>A: 202 accepted
    M-->>B: mail
    B->>C: opens the link and redeems it
    C->>K: membership in nordbau, attributes, member roles
    C->>C: user record, registration COMPLETED
    C->>M: welcome mail
    B->>K: signs in

Anna does not learn from the answer whether Bea already has an account: both cases answer 202 accepted. Only the mail differs, and only Bea sees it.

The two cases

Bea is new – or Bea already has an account

When: There is no account for Bea's address, at most the leftover of an abandoned attempt (disabled in Keycloak and the address never verified).

  1. 1
    CIAS→Keycloak
    creates the account disabled and unverified
  2. 2
    CIAS→Email
    sends the mail "confirm your address" with the one-time link
  3. 3
    User→CIAS
    redeems the link
  4. 4
    CIAS→Keycloak
    address verified, enable the account, require "set a password"
  5. 5
    CIAS→Keycloak
    member of nordbau, attributes tenant and allowedTenants, member roles

Result: Bea sets her password at Keycloak and signs in. Registration kind NEW_ACCOUNT.

When: Bea's address already belongs to an account, because she works for suedlogistik for instance.

  1. 1
    CIAS
    creates no second account and changes nothing about the existing one, not even the password
  2. 2
    CIAS→Email
    sends the mail "invitation to another tenant" with the one-time link
  3. 3
    User→CIAS
    redeems the link
  4. 4
    CIAS→Keycloak
    member of nordbau, in addition to her existing memberships. The attributes tenant and allowedTenants are set to nordbau
  5. 5
    CIAS→Keycloak
    member roles, inside the organization nordbau

Result: Bea signs in as usual, with her old password, and now works in two tenants. Registration kind ADDITIONAL_MEMBERSHIP. See One person in two tenants.

What differs
colleague is newcolleague already has an account
Kind of registrationNEW_ACCOUNTADDITIONAL_MEMBERSHIP
Account in Keycloakcreated disabled and enabled after the clickstays untouched
Mail"confirm your address""invitation to another tenant"
Passwordhas to be set, CIAS never sees itstays as it is; no password link is sent
After redeemingmember of nordbaumember of nordbau and of her existing tenants
User record in CIAScreated, with nordbau as the home tenantstays as it is, the home tenant does not change

What Bea does from the mail

In both cases the link in the mail points at the same page: /registration/verify?token=…. That page can do two things:

From the link to the membership
  1. 1
    User→Frontend
    opens the link from the mail
  2. 2
    Frontend→CIAS
    GET /cias/registration/invitations/{token}/form shows which fields Anna left open
  3. 3
    Frontend→CIAS
    POST /cias/registration/verify with the token – the endpoint /invitations/accept does exactly the same
  4. 4
    CIAS
    Does the token exist, and has it not expired?
    no: 404 cias.registration.not-found
  5. 5
    CIAS
    registration → VERIFIED, then provisioning right away. The flow TENANT_ADMIN requires no approval
    Result: 202 accepted, then the welcome mail

Redeeming takes only the token. Details Anna did not provide stay empty; the display name in the user record is built from first and last name and otherwise falls back to the address.

How long the link is valid is set by the flow’s configuration (token-ttl). In cias-runtime it is 14 days.

What Bea may see afterwards

On redeeming, Bea gets the roles of the situation TENANT_MEMBER – not those of a founder. An invitation must not hand out tenant administration.

LevelWhat applies
Initial rolesthe rule of the tenant nordbau, else the installation rule, else the default. Shipped: tenant-user
Where the roles sitnordbau is a dynamic tenant, so inside the organization. With a static tenant they are granted globally
Effective rolesif Bea has roles in nordbau, they replace her global client roles. Realm roles always apply
Data in CDMSmodel roles decide which models she sees at all; attribute filters and the owner filter cut the rows down
Bea's first request
  1. CIAS
    Resolve the tenant
    Is Bea in several organizations? Then the client has to select one
    ↳ no 403 cias.authentication.tenant-unresolved
  2. CIAS
    Tenant gate
    Is nordbau served?
    ↳ no 403 cias.authentication.tenant-not-served
  3. CIAS
    Effective roles
    Roles in nordbau replace the global ones
  4. CDMS
    Model role
    Does one of her effective roles allow this model?
    ↳ no 403
  5. CDMS
    Row filter
    attribute filter, owner filter, tenant isolation
  6. Bea sees nordbau's data, as far as her roles reach

More on that: Effective roles, Initial roles as a rule set, The three levels at a glance.

If Anna wants to give Bea more than the initial roles, she grants a role through POST /cias/admin/role-assignments. That works only if the role is a tenant role, is delegated to a role Anna holds, is granted in her own tenant, and Anna holds it herself. See Grant a role.

When the invitation does not work

Refusals
roles from required-caller-rolestenant in the caller's tokentoken of the invitationWhat happens
missing––403 cias.registration.not-authorized
presentmissing–403 cias.registration.not-authorized – without a tenant it is unclear where the invitation leads
presentpresentunknown or expired404 cias.registration.not-found – both cases look the same
presentpresentalready redeemed202, as the first time. A second click must not produce an error
presentpresentvalidBea becomes a member

Watch out

Next

Sources in the code and the knowledge base
  • CIAS/cias-registration – RegistrationAdminController (POST /cias/tenant/registrations), RegistrationController (GET /invitations/{token}/form, POST /invitations/accept, POST /verify)
  • CIAS/cias-registration – RegistrationService (register, authorize, resolveTenant, mailPurpose, tokenPurpose, supersedeOpenAttempts, provision, assignTenant, writeTenantAttributes, grantRoles), RegistrationKind, RegistrationSituation, RegistrationLinks
  • CIAS/cias-user – RegistrationUserHook, UserService.record/activate
  • CIAS/cias-authentication – EffectiveRoles.resolve, OrganizationTenantResolver
  • CIAS/cias-runtime – application.yml (flows.TENANT_ADMIN), CiasRegistrationRoleConfiguration
Search