Search code examples
securityoauth-2.0access-tokenapi-keyrefresh-token

Should I use an access token as API-KEY?


BACKGROUND

I have an application with a node backend and an angular frontend. The backend has two GraphQl endpoints:

  • /auth, which has methods like: signIn, which authenticate an interactive user (basic usr/pwd) from my angular front and and returns an access token and a secure httpOnly refresh token (cookie); refreshToken, which returns a new access token; and signOut, which just revokes the refresh token.

  • /api, which contains the business rules, and authenticates the request by the access token received (stateless)

The angular frontend authenticates the user by calling the /auth/signIn endpoint, keeps the access token in memory, is unaware about the httpOnly refresh token, and creates a timer to call the /auth/refreshToken periodically.

PROBLEM

I need to grant access to my customers to access the /api programmatically too (e.g. from Zapier), so we are talking about an API-KEY, right? I was thinking about creating an API-KEY section in the SETTINGS area in the frontend and CRUDE methods in the /auth endpoint to maintain them. I would create a new special non interactive “user”, in the users table linked to the generated API-KEY so that, for instance, the user Zapier would be related to the API-KEY created to interact with Zapier and I could see its activity along the other users activities at the audit trail and easily revoke it by deleting that user.

QUESTION

Should I use a long term (?) access token as API-KEY? Wouldn't that defeat the purpose of using access tokens? My /api would no longer be stateless and I would have to check the existence of the access token for each request, right? It doesn’t seem the right choice. Is there a better approach?

Using the refresh token as API-KEY doesn’t seem to be an option to me, first, because it doesn't seem to be allowed to set a httpOnly cookie on the client side, second, because the logic to update the access token would be too complex to the user and third, because I wouldn't want to expose the /auth endpoint.


Solution

  • API Keys are very weak security so ultimately this depends on data sensitivity such as whether it is serious if an attacker can access your data easily for a long time.

    I would favour a standard OAuth flow for the type of client - perhaps Client Credentials Grant - so that access tokens are used, which are valid for a limited time period, such as 30 minutes. Expiry and refresh coding is well documented online.

    • If it is a user app then maybe the app (or its back end) needs to do some work to get tokens correctly.

    • If the customer is writing code to call the API with code then they need to be given guidance on how to authenticate and manage expiry. These details are well documented online.

    • Attaching a token could even be managed by an outbound proxy if these users are very non technical, where the proxy deals with supplying a token.