Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

“unable to create provider: oidc: issuer did not match the issuer returned by provider” with keycloak idp #25024

Open
ptrovatelli opened this issue Jan 24, 2024 · 6 comments
Labels
auth/jwt-oidc bug Used to indicate a potential bug ecosystem

Comments

@ptrovatelli
Copy link

ptrovatelli commented Jan 24, 2024

Describe the bug
When configuring a jwt_auth_backend in vault with a provider that vault reaches through a different URL than the issuer URL, vault fails with unable to create provider: oidc: issuer did not match the issuer returned by provider

To Reproduce
When configuring vault with keycloak IPD so that keycloak authenticates vault users through oidc, we have a problem with a verification that vault makes on the issuer field.
We have a specific setup with keycloak:

  • Vault reaches keycloak through a private network (backend url)
  • end users reach keycloak from a public network (frontend url)

With this setup, keycloak considers the issuer as a frontend element: in the .well-known/openid-configuration discovery URL, the issuer field is https://<frontend-keycloak-hostname>/auth/realms/myrealm

Upon initializing the oidc configuration (when building the auth backend), vault makes a verification about the issuer that makes the process fail : it seems that vault is trying to guess what the issuer should be by concatenating

  • the hostname vault is using to reach keycloak : https://<backend-keycloak-hostname>
  • with the path configured in the oidc_discovery_url: /auth/realms/myrealm

We can see in vault logs:

2024-01-16T11:57:12.474+0100 [ERROR] auth.oidc.auth_oidc_xxxx: error checking oidc discovery URL: error="error creating provider with given values: NewProvider: 
	unable to create provider: oidc: issuer did not match the issuer returned by provider, 
	expected \"https://<backend-keycloak-hostname>/auth/realms/myrealm\"
	     got \"https://<frontend-keycloak-hostname>/auth/realms/myrealm\""

The assumption that the issuer must have the same hostname as the oidc_discovery_url address is incorrect when the idp can be reached from different URLS.

The error appears even when bound_issuer is configured in the auth backend. Vault could simply compare the value of bound_issuer with the issuer given by the discovery URL in that case rather than assuming what the issuer hostname should be.

Setup:
vault (terraform)

resource "vault_jwt_auth_backend" "keycloak" {
  description        = "Keycloak"
  path               = "oidc"
  type               = "oidc"
  oidc_discovery_url = "https://<backend-keycloak-hostname>/auth/realms/myrealm"
  bound_issuer       = "https://<frontend-keycloak-hostname>/auth/realms/myrealm"
  oidc_client_id     = var.keycloak_client_id
  oidc_client_secret = var.keycloak_client_secret
  default_role       = "default-keycloak"
  tune {
    default_lease_ttl            = "2h"
    max_lease_ttl                = "8h"
    allowed_response_headers     = []
    audit_non_hmac_request_keys  = []
    audit_non_hmac_response_keys = []
    listing_visibility           = "unauth"
    passthrough_request_headers  = []
    token_type                   = "default-service"
  }
}

resource "vault_jwt_auth_backend_role" "default_keycloak" {
  backend        = vault_jwt_auth_backend.keycloak.path
  role_name      = "default-keycloak"
  token_policies = ["default"]

  user_claim            = "xxx"
  groups_claim          = "groups"
  role_type             = "oidc"
  allowed_redirect_uris = var.oidc_authorized_redirects
  verbose_oidc_logging  = true
}

keycloak:

  • KC_HOSTNAME_STRICT=false : backend urls are built based on the request
  • KC_HOSTNAME_URL=https://<frontend-keycloak-hostname>/auth : The front-end url is forced in keycloak with so that end users are not redirected to the backend URL

With this setup, accessing to https://<backend-keycloak-hostname>/auth/realm/myrealm/.well-known/openid-configuration displays the issuer as https://<frontend-keycloak-hostname>/auth/realm/myrealm

Issue could be circumvented by making vault access keycloak through the public URL https://<frontend-keycloak-hostname> but it’s not what we want to do from a network point of view.

Another solution would be to not use the discovery URL but jwks_url instead but that doesn't seem to be working at the moment: see

FYI related discussions on keycloak side:

Expected behavior
Vault should be able to log users authenticated through keycloak using oidc

Environment:

  • hashicorp vault 1.15.4+ent
  • keycloak 23.0.4

Additional context

@phmcder
Copy link

phmcder commented Jan 27, 2024

I've just hit the same problem as well when deploying to docker desktop. I can't connect to keycloak using the public host name as that keeps getting resolved to 127.0.0.1. As above, I set the oidc_discovery_url to the internal host name but I get the miss match issuer error message

@ptrovatelli
Copy link
Author

quick update on this issue. i'm in contact with hashicorp support. What we've established so far:

@Aladex
Copy link

Aladex commented Oct 21, 2024

I encountered an issue where Vault needed to resolve the Keycloak domain (keycloak.example.com) to an internal IP, but the domain points to an external IP. Here's how I solved it:

  1. Using hostAliases:
    I added a hostAliases entry on one of the nodes. Since my NGINX ingress is running as a DaemonSet with hostNetwork: true, this allowed Vault to resolve keycloak.example.com to the internal IP.

  2. Alternative solution with a Service:
    Another approach is to create a Service that either points directly to Keycloak or to the NGINX ingress. By assigning a static IP to this Service, you can reference it from Vault and avoid exposing NGINX externally, while still ensuring that traffic is routed to Keycloak internally.

@heatherezell heatherezell added auth/jwt-oidc ecosystem bug Used to indicate a potential bug labels Oct 23, 2024
@heatherezell
Copy link
Contributor

heatherezell commented Oct 23, 2024

quick update on this issue. i'm in contact with hashicorp support. What we've established so far:

Were you able to get support on this? Would you be willing to share the ticket ID with me? You can email it to me, my full name at hashicorp dot com. Thanks!

@ptrovatelli
Copy link
Author

I encountered an issue where Vault needed to resolve the Keycloak domain (keycloak.example.com) to an internal IP, but the domain points to an external IP. Here's how I solved it:

  1. Using hostAliases:
    I added a hostAliases entry on one of the nodes. Since my NGINX ingress is running as a DaemonSet with hostNetwork: true, this allowed Vault to resolve keycloak.example.com to the internal IP.
  2. Alternative solution with a Service:
    Another approach is to create a Service that either points directly to Keycloak or to the NGINX ingress. By assigning a static IP to this Service, you can reference it from Vault and avoid exposing NGINX externally, while still ensuring that traffic is routed to Keycloak internally.

It is a solution indeed thanks for your input. We are deployed on VM so we could simply override the DNS resolution through /etc/hosts. However, if the keycloak IP changes then we need to think of changing this configuration too. It is not the ideal solution

@ptrovatelli
Copy link
Author

ptrovatelli commented Oct 24, 2024

Were you able to get support on this? Would you be willing to share the ticket ID with me? You can email it to me, my full name at hashicorp dot com. Thanks!

Still waiting for support on this... Sent the ticket id to you by email, thanks for your interest in this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth/jwt-oidc bug Used to indicate a potential bug ecosystem
Projects
None yet
Development

No branches or pull requests

4 participants