zitadel: Domain discovery (identity brokering) doesn't work

Describe the bug I’m trying to set up domain discovery so that organizations can have different branding/IDPs but keeping a single login page.

I followed the guide on identity brokering, but I can’t get ZITADEL to show the correct login page after entering the username.

To Reproduce I created the following resources (n.b.: private_labeling_setting and user_login)

terraform {
  required_providers {
    zitadel = {
      source  = "zitadel/zitadel"
      version = "1.0.0-alpha.8"
    }
  }
}

resource "zitadel_org" "main_org" {
  name = "Main Org"
}

resource "zitadel_project" "main_project" {
  depends_on = [zitadel_org.main_org]

  org_id = zitadel_org.main_org.id

  name                     = "main-project"
  project_role_assertion   = true
  project_role_check       = true
  has_project_check        = true
  private_labeling_setting = "PRIVATE_LABELING_SETTING_ALLOW_LOGIN_USER_RESOURCE_OWNER_POLICY"
}

resource "zitadel_application_oidc" "application_oidc" {
  depends_on = [zitadel_org.main_org, zitadel_project.main_project]

  org_id     = zitadel_org.main_org.id
  project_id = zitadel_project.main_project.id

  name                        = "webapp"
  redirect_uris               = ["http://localhost:8080"]
  response_types              = ["OIDC_RESPONSE_TYPE_CODE"]
  grant_types                 = ["OIDC_GRANT_TYPE_AUTHORIZATION_CODE", "OIDC_GRANT_TYPE_REFRESH_TOKEN"]
  post_logout_redirect_uris   = ["http://localhost:8080"]
  app_type                    = "OIDC_APP_TYPE_WEB"
  auth_method_type            = "OIDC_AUTH_METHOD_TYPE_NONE"
  version                     = "OIDC_VERSION_1_0"
  clock_skew                  = "0s"
  dev_mode                    = true
  access_token_type           = "OIDC_TOKEN_TYPE_BEARER"
  id_token_role_assertion     = true
  id_token_userinfo_assertion = true
}

variable "google_oidc_client_id" {
  type      = string
  sensitive = true
}

variable "google_oidc_client_secret" {
  type      = string
  sensitive = true
}

resource "zitadel_org_oidc_idp" "google_oidc" {
  depends_on = [zitadel_org.main_org]

  org_id               = zitadel_org.main_org.id
  name                 = "Google"
  styling_type         = "STYLING_TYPE_GOOGLE"
  client_id            = var.google_oidc_client_id
  client_secret        = var.google_oidc_client_secret
  issuer               = "https://accounts.google.com"
  scopes               = ["openid", "profile", "email"]
  display_name_mapping = "OIDC_MAPPING_FIELD_EMAIL"
  username_mapping     = "OIDC_MAPPING_FIELD_EMAIL"
  auto_register        = true
}

resource "zitadel_login_policy" "login_policy" {
  depends_on = [zitadel_org.main_org, zitadel_org_oidc_idp.google_oidc]

  org_id                        = zitadel_org.main_org.id
  allow_external_idp            = true
  allow_register                = true
  default_redirect_uri          = "localhost:8080"
  external_login_check_lifetime = "240h0m0s"
  force_mfa                     = false
  hide_password_reset           = true
  idps                          = [zitadel_org_oidc_idp.google_oidc.id]
  ignore_unknown_usernames      = true
  mfa_init_skip_lifetime        = "720h0m0s"
  multi_factor_check_lifetime   = "12h0m0s"
  multi_factors                 = ["MULTI_FACTOR_TYPE_U2F_WITH_VERIFICATION"]
  password_check_lifetime       = "240h0m0s"
  passwordless_type             = "PASSWORDLESS_TYPE_NOT_ALLOWED"
  second_factor_check_lifetime  = "18h0m0s"
  second_factors                = ["SECOND_FACTOR_TYPE_OTP", "SECOND_FACTOR_TYPE_U2F"]
  user_login                    = false
}

resource "zitadel_domain" "domain" {
  depends_on = [zitadel_org.main_org]

  org_id = zitadel_org.main_org.id

  name = "localhost.com"
}

resource "zitadel_human_user" "human_user" {
  depends_on = [zitadel_org.main_org]

  org_id = zitadel_org.main_org.id

  user_name         = "human"
  first_name        = "firstname"
  last_name         = "lastname"
  display_name      = "displayname"
  email             = "human@localhost.com"
  is_email_verified = true
  initial_password  = "Password1!"
}

Expected behaviour ZITADEL should match the domain localhost.com and present Google as IPD (as if passing the primary domain as a scope, which works)

Screenshots

Screenshot 2022-09-13 at 20 20 08 Screenshot 2022-09-13 at 20 20 14

Additional context ZITADEL 2.4.0

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 21 (11 by maintainers)

Most upvoted comments

So I will close this issue, feel free to reopen or open a new one if you still have some other problems

Ok, so I think in here are two action items then:

  • Our “Domains” feature should be allowed to use as discovery feature based on the domainname
  • After the discovery the user needs to be able to register and not only login.

@hifabienne @livio-a @adlerhurst what do you think of this… my2cents are the following

  • Iteration of domains is fine with me… i see no way of avoiding that 😁
  • We should allow register after discovery
  • Chjange the behaviour of domain in this direction makes sense (actually I think we should allow customers to decide if domains are used for discovery and/or suffix of usernames)

In terms of urgency: this is currently blocking the onboarding of SSO customers (since they require a dedicated IDP Got it, we keep that in mind to raise the prio!

At the moment what you try to achieve is only possible with the primary domain scope. We do not have this on our roadmap right now. This Thursday we will have an internal meeting about some topics on how to improve the login flow. We will discuss this also and I will give you feedback after.

Hi @DavideWalder

If I understand it correct, what you try to do is at the moment not possible. We do not have the feature to link an existing user that has a local user right now, after entering the username. The way to do this right now, is to click on the idp (e.g Google) button on the first screen, where you now enter the username. Then the user will be redirected to the idp. After authentication he gets back to the zitadel login screen and if we find no linkt user, we will show the option to link an existing user or register a new one. If auto register we create automatically a new user.