Allow ABAC access tokens to have an expiry or TTL, or specify an authentication lambda

I’m building a webapp with a server-less backend and Gatsby on the frontend, and I’m hoping to make it so my backend issues a token to the client to access their resources on the database using ABAC roles. This would greatly reduce time writing APIs, ensuring against data leaks, and fixing other security issues which ABAC solves. However, I am not using credentials but instead OAuth logins and JWTs. The current authentication methods are very much oriented toward credentials, however I see that they still work without them. This is well and good, except tokens never expire unless they are manually deleted (Logout function), which could be done with a cron job of some sort but completely defeats the point of server-less and is counter-intuitive. If my user’s client is compromised somehow and a foreign attacker gains access to their DB token, without a manual deletion of this token it is valid, so long as Logout is not called. This poses a security risk should the client somehow exit unexpectedly and not call Logout.

What I found while researching this topic is this gist and a connected blog article explaining exactly my problem in detail, meaning I am not alone in this struggle. While the solution provided certainly WORKS, it is not ideal, and could be improved with a few additions to how Fauna handles tokens.

Some possible solutions are:

  • Create a lambda function that determines if a token is truly “valid” after it is located in the Tokens collection. This allows for dynamic behavior regarding access to the database and provides more possibilities with authentication.
  • Allow configuring a TTL for the Tokens collection, making tokens automatically revoke after a certain period of time
  • Add support for other methods of authentication than tokens

Hey @itsmeow,

we understand that this is not ideal and are actually working at this moment to make TTL’s behave as they should behave. That does not mean that it’s impossible to make a secure implementation right now but it’s definitely cumbersome. For example, you could make a specific collection on which you will generate tokens (e.g. session) and place a ‘is_valid_until’ date on there.

When you execute a specific query, you could get the session via the Identity() function and verify whether this session is still valid. But as we said, we realise this is not ideal and are currently working hard to improve that!

Isn’t the result of Identity() entirely dependent of what token is used in the Login() Function making the idea of making my own tokens useless? Or am I misunderstanding what you mean

You are right that Identity() depends entirely on the token that is used.
However, nothing stops you from adding the entity to that ‘session’ document.

E.g.

Create(
   Collection('sessions'),
   { data: {
        user: <your user reference>,
        valid_until: <some date>
     }
  }

Whenever you use that token, you can get the real Identity:

Let({
   session: Get(Identity())
   user: Select(['data', 'user'], Var('session'))
  ...
},
<do something>)

You could write roles that block access depending on whether the session is valid or not. It might be useful in some cases if you want to store other session-related data as well (biota uses such an approach)

But as I said, soon you won’t have to worry about it and can just use the token straight on the ‘user’ or ‘account’ collection, (whatever it is in your case) and simply use ‘ttl’, we are working on it.