See Part 1 of this post: How The Big Cloud Providers Fail at IDaaS: Heuristics
In the previous post I outlined my heuristics for evaluating IDaaS offerings in the big cloud providers. The post put heavy emphasis on spec-compliance to OpenID Connect (OIDC) in the context of a JAMstack. JAMStack provides a highly scalable, well-vetted, and low-cost method for building out a web app and OIDC provides well-vetted and secure authentication and authorization. The teaser in that post was that all the cloud providers fail to provide a fully managed OIDC based identity service. Let’s dig in.
Identity as a Service in Big Cloud
The IDaaS offerings by the big three are:
I’ll also briefly touch on Auth0 as they are a clear leader in this space and actually do provide spec compliance.
The 8 focus points of my evaluation are:
- Choice of Social Federation
- Choice of Custom Login
- Account Linking
- Fully Managed Service
- Brand Control
- OIDC Discovery Endpoint
- Authorization Code Flow w/ PKCE
- Silent Refresh
Check back to How The Big Cloud Providers Fail at IDaaS: Heuristics on why these are important.
Before we begin: Google Identity Platform is NOT an OIDC compliant IDaaS provider
AWS, Azure, and Auth0 all follow the same architectural pattern regarding OIDC for their IDaaS offering. They all attempt to provide an OIDC compliant endpoint which has the ability to the federate with varying social logins. This makes it easy for developers to integrate with these services using OIDC compliant libraries. You can think of it as OIDC on both sides: Client uses OIDC to connect with the IDaaS offering and then the IDaaS offering uses OIDC to connect with the potential social logins. This shows the flexibility of the OIDC spec:
Google on the other hand, has opted to expose the signup/signin flows through their proprietary Firebase SDK. They only have implemented OIDC compliance on one side of the equation. Google Identity can use any OIDC compatible identity provider as a form of authentication but Google Identity itself is not OIDC compatible. There is no OIDC discovery endpoint. The only option is to use their proprietary SDKs or APIs.
This needlessly create lock-in as it breaks away from spec compliance forcing all flows to go through their custom SDK/APIs rather than standard OIDC flows. What I’m looking for in a IDaaS provider is true OIDC compliance, so this really takes Google’s offering out of the runnings.
In addition, Google’s offerings are very difficult to parse as they have three separate services targeted toward consumer facing web applications. Google has an identity crisis with its identity offerings:
- Google Sign-in: This enables integrating Google Social Sign in (and only Google Social Sign in) into an application.
- Firebase Authentication: This enables integrating many types of identity providers into an application.
- Google Identity Platform: This appears to be just a wrapper around Firebase Authentication but branded and packaged as Google Cloud service.
For this analysis I’m just looking at Google Identity Platform/Firebase as I’m not interested in restricting users to only being able to login with a Google account. My guess is that firebase will eventually get fully rolled into the Google Cloud brand.
Onto the scoring!
Choice of Social Federation and Custom Login
All the providers provide mechanisms for Social Logins and direct username/password sign in flows. Nothing interesting to see here!
Scorecard: Everyone Wins!
All the cloud offerings provide a way to consolidate identities through account linking when users choose to login via multiple paths (e.g. Username/Password one session, Google Sign-in next session). This does require some custom UI and API calls in the application to sign in and link the additional identities. Examples:
Scorecard: Everyone wins!
Cognito, Azure, and Auth0 all provide hosted UIs for the signin/signup page due to their OIDC compliance. This makes it as easy as possible for the developer to quickly get identity integrated with minimal code.
Since Google does not provide an OIDC compliant endpoint, the developer is left to implementing the UI for sign in and sign up on their own with help from the Firebase SDK.
It should be noted that AWS Cognito appears to be moving in a similar direction as Google by promoting their Amplify SDK as a custom, locked-in, mechanism for interacting with the Cognito Authorization Server.
Scorecard: Google Cloud fails in providing a fully managed offering by forcing users to implement the signup/signin flows using their Firebase SDK
Azure and AWS both provide options for UI customization in their hosted logins to get the account chooser to match brand with custom CSS and custom logos.
However, when it comes to providing a custom domain, Azure is the only provider that currently does not offer this capability. The identity page is hosted at https://<your-tenant-name>.b2clogin.com. That login looks nothing less than suspect. This is unfortunate given all the security advocates out there training users to pay close attention to domain names in protection of phishing attempts. This just makes it confusing for end users.
The positive of Google’s approach with the Firebase SDK is you do get more brand control as that they have explicitly opted to not host any UI themselves. All signin flows are built by the developer using Firebase SDK.
Scorecard: Azure fails with no option for custom domains
OIDC Discovery Endpoint
The OIDC Discovery endpoint for Cognito can be viewed here. As part of OIDC compliance, the discovery endpoint should advertise
response_types_supported which informs the client which types of OIDC flows can be requested. The OIDC spec calls out the required values of
token id_token. So far so good, Cognito exposes the discovery endpoint and lists those 3 required OAuth 2.0 response types as required by the spec. Open the link up and see for yourself.
Unfortunately, this is completely misleading as Cognito only supports response types of
code as can be seen in their docs. Requesting any of the other response types results in an HTTP 400 error. This results in generic client OIDC libs to break when initiating the Implicit Flow with Cognito as they expect the Discovery Endpoint to be accurate.
Azure also has issues with its Discovery Endpoint. Another purpose of the Discovery Endpoint is to advertise the Authorization Endpoint for initiating the auth flow. Azure has a problem in that the Discovery Endpoint publishes one Authorization Endpoint but the docs instruct the clients to use a different authorization endpoint:
|Authorization Endpoint Source||Authorization Endpoint|
This may be fine if both the authorization endpoints worked as advertised, but only the V2.0 endpoint was able to complete the desired flows making the Discovery Endpoint rather useless.
Google doesn’t expose an OIDC Discovery Endpoint at all for their Identity Service. You are stuck using their SDKs.
Scorecard: Azure and AWS both have failures in the accuracy of their Discovery Endpoint. Google Cloud Identity doesn’t even offer a Discovery Endpoint.
Authorization Code with PKCE
As mentioned in my previous post, the IETF is recommending clients stop using the Implicit Flow in favor of the Authorization Code with PKCE for the web. For the Authorization Code Flow with PKCE to work the Authorization Server must support CORS on the token endpoint for the client to successfully make the exchange.
Unfortunately Azure AD B2C does not support CORS on their token endpoint breaking any ability to move from the Implicit Flow to the more secure Authorization Code with PKCE.
This is yet another heuristic that cannot be applied to Google’s architecture due to forcing the use of the Firebase SDK.
Result: Azure and Google fail to provide the more secure Authorization Code with PKCE.
Another good security measure when implementing OIDC flows on the web is to leverage Silent Refresh. This allows the client to refresh the short-lived access token via an invisible IFrame if the user still has a valid session with the Identity Provider.
AWS Cognito is unable to do a Silent Refresh. Attempting to to pass
prompt=none when calling the
/authorize endpoint will result in a 400 error. An alternative is to store the refresh token in local storage or session storage to perform a silent refresh, but this is considered a poor security practice as the refresh token is long-lived and browser storage is notoriously insecure.
Although Google Identity presumably supports a silent refresh via the Firebase SDK it is not using the standard
prompt=none OIDC flow.
Scorecard: Azure strong. Cognito weak. Google is still hiding behind its SDK
A note on Auth0
Auth0 is a SaaS offering that focuses on the identity space exclusively. They are clearly the leaders in their spec compliance, documentation and ease of use beating anything that the big cloud providers offer. However, it does come at a price. They have a free tier with base functionality but certain features require a paid plan like brand control and account linking.
|Criteria||AWS Cognito||Azure AD B2C||Google Identity||Auth0|
|OIDC Discovery Endpoint||⚠️||⚠️||🚫||✅|
|Authorization Code Flow + PKCE||✅ ️||🚫||🚫||✅|
|Silent Refresh||🚫 ️||✅||⚠️||✅|
I value using industry standards for security, user privacy, and transparency. Using standards means I also don’t have to re-learn a new provider specific API/protocol. It also provides flexibility in reusing standard spec compliant SDKs/libraries in my language of choice for speed of development.
With both the OAuth2/OIDC specs being out in the wild for 5+ years I’m disappointed to see these standards not more widely embraced by the IDaaS offerings by the major cloud providers. It’s promising to see Auth0 fill the void that the cloud providers have left by coming out with a very robust, service that has all the benefits of spec compliance.
I do wonder though, with the difficulty the cloud providers have in getting spec compliance with OIDC, is part of the blame on the standard itself for not being easier to adopt? Is OIDC too heavy for the average web application? Is it perhaps too customized for the enterprise and not the cash strapped startup or enthusiast hobby project which needs to move quickly? Or is it all on the cloud providers?
In short, how did Identity get so horribly complicated?