Pomerium: Feedbacks on using pomerium with Azure ADB2C

Created on 1 Oct 2019  ·  3Comments  ·  Source: pomerium/pomerium

We did some experimentation with Azure ADB2C and here are some things we found out in relation to pomerium. This is not a request for supporting ADB2C per se, but maybe some of those feedbacks could end up improving pomerium and maybe also this could be a first step toward supporting ADB2C. If it's doable, we could even try to contribute :)

ADB2C is basically a wrapper around AAD to federate external identity provider into one:

  • you set up an ADB2C tenant, which is actually an AAD tenant + some extra UIs and APIs
  • you set up some external provider (by creating app there)

    • for example one for google identity, one for an AAD tenant, maybe another one via a generic oidc integration, etc

  • when your user connects to your app and is redirected to this ADB2C tenant, the login page enables the user to choose which identity provider to actually use (there even is an query parameter domain_hint to directly redirect to one of the identity providers)
  • when the user is logged in, a corresponding user is added to the underlying AAD.

On top of that, ADB2C imposes the use of "user flows" that describe how authentication happens, if some extra information is asked to the user, etc. It is even possible to program some extra behaviour in the authentication process (say to add some claims to the user id token or do extra validations).

While trying to setup Pomerium to exploit ADB2C we encountered various "problems".

Configuring the Identity Provider

We tried to set it up as a generic oidc provider (IDP_PROVIDER=oidc), but the oidc discovery document url of ADB2C is like this: https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_USER_FLOW.

B2C_1_USER_FLOW being one of the various configurable user flow: it is not possible to not set this parameter, if not the url returns 404. Since pomerium constructs this URL itself, it isn't possible to configure it to use it.

We were able to work around this to test continue our test (we simply set the value of IDP_PROVIDER_URL to https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_USER_FLOW&ignored= :)

As expected, this didn't work because pomerium tries to validate the content of the oidc discovery document by comparing the issuer value with the value of idp_provider_url.

But we nevertheless noticed a problem with this check because even if there was a valid value for idp_provider_url, those two informations should not have to match:

  • for example, with ADB2C, you can change in the configuration of the user flow the value used for the issuer
  • also, in practice, the value of the issuer in the document is not the same as in the url: for example, if the url is https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_USER_FLOW, the issuer is something like https://mytenant.b2clogin.com/xxx-xxx-xxx-xxx/v2.0/ with the id of the tenant instead of its name. In this specific case there would be a workaround because the oidc discovery document is also accessible via https://mytenant.b2clogin.com/xxx-xxx-xxx-xxx/v2.0/.well-known/openid-configuration?p=B2C_1_USER_FLOW, but this is not a given.

One solution for both those problems would be "simple", separate in the configuration
-the actual url: https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_USER_FLOW

  • from the expected issuer: https://mytenant.b2clogin.com/xxx-xxx-xxx-xxx/v2.0/

An alternative to that would be to have a specific IDP_PROVIDER for ADB2C that uses a specific configuration for the user flow to set. But in that case, it means that the issuer shouldn't be validated as it currently is: this is too restrictive, and maybe other identity provider could suffer from this too?

We didn't go farther with testing the integration of pomerium and ADB2C but from what we saw, it seems that if the above problems were solved, it should work to authenticate users.

Accessing Group Information

ADB2C does not have (yet) the concept of groups, but since it is based on AAD, there exists actually the notion of group when configuring the tenant using the AAD UIs instead of the ADB2C UIs.

This means that once a user has been authenticated via ADB2C, a corresponding user is created in the AAD tenant and it can thus be added to an AAD group.

What we haven't had the opportunity to explore is if it is necessary to create an application in AAD itself in order to give it the right to access the group informations (as explained in pomerium documentation): the applications created via ADB2C can't have extra api access configured apparently…

In this case, this means it would be necessary to configure two client id in pomerium:

  • one created via ADB2C for authenticating users
  • one created via AAD for accessing user groups

This would be similar to how things works with Google for example.

Conclusion

So, in the end, it seems that supporting ADB2C doesn't seem so complex, but there are things to do in order to make it work… I hope those feedbacks can be useful, and if you need more details or that I do some more tests, I'm always available :)

NeedsInvestigation

Most helpful comment

@victornoel just a head up... once the v0.4.0 release is cut, this is at the top of my todo list to read with a clear head, and hot cup of coffee. I'm really looking forward to it.

All 3 comments

@victornoel just a head up... once the v0.4.0 release is cut, this is at the top of my todo list to read with a clear head, and hot cup of coffee. I'm really looking forward to it.

😅 Well 0.4.0 is out the door so I've finally had a chance to read about your experiencing trying to get Pomerium working with ADB2C. First of all, thank you for simplified explanation of ADB2C (first I've heard of it!) and your detailed experience report.

So to boil things down to what would have to change architecturally, it sounds like:

  1. We'd need to support (which seems easiest to do through a custom identity provider, but I'm open to other approaches) an identity provider that is more lenient in several ways.
  2. Allow additional query params to signal that this is a ADB2C request
  3. Have different verification criteria for issuer; in this case to match the client's tenant not yours. But this also does not seem to be guaranteed either. Given the context, I think we can be flexible on what is validated, depending on what is expected to be returned for this value.
  4. Have the ability to query groups. I think you are on the right track in terms of using a separate API (similar to the google identity provider setup) to query, and retrieve a user's group information. My previous experience with AAD, and added permissions is that it is extremely finicky.

Overall, I agree. I think this sounds very doable.

If you are available, it would probably be beneficial to touch base over a more synchronous communication method. Thanks again @victornoel

@desimone with much delay (other priorities ;), here are the feedbacks we got from the Azure people after discussing (it was around the end of October) all of this with them:

  • They will raises the two following improvements to the ADB2C team (I'm not sure if something happened since then…)

    • allowing to configure a default user flow (to avoid having to set it in the url in pomerium)

    • homogenize the issuer and the url (so that things are more coherent)

  • ADB2C does not allow to manage groups for users in there, and they insist to say that it is a bad idea to use the group concept from the underlying AD to handle it

    • their recommendation is that this kind of concerns should be handled via custom claims that are added to the JWT token

    • if I understand well, it would be interesting maybe for pomerium to specify authorization via the existence of some claims and their values maybe?

  • For the record, they told us ADB2C is in active development currently (while it was kinda on pause before)

So, honestly, I wouldn't expect much changes coming from ADB2C for better integration with pomerium, but there are interesting ideas to improve pomerium here, on top of those we already discussed.

Was this page helpful?
0 / 5 - 0 ratings