CodamAIDocs
Topicdone

Import existing accounts

How CIAS imports Keycloak accounts it does not know yet as users.

Variants
unknown active accountunknown, inactive accountalready knownskipped (several organizations, address taken)

What this is about

Not every account is created through CIAS registration. Some existed before CIAS was introduced, others were created by an operator in the Keycloak console. CIAS does not know such accounts: there is no user record, so they do not appear in any list and cannot be suspended.

The import creates records for these accounts.

The set diagram

flowchart LR
    subgraph K["Accounts in Keycloak"]
      direction TB
      A["already known in CIAS"]
      B["unknown, active"]
      C["unknown, inactive"]
      D["unknown, but cannot be imported"]
    end
    A -- "stays unchanged" --> R1["alreadyKnown"]
    B -- "record, ACTIVE" --> R2["activated"]
    C -- "record, PENDING" --> R3["recorded"]
    D -- "with reason" --> R4["skipped"]

The flow

POST /cias/admin/users/import
  1. 1
    Admin→CIAS
    starts the import, without a body
  2. 2
    CIAS
    Platform administrator?
    otherwise 403
  3. 3
    CIAS→Keycloak
    reads all accounts, in pages of 200
  4. 4
    CIAS
    For each account: already known? Then skip to the next
  5. 5
    CIAS
    Determine the home tenant, create the record, set it to ACTIVE if the account is active
  6. 6
    CIAS→Admin
    Report

The import only runs when you trigger it, never on its own. The hub’s admin UI offers a button for this in the user list.

What happens to each account

Four cases

When: The account is enabled in Keycloak and the address is verified.

CIAS creates a record and sets it to ACTIVE. The display name comes from first and last name.

Result: Counts as recorded and activated.

When: The account is disabled or the address is not verified.

CIAS creates a record, but leaves it at PENDING.

Result: Counts as recorded.

When: A record already exists for the account.

Nothing happens. The import does not overwrite an existing record.

Result: Counts as alreadyKnown.

When: The account cannot be assigned unambiguously.

Two reasons: the account is a member of several organizations, so there is no clear home tenant. Or the address already belongs to another account in CIAS.

Result: Listed in skipped with address and reason.

The home tenant

CIAS reads the home tenant from the membership in an organization: if the account is a member of exactly one organization, its alias becomes the home tenant. Without an organization, the person gets no home tenant.

The report

Request
POST /cias/admin/users/import
Response
{
  "found": 120,
  "recorded": 14,
  "activated": 12,
  "alreadyKnown": 104,
  "skipped": [
    { "email": "ben@example.org", "reason": "belongs to several organizations (nordbau, suedlogistik)" },
    { "email": "cara@example.org", "reason": "…" }
  ]
}
FieldMeaning
foundaccounts in Keycloak
recordednewly created records, including the activated ones
activatedof these, set to ACTIVE right away
alreadyKnownalready known before
skippednot imported, with reason

Each account is saved on its own. If a run aborts, you simply start it again. Accounts that were already imported then count as alreadyKnown.

Next

Sources in the code and the knowledge base
  • CIAS/cias-user – UserImportService, UserImportUseCase, ImportReport, UserAdminController (import)
  • CIAS/cias-iam-keycloak – KeycloakIdentityAdapter (list), CIAS/cias-iam-api – IamIdentity (isUsable)
  • hub-frontend – server/api/hub/identity/users/import.post.ts
Search