When to implement authentication and authorization?

I am currently in situation where I have to decide when to implement security measures. So the question is simple, is it better to implement authorization and authentication methods right off the bat in the beginning of the project, OR at the end of the project, before the first release?

Things I considered: at the end, one would make quite a bit of changes to the API; at the beginning it is time consuming, if the client wants to see first results soon.

OAuth authorization code grant with exposed client secret

Let’s assume that a client has the client secret exposed somewhere. What are the risks that the client and its users are exposed to? Are those the same as having implemented the implicit flow from the begin with?

I would say that, the risk here is for an attacker stealing a code, and since the client secret is available, assuming no other form of client authentication is performed, then the attacker would be able to exchange the code to token. So it looks like it’s similar with the risks of implicit flow, but a bit more secure since by default the tokens are not exposed in the user-agent (implicit flow could use for example response_mode=form_post and avoid that scenario)

Is an “inversed” Device Authorization Grant flow secure for authenticating a daemon/service native app to a web server?

I am working on a hobby project which will involve a web server (hosted and owned by me) and a native app (which will communicate with the web server periodically) an end-user can install via a deb/rpm package. This native app has no traditional UI (besides via command line) and can be installed on browser-less environments. Additionally, I’m trying to avoid registering custom URL schemes. As such, I do not wish to use redirect flows, if possible.

The web server and the native app will both be open source and the code will be visible to everyone, but I suppose it shouldn’t matter in the context of authentication. However, I wanted to point that out in case it matters.

So far, during my research, I’ve come across two mechanisms which seem suitable for what I am trying to achieve:

  • Resource Owner Password Credentials Grant
  • Device Authorization Grant

Unfortunately, I’ve come across a lot of articles and blogs stating that Resource Owner Password Credentials Grant should no longer be used. Not sure how much weight I should give these articles, but I’m leaning towards Device Authorization Grant for now.

From my understanding, one of the steps involved in this grant is the client will continuously poll the server to check if the user has authenticated the client. However, instead of polling the server, why not flip the place where the code is entered?

In other words, instead of the client/device displaying a code to the user and the user then entering the code on the server, why not display the code on the server and have the user enter the code into the client? This way the client doesn’t have to needlessly poll the server? Does this not achieve the same thing? I’m really not sure though. I want to ensure I’m not missing something before I implement this.

This is how I envision the general flow for users using my project:

  1. The user would register an account on my site (i.e, the web server). This is just a traditional username and password authentication.
  2. The user can then download and install the deb/rpm package which contains my native app. Although, it should be noted that there’s obviously nothing preventing the user from installing the package without registering an account on the server. The whole point of this authentication is create a link between the account on the server and the native app.
  3. Prior to enabling the daemon/service functionality of the native app, the user will need to authenticate the native app to the server.
  4. To do so, the user can log into the server (using their regular username/password creds) and generate a temporary token.
  5. The user can then use the CLI functionality of the native app to use this temporary token. For example, the user may type my_app_executable authenticate, where my_app_executable is the binary executable and authenticate is the parameter.
  6. This will prompt the user to enter their username and the temporary token.
  7. The app will then send the entered username and temp token to the server which will validate this combination. If it’s valid, the server will send a access token back to the app.
  8. The app can then use this access token to communicate with the server. Authentication complete.

Based on this, I have a couple of questions:

  1. Does this flow seem secure? Is there an aspect of this that I’m overlooking?
  2. Is it okay to more or less permanently encrypt and persist this access token on the filesystem? If the user turns off the native app for months and then they turn it back on, I would like it to function normally without making the user authenticate again. I suppose I’ll need to implement a way to revoke an access token, and I’m thinking about tracking this in the database on the server side. This would mean that for each HTTP request from the app to the server, the server will need to make a DB check to ensure the access token hasn’t been revoked.

Should we use API keys for authorization on a public API (instead of JWT)?

We are building a public-facing API. The consumers of this API will be business partners of ours – we will probably have a personal relationship with each one, and I suspect there will only ever be 10-40 of these customers. So we’re not dealing with the same problems that e.g. Spotify/Facebook might with their public APIs.

We want to give each user different API read permissions, so some level of authorization is required.

We were going to issue each customer with an API key, and store the related permissions in a table. But now we’re wondering if we should implement JWTs to handle this.

