-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Make AzureProvider a child type of OIDCProvider #2384
Comments
In #1972 I removed the v1 compatibility due to the complexity you mentioned. Maybe I'm missing something, but isn't it a simple switch in configuration to use the v2 endpoints? I don't see a reason to support the v1 endpoints, particularly if we instruct to supply an OIDC issuer URL as the current doc does. |
This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed. |
This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed. |
Closing this as new Entra provider has been merged. |
Make AzureProvider a child type of OIDCProvider
This issue aims to collect information and considerations regarding making AzureProvider type a child type of OIDCProvider.
Reasoning
Azure authentication endpoint (V2) follows the OIDC specification, so this refactor would reduce complexity for the provider-specific files and re-use most of the generic OIDC features.
The root of this initiative lies in enabling Workload identity for the Azure provider. Azure authentication supports client_assertion certificate credential for a token exchange endpoint. Certificate credential is a replacement for client-secret exchange and it's supported natively with Azure Workload Identity. The support for cert credentials for Azure provider was initially proposed by myself in #2364, but as @tuunit pointed out,
client_assertion
is a feature of OIDC and we should rather implement this in generic OIDC provider and make the Azure provider re-use most of the methods.What's outstanding in Azure authentication
In vast majority of the cases, Azure authentication can be used with generic OIDC. Specifically when:
So we need to cover three corner cases.
Handling V1 endpoint
Sadly, V1 endpoint isn't compliant with OIDC, and whole idea of V2 is to make it more compliant with the standards. Also, lots of the complexity in the provider code comes from backward compatiblity with V1 endpoint. For example: V1 endpoint requires a
resource
parameter in the authorization request that is incompliant with OIDC, V2 supports compliantscope
. This results in the ugly conditions in the code. Azure AD endpoint comparison perfectly describes the differences.It's hard to say how common V1 endpoint is. If we want to keep the V1 endpoint support, I would suggest to keep the existing provider as legacy and introduce new one that base on generic OIDC, otherwise we will end up buidling conditions and overriding methods. We can also take advantage of the refactor and name the new provider for example
azure-entra-id
.Handling groups
Some higlights regarding groups:
groups
claim.--azure-graph-group-field
to use friendly groupdisplayName
s instead ofid
s.So the implementation of
EnrichSession()
has to be custom for this case, implemented ideally with sync of #1972, this would cover single-tenant & multi-Azure tenant group overage.However, when using multi-tenant login with personal microsoft account (for example: Github) and not through Azure tenant, we are completely unable to read the groups through Graph API. The
GroupMember.Read.All
permission requires admin constent on the tenant. ID tokens comming from personal MS account (github, outlook, etc.) are signed by some internal MS tenant (for example9188040d-6c67-4c5b-b112-36a304b66dad
) and we won't get this consent. In this scenario we can't read groups from access token neither, as access tokens for such accounts are not JWTs.Current version of Azure provider does not allow personal microsoft account.
Handling multi-tenant apps
Multi-tenant app OIDC endpoint addresses do not include the tenant id:
The OIDC discovery document has a following entry:
Which is pretty much a template and cannot be validated by regular OIDC middleware. As current documentation states, to make the azure multi-tenancy working, we need to disable issuer verification with CLI flag:
This flag is sufficient to make the current version of oauth2-proxy working with multi azure tenant apps (no personal account). Skipping issuer verification is inevitable, it's even listed in the recommended approach for issuer verification in the multi-tenant apps:
https://github.com/Azure-Samples/guidance-identity-management-for-multitenant-apps/blob/master/docs/04-working-with-claims.md#issuer-validation
(this document is 8 years old but still remains generally valid)
What we can do though is to create a CLI parameter to specify list of allowed tenants or insecurely allow all tenants. Then, according to the documentation above, check against the
tid
orissuer
claim in the idToken and decide whether user is authenticated.The client_secret for multi-tenant app has to be a global App registration password, in oppose to Service Principal Password which is tenant-specific.
Other considerations
AccessToken failover fo email claim
Currently we do fallback to access token when reading the email claim:
https://github.com/oauth2-proxy/oauth2-proxy/blob/master/providers/azure.go#L262-L273
That's OK, minus the fact that when using personal microsoft account (outlook, gitlab), the Access Token is not JWT. So in case
email
claim is missing in the id_token, we are running into a misleading error, when trying to read the claim from invalid token. Thus, we need to be sure that we includeemail
as id_token optional claim for the app registration. For terraform, we can azuread_application_optional_claims resource.Anyway seems like these issues are not valid anymore, so we can just rely on the ID Token with proper claim in place.
Reading e-mail from Profile API
Currently we read e-mail from the profile API:
https://github.com/oauth2-proxy/oauth2-proxy/blob/master/providers/azure.go#L413
This is not necessary and we could read the mail from id_token from properly configured app registration (see above).
It's important to mention that when user does not have the e-mail set, the claim isn't set.
Other higlights
Multi-tenant configuration debugging
Without
--insecure-oidc-skip-issuer-verification
flag:With invalid client secret (for example comming from Service Principal, not app registration):
When application password is set, but id_token has missing
email
claim an oauth2-proxy tries to read it from access token that isn't JWT (personal microsoft account):When having
email
claim is available in id_token, but Graph fails as we can't read groups:Summary
Here are the architectural questions to answer:
--insecure-oidc-skip-issuer-verification
?Please drop any other input, will try to follow.
The text was updated successfully, but these errors were encountered: