Dynamic host url and oidc callback

When creating a jwt/oicd auth you have to provide a callback url which matches a callback url on the auth provider. Some auth providers allow you to have a wildcard (“https://*.gitpod.io” )

We have an issue where our development env is “on the cloud” and we get a different dynamically created url for each workspace we start

The app we’re developing uses vault with Auth0 to authenticate - but we’re getting callback errors because we obviously don’t know the hostname in advance and so can’t set up the callback url’s in vault

Has anyone else has this issue ?

It’s not entirely clear which side of Vault’s OIDC support you are using - the auth method or the identity provider?

Either way, pre-configuration of OIDC redirect URLs is a part of OIDC’s security model - so you can’t just turn it off. You’d need to call the Vault API to set up each new redirect URL.

It’s for auth. In order to call the vault api to set up a new redirect, every developer would then need write access to the oidc roles api every time they fire up a new workspace. Certainly doable, but they would need a token pre-defined that allows this access … not what I would call secure

if the provider (auth0) allows for a global pattern like https://.gitpod.io (they do) then specify a callback url pattern like https://.gitpod.io in vault the config and allow the client to send the callback as an option to the initial authentication call so that vault could verify that the supplied url matches the stored pattern and then pass it on as the callback url

ie: Auth0 callback is https://*.gitpod.io

we could manually create a role with 10 callbacks

machine[0-9].gitpod.io

Using the method above we would create a role with a callback of https://*.gitpod.io.
Client passes https://machine1.gitpod.io as a parameter to the oidc login , vault verifies that it matches *.gitpod.io and uses https://machine1.gitpod.io as the callbackurl passed to auth0

I struggle to see why this method is any less secure than manually specifying 10 callbacks

I asked if it was the Vault auth method or identity provider you’re using here, so “auth” sounds like an abbreviation for “auth method” but the rest of your message gives the impression you’re actually using the identity provider…

Vault can play multiple roles in an OIDC setup. Please can we first establish which one? Or multiple? it is playing in your environment?

Sorry for the confusion. I want to use Auth0 as the identity provider, so we’re using the JWT/OIDC api

The callback parameter is a required option for the role

Ah… So the slightly unusual thing about your deployment is that rather than having one Vault instance, you’re embedding a new instance of Vault into each development environment your developers create?

no, we’re using a central vault, but the application is running inside the environment we’re spinning up in the cloud.

So, we go to github, and open a branch. we can then launch an environment with apache, node etc running. The application is then exposed on a port . This env has a random name, so the application is running on (for example) https://my-foobar-iq5npdrsvsegdyt.ws-eu47.gitpod.io:4200/

the problem is that we have no control over the iq5npdrsvsegdyt.ws part :wink: So we cannot pre-configure the callback in the oidc role

OK, I’m back to being confused then, because with this design, the callback URLs for the OIDC auth method to Vault, are supposed to point at Vault, not other applications.

Maybe it would help if your explained more about how you’re application fits into this? As the parties involved with using the OIDC auth method to Vault, are:

  • The identity provider (Auth0 here)
  • Vault
  • The user and their browser

There’s no room for a 4th party, your application, in this flow as I understand it.

ok, I see where you’re coming from. I’ll have a look at what I’m doing wrong.

In the meantime, lets say that I am doing this …

how would we go about sorting this ?

I don’t really understand what your goal is, so I’m not sure what to say unless you can explain more what you’re trying to achieve?

ok, let’s take a step back. I’m perhaps completely muddled regarding the login flow.

I am writing a web app. My web app needs to login to vault, using oidc. My app sends the initial login request to vault. What happens from here on in ?

My flow is:

App → start oidc login process, gets auth url to call. Browser is redirected to the url for auth
App->login to oidc auth provider (auth0 , google etc)

** At this point the callback url is called with the code, nonce and state value **
if the callback is to vault , how does the browser get back to my application url ?

Maybe this it the problem. The browser based OIDC flow is really designed for people, not for systems.

So if you are wanting a user to login to Vault then OIDC could be a good choice. The flow would be user goes to Vault → OIDC provider → Vault (now logged in).

Alternatively you could use OIDC to login to your web application: App → OIDC provider → app (with a login token from your OIDC provider)

If you are wanting your app to login to Vault that is something totally different, and not something you’d look at OIDC for. You would generally have the app login to Vault (e.g. upon startup) using something like AppRole, Kubernetes or AWS auth. Vault doesn’t know/care who is behind the app - it just sees calls from the app, with it being the app’s responsibility to check any end user’s permissions.

Alternatively you could have the app pretend to be the end user. With this method you’d have the user login to Vault and then provider the resulting token to your app. It could then pass that token to Vault whenever it makes API calls. This is not recommended for several reasons. Firstly you’d need to ask the user to login to Vault and provide the token to your app, which is going to be a fairly horrible user experienced. Secondly your app now has the user’s Vault token which is pretty bad from a security point of view - that token has whatever permissions the user has, which is quite possibly a lot wider than what the app actually needs.

hi @jmls ,
Did you find a solution?
I have exactly the same use case.

I’m using Gitpod to spawn a pre-defined development environment.
The user can SSH into that environment using a dynamic CNAME.
Example: xsdasdsadads.ws.gitpod.mydomain.com

Once the user ssh into the workspace, he would use the vault oidc authentication method, typing: vault login --method=oidc.

When this command is executed, Vault returns a URL that points to the authentication provider ( google, auth0, etc) and waits for the callback, listening on a port (default 8250).

Callback URL: http://localhost:8250/oidc/callback

This is when the problem starts. I can open the provided authentication URL on my browser but the callback should point to the remote host where the vault command was executed and is waiting for the callback request.

Desired callback url: xsdasdsadads.ws.gitpod.mydomain.com:8250

Since I don’t have control over the URL prefix I would like to configure a wildcard as an allowed OIDC callback URI.

Example: *.ws.gitpod.mydomain.com:8250

1 Like

The problem is that the OIDC Authorization Code flow was never designed to support this use case, so it doesn’t.

The vault login -method=oidc command has a hard requirement on running on the same computer as the web browser the user will use to complete the login, and so it is not a tool to be used over an SSH connection.

There are two options I can think of:

One: Complete a Vault OIDC login on a machine where you do have a graphical web browser, and copy/paste the Vault token to the environment on the other side of the SSH connection.

The command vault login with no -method directly accepts a Vault token and stores it for future Vault commands.

Two: Implement a custom tool that uses the OIDC Device Code flow to log in.

In this flow, the custom tool makes an HTTP request to the OIDC IdP, and receives a code or new URL containing the code.

It prints an URL to the screen, along with instructions to the user to visit the URL in their browser - either the code is embedded in the URL, or the user is asked to manually type it in. (That is to support cases where copy/paste is impossible - probably not the case here.)

The user proceeds with the login flow in the browser and meanwhile the custom tool polls the OIDC IdP asking whether it is complete yet.

Once the user has completed the login, the custom tool receives the OIDC token on its next poll.

The custom tool then submits the OIDC token (a JWT) to the Vault OIDC/JWT auth method, using a role that is configured in Vault as role_type=jwt. Vault validates the JWT and exchanges it for a Vault token.

The custom tool then stores the Vault token for the user’s use (e.g. by running vault login $TOKEN).

Unfortunately the Vault CLI doesn’t support this flow natively, hence the need for a custom tool.

1 Like

I see.
Thank you very much for the deep explanation.
I’m gonna evaluate the 2nd option.

Kind regards,