Deciding on Auth models
Tags: security, oauth, ux
Published: 2021-05-20 13:57:35

Deciding on what authentication model to use has always been a daunting task. With all the different flows that are available in specifications like OAuth it has become more complicated for software engineers to choose an appropriate one.

OAuth talks about using 'Auth code with PKCE' (read PKCE as Pixie) when it comes to mobile applications. But this has always been a 'love it or hate it' kind of thing for me. This is primarily due to the fact that, as a business you want to use a login screen that is customised as per the company UI/UX guidelines. You do not want to show a web page based login screen that is kind of shoe horned into an Android native app. Believe me, it never looks good and never feels seamless, even in cases where the authentication provider allows for customisations of the login screen.

So it got me thinking, what are my options here. I started reading about 'password grant' in Aaron Parecki's blog article 'OAuth 2 Simplified'. I also read about 'public clients' while working with Keycloak IAM. So was that the solution that I am looking for - 'password grant with a public client'. But then again I came across a number of articles that suggested NOT using the same and preferred using 'Auth code with PKCE' instead. That put me right back to the place where I started.

As a software solution architect, what I want to build is an authentication solution that adheres to standards, which will ensure proper security for my business applications, but also can cater to the business UI/UX requirements. I do know that there are trade-offs required in architecture all the time, but that does not mean a trade-off which would be obviously apparent to all of my users, every time they login. As far as I can 'Auth code with PKCE' does not cut it for me.

Let's get to a real world scenario where in the choice is to use an OSS solution for IAM like Keycloak. Assume that the Keycloak instance is hosted in the cloud environment of the big 3 (AWS, Azure or GCP) with necessary control mechanisms. In this scenario what should be the approach?

I began thinking from the perspective of not exposing the IAM service to the end-user directly. I wanted to provide REST API end-points catering to the needs of my application from an authentication standpoint. This meant that I provide APIs for 'login', 'logout', 'register', 'password reset' etc. These APIs would internally call the relevant APIs at the IAM service to achieve the end result. In terms of OAuth flow, I would have to use the 'client_credentials' flow between the APIs that I expose and the Auth provider.

Considering the above, if I draw a sequence diagram this is how it would look.

![Fig 1 - Client credentials](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bpkb1r6yfb8navdi7b7.jpg)

When I look at the APIs that are available from Keycloak, it is clear that all the APIs that I exposed are already present, even with features like 'Remember me'. So this got me thinking again, 'Why the hell am I exposing the APIs all over again?', when I can expose the Keycloak APIs to internet and use that directly. I can simply setup a 'public client' and call the APIs from the App without the client secret. I would directly collect the username and password in my customised login screen, developed as per the UI/UX guidelines that I want to adhere to. The sequence diagram for the same will be as below.

![Fig 2 - Implicit flow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y7qr3dcyk7vcs4ueuckm.jpg)

I am currently in 2 minds on how to proceed. I surely do not want to use the 'Auth code with PKCE' flow as the experience that it gives to my users is not seamless. But by using the 'password grant' with 'public client' am I exposing myself to some known security loopholes. This is something to be found out. Till then Ciao.