> I want to first say thanks for engaging with me on this issue so directly, much appreciated.
Of course :)
> As I said earlier - validating that the customer controls an azure user doesn't necessarily mean that they have permissions to grant admin consent.
I think what I'm trying to say is: you don't really care if they have permissions to grant admin consent - you care if admin consent was granted. In step4, you show the link to the admin consent flow, and if they are an admin, they click it, and if not, they click skip. In step5, you check if an admin consent is present. It might have come from the prior step, but it also might have come from something else - who cares.
> whether I couple it to Entra or not is not something you can rely on
I think, if we're talking about the Entra admin consent flow, some degree of Entra usage can be assumed. The admin consent flow requires an Entra identity.
> PKCE
PKCE would actually not be a solve here. I don't know why so many people think PKCE solves problems that it doesn't solve, but it's very a common thing. Using browser dev tools, I can just change the tenant parameter with the appropriate cookies/state in place, and PKCE would verify fine. Even with confidential client PKCE, it just becomes a confused deputy based on the cookies.
> a new API
If you want to verify whether admin consent is present, the existing [oauth2permissiongrant](https://learn.microsoft.com/en-us/graph/api/resources/oauth2...) API exposes that information. Though admittedly I think we've left that thing in beta for a decade.
Don't get me wrong, I see what you're saying. We could OpenID Connect-ify it and emit an id token that has some sort of claim xms_adminconsent=1, which could be verified by the app. Actually, that's what the v1 endpoint does if you use the deprecated prompt=admin_consent parameter (minus xms_adminconsent=1, whose lack caused its own set of headaches). Directionally though, we felt that separating the auth flows from the provisioning flows simplified them both, and building special auth-ified variations for every provisioning flow (not just admin consent, but also sign-up, and authorize customer support guy, and ...) was over coupling. It's just unnatural to overload the authentication stack with all those random responsibilities. Having bog-standard REST+JSON APIs (i.e. MS Graph) for provisioning flows (and maybe also a default guided user interface like /adminconsent) provides a clean separation.
Edit: I think, if I were to make a change, it'd be a very small change - renaming `tid` to `tid_hint`. It's already a common practice to pass `login_hint` as a user indicator between services - and nobody gets confused and thinks that user is signed in, just because you have their username in a form post parameter. Maybe the explicit signposting of "hint" does the trick, socially.