Bug: GraphQL custom auth workflow stops working until tested

  • Goal: Custom auth to be reliable for all users, all the time.

  • Steps: We have a "Custom Auth" workflow setup for GraphQL, it produces a JWT based on the currently logged in Retool user and defines it as a variable which is passed as a header. The "Auth trigger" is set to "Every query run".

Sporadically this auth stops working and queries from within apps fail for the user until they navigate to the resource and click "Test auth workflow". Once this is done it will begin working again.

Because this last step always works to rectify the situation it feels like it can only be a Retool bug.

  • Setup:

Hey @tommoor — is there a particular requirement to run auth on every query run? How frequently is your resource called?

I’m not entirely sure, but I imagine that setting is for more specific, far less frequent workflows rather than high traffic production queries. Especially GraphQL resources, which can be notoriously hard to secure/auth.

If you’re still in early stages of development, there are potentially better solutions for achieving the same outcome.

As it includes the current_user it feels as though Run on every query is required?

I guess I'll email support, this is a pretty terrible way of handling bug reporting for your product.

Hi @tommoor, welcome to the forum! :wave:

This does seem to be a bug on our end, I looks like auth trigger is never running. The token could be expiring and we are not getting a new one despite the fact that this flow is set to run with every query run.

For example:

With this Resource:
Screenshot 2024-08-16 at 2.52.47 PM

We are setting the token param to the value of CUSTOM_TOKEN, which should be defined with the following steps:

When this runs "every time a query is run," the value of CUSTOM_TOKEN should be updated to the return value of step1: "new-value."
Screenshot 2024-08-16 at 2.54.39 PM

However, when we actually run the query, the value is "CUSTOM_TOKEN," as if the flow never ran:
Screenshot 2024-08-16 at 2.56.45 PM
Note: Httpbin is echoing the request.

And it's only when we click Re-auth that CUSTOM_TOKEN gets it's value:

As a workaround, we could use a Refresh auth workflow instead of the auth trigger. This flow will run after "any non-200 response when querying a resource."

We just created a bug report for this issue. We'll update you here when it's fixed, and please let us know if the workaround works for you. :slightly_smiling_face:

Hi, thanks for the acknowledgment. The workaround will not work in this case because we're using GraphQL and errors are returned with a 200 response code, as standard for this type of API.

I have changed it to "Time-based expiration" and I'm hoping that will help instead.

Changing it to "Time-based expiration" reduced the frequency of occurrence but it still happens.

Thanks for the update! It sounds like a step in the right direction. Do we know how long it takes for the token to expire? Until this issue with Auth Trigger for every query run is fixed, we could reduce the seconds set for 'Re-run auth only once this many seconds have elapsed' to be lower than what it takes for the token to expire.

Do we know how long it takes for the token to expire?

From our side there is no expiry, from Retool's side I'm not sure how long it takes before it stops working – haven't been able to pin point that. I set the time-based expiration as low as 24h and still saw the issue

Any update here? This is a daily burden for our team

Hi @tommoor, from looking at the jsonwebtoken docs:
https://www.npmjs.com/package/jsonwebtoken

It looks like we have control over the expiration:

Let's try setting the expiration to 24h inside the object we pass to the jwt.sign function, and test it with your existing 24h expiration auth trigger.

Paulo I'm unclear how this is relevant – are you suggesting that Retool is parsing our custom auth JWT?

I was suggesting manually setting the expiration for the JSON Web Token to ensure that Re-auth is not required because the token is expiring.

For example, if the time-based expiration auth trigger is set to one hour, we could sign the token with an expiration of one hour (or more):
Screenshot 2024-08-30 at 1.58.19 PM

That being said, the token shouldn't have an expiration if it's created without a expiresIn or exp key.

Re-authentication using JWT is required when the token expires, is revoked, or under certain security conditions. Since we are certain that it's not expiring, let's look at the other two options.

Since Retool is generating the token locally and using it, Retool doesn't manage the revocation of tokens directly. However, the token is attached to the user's session, logging out or ending the session in Retool would effectively "revoke" the token from Retool's perspective because it would no longer be available for use. This kind of revocation is more about session management within Retool rather than directly managing the JWT's validity from the server side.

If multiple users were using the same Retool account, they would experience this issue because the second session would invalidate the token from the existing one. But I doubt this is the case because they would also be prompted to log in again, which doesn't sound like it's happening.

The GraphQL endpoint or its associated authentication service is responsible for any revocation, including handling expiration and other security checks. Could you share a screenshot of this part of your setup:

In order to protect your privacy, feel free to send it to me as a DM if it includes sensitive data.

Hi @tommoor, let’s try setting up a refresh auth workflow for your resource, alongside the Auth Trigger for every query run. I checked internally, and it seems the Auth Trigger is actually running the refresh auth flow instead of auth. In your case, it was never running because we did not have a refresh auth workflow set up. In other words, the Auth Trigger was being ignored due to the missing refresh flow.

Regardless of whether or not we receive a non 200 response from GQL, the refresh auth trigger will still run for every query, so this should resolve the issue you’re experiencing.

Hi @tommoor, Did the above work?

Yes, I believe this has been working – noone has complained for a while!

You need to change the UX here to make the broken setup not possible, maybe have the refresh workflow required.

I'm glad to hear that things have been running smoothly on your end recently!

Thank you for the feedback!I completely agree with your point about improving the UX to prevent a broken setup. I've been working closely with the Resource Auth team on this, and they’ve been actively helping me to address this situation for you. Rest assured, I’ve added your feedback to our internal report, and we'll continue to work on making the refresh workflow a more seamless and required part of the process.

Hi Tom,

Wanted to follow up on this on behalf of engineering as well- we've updated the custom auth UI and our documentation on refresh auth workflow triggers, thanks again for flagging this for us!

Have a great day. :slight_smile:

1 Like