DEV Community

Warren Parad for Authress Engineering Blog

Posted on • Originally published at dev.to on

AWS Cognito: Don’t go to production

AWS Cognito is AWS auth solution, it’s much better than Azure’s and many others that think Auth is easy. It’s also great that it is AWS cloud native. But it comes with some glaring issues that might make you think twice.

With all solutions that are important layers for application, it’s critical to find the right one. Given the importance, it is something you don’t want to get wrong, but also can’t afford to build yourself. You can certainly try, and then end up on tomorrow’s front page about your user data leak.

I’m not saying here’s the right answer, but you need to figure out what is critical. Are you building a prototype service or MVP that you might throw away and don’t care about the users logging in, or are those users internal employees, then Cognito is a great thing to start with.


Take heed though, Cognito has the following problems:

Lacks Durability & Reliability

  • There is no way to backup Cognito. Cognito doesn’t support disaster recovery (DR) options.
  • Cognito sessions don’t work for long running user login (they have to continue to log in on an ongoing basis)
  • Cognito can’t be replicated between regions (so there is only one instance, users have to connect to the region where it is created
  • You can't turn off SMS MFA after you enable it, which means if you do it by accident and your users don't have SMS, then you permanently broke your pool. This coupled with no Backup strategy spells doom:

Cognito SMS Warning

Missing Configuration

  • It doesn't support custom configuration for the providers, so after connecting and setting up openId/SAML it is what it is. There are some small tweaks you can do, but you don't get fine-grained control over how the data enters cognito or the ability to really configure it.

  • It’s doesn’t support non-compliant openId implementations. That means you can’t connect providers that didn’t follow the standard (happens a lot, unfortunately)

  • The managed/provided login UI is empty and lacks the configurability to style it as your brand. You would expect something more like this Login Box configuration

  • If you instead write your own custom login screen, then you lose half of the features of Cognito Login.

Lacking API

  • user management is restricted, as the api’s don’t do even an okay job supporting fetching user data and managing users. There are no good queries to return user data, filter it, or make updates.

  • Depending on what you need setting up user emails/MFA etc… is a huge nightmare. Cognito supports N different kinds of lambda functions, at the time of writing it was 6. Picking the right one, and assuming it gets called at the right time will usually leave you hanging.

Complex

  • Sending out custom emails for Cognito interactions requires AWS to explicitly support your language. If your chosen software language isn't listed on this page which at the time of writing is only C, Java, Javascript, and Python, you can't use custom emails, end of story. [Note: This functionality is NOT in the SDK].

  • The custom Cognito libraries libraries are poorly documented and really confusing for most people AWS tried to create Amplify, I think that made it worse. Amplify and Cognito both have additional libraries and link to third party libraries for even doing simply things like logging in

Incomplete

  • It doesn't support simple required functionality such as keeping the user logged in. It relies on Refresh tokens which are never meant for this strategy. It does not support Silent Authentication in the background either.

  • Cognito doesn’t offer granular access management, so if you need permissions or IAM for users, you only get the basic JWT hacks.

  • Cognito has claims, but those claims are frequently not consistently populated. In a lot of cases that's expected since not every user actually has every claim, but in many cases, they just don't show up in APIGW Authorizers for instance.

Bad DX

  • There’s no way to generate api tokens for users to connect with your service utilizing cognito, you have to build a custom implementation. That is, it doesn't support giving api keys to your users or coupling the api keys to specific users or customer accounts.

No B2B SSO

  • It supports SSOs as long as those SSO are first party providers, i.e. ones that you trust. If you add Corporate SSO IdPs from your customers, it can allow one of your customers to infiltrate your other customers. Third party SSO isn't secured well.
  • It doesn’t support 3rd party app developers logging in with your solution, all applications are meant to be first party. You can't offer OAuth as a platform to generate "Sign In with Solution X" for building an App marketplace.

  • Cognito doesn’t support machine-to-machine authentication, you would have to roll your own implementation. It does support basic OAuth service clients client_credentials, but it doesn't scale to handing those out, and the authenticate with those clients isn't entirely spec compliant. And now AWS is charging $6 / client / month AND also charges per token generation, if the fact that this implementation didn't support the standard requirements wasn't bad enough, now everything is going to cost extra.

Lacks Credential Vaults

  • Cognito doesn’t support OAuth2 credential vaults, so you can’t use it to interface with first-party authentication app. Want to connect to your user’s Google Drive, or their LinkedIn account, can’t do it with Cognito.

Often Insecure

  • Cognito doesn't support EdDSA signatures on tokens, and doesn't support the authorization_code exchange using PKCE verifiers for both the user side and the IdP side, meaning that for many providers this login flow is open to MITM attacks.

  • Cognito is insecure by design. Simple things like DDoS protection for your login endpoint isn't provided, nor is easy to configure. Since you need this if using Cognito, because you are going to get attacked, here's AWS recommended infrastructure

  • There's no way to log a user in with a Federated identity provider, such as google from mobile, without creating a fake user in Cognito, and then pulling some linking magic. This requires the user to still have a password associated with their account which creates a huge attack surface for your users.


Cognito Groups look interesting…

Will 99.9% of the groups ever assigned to a user be the only group that is assigned and never replaced with another one. If a user is in group X, are they be in group for their whole existence and never in group Y, and only 0.1% will ever change from X to Y, and that's it. As in changing groups is not a feature of your application.

As long as that is the case, such as creating an Admin group, then this is fine, and it works. But as soon as you have multiple groups, and you expect that users can change which group they are in, you start to have a problem. Group changes are not instantaneous, and more so, understanding what permissions a "Group" has is even more complicated. Having two services both utilizing the same groups "User", "PowerUser", "Admin", both services would have to make explicit guesses about what permissions are in PowerUser and User which aren't in the other. This leads to conflicts about what a user expects they can do and what they can actually do.

Additionally when the gain or lose access to these groups, their permissions are coupled to their JWT. That means you'll need to force the JWT to rotate, which in a lot of cases, you don't have access to do. If your application has users with API keys, then it is down-right impossible.

Here are some common problems with many auth providers in the space:

  • Most auth providers have non standard implementations, despite saying they are oauth2 compliant, so you have to learn a new toolset
  • the bigger the provider the less likely they’ll provide a good onboarding experience for you, so you’ll have to figure out most of migration yourself
  • Some providers require you to use their hosted ui which offers confusing configuration
  • you’ll need to issue service clients for your services to connect to the APIs (since IAM obviously won’t work)
  • Most providers don’t offer good security controls, so you can’t provide your company’s admin/devs granular access to the IdPs resources.

Still want to use Cognito?

Maybe Cognito's got something special that you really want. Be it a username/password DB that support email/sms/2fa device codes or something else. Well, the libraries are terrible, so now you also need to deal with a terrible developer experience. But you can make that a lot easier by using an auth provider that can hook up to Cognito.

So what can we do about it…

I'm sure I'm missing a lot more, that's just what comes to mind in this moment. If you still aren't sure what the right things to look for is, check out this article for How to pick the best auth solution, it might just put you on the right path.

You might be in the situation where you just can't change anything, so trying to avoid Cognito might not be possible. However, there are a number of solutions that let you build on top of Cognito to fill in the gaps in functionality. Especially around RBAC, ABAC, gRBAC, SSO, multiple identities, Disastery Recovery, etc...

The truth is that--your situation matters a lot more than some arbitrary product pitch. However, if you found this article insightful and want a recommendation on a provider that makes it easy to start and and sustainable in the long term, Authress is most likely the best solution.


Come join our Community and discuss this and other security related topics!


Join the community

Top comments (0)