Pros of API keys:

  • Simple. Easy for the clients to implement (fairly important for us)
  • Makes rate limiting simpler, as there will be fewer auth calls.
  • Cheaper (we are using AWS lambda so paying per request)
  • Quicker for us to build too

Pros of JWTs

  • More established way of handling authorization. No need to reinvent the wheel.
  • Avoid any unforeseen pitfalls around implementing your own access mechanism
  • Fewer database look-ups on our end (but presumably slower flow overall)
  • …any others I’ve missed here?

We’re leaning towards API keys for simplicity, but want to ensure we’re not missing something important.

Does my app need authentication in addition to Spotify authorization?

I have an app that revolves entirely around Spotify. I have followed the authorization guide from Spotify and am using the Authorization Code Flow so the access token can be refreshed. My thinking was that this will prevent them from having to log back into Spotify each time they return to the app, but I’m not sure how to do this securely.

For authorization, they are taken to the Spotify page to authenticate and grant my app access to to the requested scopes. After being redirected to my React application, the authorization code is forwarded to my REST API server so it can grab an access and refresh token.

At this point, I’m wondering:

  1. Should I store the refresh token in the DB? Wouldn’t I need to encrypt it?
  2. Should I return the access token to my React app so that it can include it in subsequent requests to my API?

Since I’m storing their Spotify id in my DB, it seems like I could use the access token to hit https://api.spotify.com/v1/me to get this id and look them up in my database to make sure they’re authorized to access the requested resources both on my server and on Spotify’s in one shot. It seems like this would prevent them from needing to have a separate authentication just for my app, since everything is tied to Spotify anyway.

My concern with this approach is that it seems insecure. If a malicious entity acquires one of my user’s tokens, I’m afraid they would have eternal access, since I’m refreshing the token on behalf of the user as specified by the Authorization Code Flow.

So, I’m considering having my own authentication (AWS Cognito) in addition to Spotify authorization.

It seems like leveraging Cognito for authentication would allow me to make sure it’s them just by verifying the JWT. Then, I can look them up in my DB by the JWT sub. This seems like the cleaner way to do things, but it leaves me with questions:

  1. Wouldn’t I then need to store their Spotify access token in my DB as well? Wouldn’t I need to encrypt it?
  2. Is this this some sort of anti-pattern, since the user has to sign in with me and sign in with Spotify? I can’t seem to rationalize why this is different from any other federated idP flow, like how Cognito lets FB, Google, etc. be leveraged for sign in to authenticate users with my app. They’re signing in with Spotify already, so I’m confused as to why there needs to be an extra step of also having to sign into my app.

I have read the OAuth 2.0 RFC 6749 documentation, the OpenID Connect documentation

I have also read a plethora of posts (and the links within them), including, but not limited to:

  • OAuth2 and Authentication
  • Storing third party API tokens in a database
  • Should client have access to 3rd party API access token?
  • https://medium.com/@abstarreveld/oauth-and-openid-explained-with-real-life-examples-bf40daa8049f
  • https://stackoverflow.com/questions/57379459/auth-strategy-for-aws-api-gateway
  • https://stackoverflow.com/questions/32236568/how-to-set-up-an-oauth2-authentication-provider-with-aws-api-gateway/33686216#33686216
  • https://stackoverflow.com/questions/42734848/access-token-to-encrypt-or-not

AWS Appsync authorization – why is IAM authorization safer than API Key based approach

We are currently evaluating which authorization type to use for our production AppSync APIs.

As per AWS docs(https://docs.aws.amazon.com/appsync/latest/devguide/security.html, https://aws.amazon.com/blogs/mobile/using-multiple-authorization-types-with-aws-appsync-graphql-apis/ ), AppSync supports multiple authorization types – like API Key based (passing a static API Key), IAM role based.

My questions are around the differences between API Key based approach & IAM based one:

1)why is using a static api-key considered bad for production use cases if all calls to AppSync are HTTPS based(which has good encryption)?

2)Why can’t we use a short lived token of our own along with API key & validate that token in a resolver? This would bring in some dynamism as the token is shortlived , so even if somebody hacks and gets this token ; by them time a replay happens the token is already expired?

3)The previous manual token approach seems similar to using an IAM role for Authorization. How safer would it be to use Amazon Cognito’s IAM Auth. roles for this be than a manual token approach? Does the SIGV4 standard used by AWS help in anyway here?