What this is about
CIAS sends emails to people when something happens in the life of an account: a registration starts, waits for approval, is finished, or an administrator sends a link to set a password. Each email has a fixed key, such as VERIFY_EMAIL. Through this key CIAS finds the template, that is, the text with placeholders.
Emails that Keycloak sends itself, such as “forgot password”, are not part of this. They are designed by whoever runs the realm, in the Keycloak theme.
All emails at a glance
| Key | Occasion | Link in the email | Subject (German template) |
|---|---|---|---|
VERIFY_EMAIL | a registration for a new address starts | verificationUrl, confirms the address | Bitte bestätigen Sie Ihre E-Mail-Adresse |
MEMBERSHIP_INVITATION | an existing account is to join a tenant | verificationUrl, confirms joining | Sie wurden zu einem Bereich eingeladen |
INVITATION | template for an invitation in which the person completes their details themselves | verificationUrl | Einladung: Bitte vervollständigen Sie Ihre Angaben |
ALREADY_REGISTERED | someone registers an address that already has an account, and there is no tenant to join | loginUrl, to log in | Zu dieser Adresse besteht bereits ein Konto |
APPROVAL_PENDING | the address is confirmed, now an administrator must approve | none | Ihre Registrierung wird geprüft |
REJECTED | an administrator rejected the registration | none, optionally with reason reason | Ihre Registrierung wurde abgelehnt |
WELCOME | the registration is finished, the account is set up | passwordUrl for a new account, otherwise loginUrl | Willkommen |
PASSWORD_SETUP | an administrator sends a link to set the password | passwordUrl | Passwort für Ihr Konto festlegen |
SWITCH_CONSENT_REQUESTED | somebody asks to be allowed to work on your behalf | consentUrl, if set | {Name} bittet um Zugriff auf Ihr Konto |
SWITCH_CONSENT_USED | a consent to a user switch is used for the first time | consentUrl, if set | {Name} nutzt jetzt Ihre Freigabe |
The emails of a registration
-
1CIAS→Emailrequest accepted:
VERIFY_EMAIL(new address),MEMBERSHIP_INVITATION(existing account, tenant to join) orALREADY_REGISTERED(existing account, no tenant) -
2User→CIASclicks the link
-
3CIASMust an administrator approve?
-
4CIAS→Emailyes:
APPROVAL_PENDING. Later, on rejection,REJECTED -
5CIAS→Emailafter provisioning:
WELCOMEResult: Account ready, the person gets the link to set the password or to log in
Why does an existing account without a tenant get ALREADY_REGISTERED instead of an error? The answer to the registering side is the same in both cases. So nobody can find out from outside which addresses already have an account. Only the email to the address itself says so. See The email is the account.
The variants
When: Self-registration, creation by an administrator, or invitation of a new address.
The link confirms the address. Only then is the account enabled. How long the link is valid is set by the flow, see Verify the email.
Result: link verificationUrl
When: The address already has an account, and the registration names a tenant.
The person confirms that they want to join. No new account is created.
Result: link verificationUrl
When: An installation wants to word an invitation differently.
CIAS ships the template, and in standalone CIAS tenant administrators may edit it. The registration flow sends an invitation to a new address as VERIFY_EMAIL, with the flow as variant, see How the right template is found.
Result: link verificationUrl
When: The address already has an account, and there is no tenant to join.
The email says that the account already exists and offers to log in.
Result: link loginUrl
When: The flow requires approval, the address is confirmed.
This tells the person that they need to do nothing more. See Approval by an administrator.
Result: no link
When: An administrator rejects the registration.
If the administrator gives a reason, it appears in the email. Without a reason the paragraph is left out.
Result: no link, optional reason
When: Provisioning is finished.
For a new account it contains, if the installation has set this up, a link to set the password. Otherwise it points to the login and to "forgot password". If only this email fails, the registration is still finished.
Result: passwordUrl or loginUrl
When: An administrator sends a person a new link to set the password.
Only if the installation has set up password links. See Resend the password setup link.
Result: link passwordUrl
When: Somebody with the role allowed-user-context-switch asks a person for consent.
The email says who is asking, with whose permissions, until when and why. A second identical request sends no second email. If sending fails, the request stays anyway.
Result: consentUrl, if the installation has set an address
When: A consent is used for a switch for the first time.
Goes once per consent to the person who gave it. If sending fails, the switch goes through anyway.
Result: consentUrl, if set
What is available in every email
A template fills placeholders from a context, a list of names and values. Registration emails always have:
| Placeholder | Content |
|---|---|
email | the person’s address |
registrationId | the ID of the registration |
verificationUrl | the verification link, empty where there is none |
loginUrl | the login page of the application the person came from |
passwordUrl | the link to set the password, empty where there is none |
reason | only for REJECTED: the reason, may be empty |
Links that do not exist are empty, but always present. So a template does not have to check whether a placeholder exists. A registration hook can add further values, such as a brand name, see Sending and branding. PASSWORD_SETUP only knows passwordUrl and displayName.
The two consent emails know requesterName and requesterEmail or granteeName and granteeEmail, plus targetRoles (true or false), validUntil (empty means no end), reason, tenantKey and consentUrl.
Every email also has application and flow: which product the person came from and through which flow. Both are empty where the sender knows nothing about them. A template branches on them instead of needing templates of its own, see How the right template is found.