How to create static/permanent API tokens for users?

is there any way to generate static/permanent API tokens for users in Bubble?

I want to let users set up webhooks in other systems that will send data to my Bubble app and it seems silly to ask them to change the tokens in their set-ups now and then.

I learnt from Bubble support that API tokens generated with the “Log a user in” or “Sign a user up” actions get revoked at random from time to time even if you set “Stay logged in” to Yes (out of 40 test accounts I’ve created over the last few months only 15 tokens are still valid!).

Is there a simple solution or would I need to set up external authentication + API gateway services?

That’s the best way to do it. You can just use an error handler so if it errors for authentication you just regenerate a new one.

By “That’s the best way to do it.” you mean setting up an external service?

No by using internal auth and just having an error handler to reAuth if failed. To my knowledge it’s the only way to maintain true security.

Custom API keys wouldn’t be checkable if you have correct privacy rules.

I’m not sure of any 3rd party auth services that would maintain full security and get you custom tokens. I believe you’d be sacrificing security somewhere to do this any other way than what bubble recommends.

Hm, ok. I’m not a dev but I imagined I could pass to some external service the login/password of each new user, and it would return API tokens.
Then, my users would call API endpoints in the external service with the token it generated, and it would pass the request to bubble using basic auth.
But honestly, setting it up without a dev is not a thought I’d welcome easily.

Anyway, so if I understand correctly, you’re saying I can’t let users set up simple webhooks and I’ll need to create regular OAuth integrations that will handle token refresh, correct?

What will they be using the API key for?

Should be as simple as having them use basic auth with refresh tokens as many apps require.

If they try to make a call and get an unauthorized error they have an error handler that gets called to rerun the auth call and rerun the original call.

Users would send data, e.g., when a form submission from Typeform occurs.
For MVP/beta I wanted to avoid anything more complicated and simply let users set up webhooks like this:

Same would go for Zendesk, Hubspot, etc. without having to dive into their docs that much.

If this is just webhooks you could probably use similar logic to what George recommended here. For most other stuff you’ll want to use the standard bubble auth flows.

1 Like

I went through the post but I’m not sure what you’re referring to.
I know about the possibility of using the “?api_token” parameter — that’s how I do it currently.

And you can’t be referring to using the admin-level API token I can generate in settings, right? This works for “internal” integrations like Stripe, but not when I want to let users integrate their systems with my app.
With this token they wouldn’t log in within the scope of their account but rather with my, admin, scope and to save something in their account I wouldn’t be able to use “Current user” but rather would need to use some additional url param with their unique_id and “Do search for” the user every time they make a call. Per my understanding you don’t make these tokens public to your users.

Or am I missing something here?

You’d don’t really want to use that at all. It gives access to all calls and overrides security it’s your admin level key.

More some of the other ways to verify the call like IP, IDs, etc. you really have to check their documentation to proceed.

Exactly, I never intended to use it.

Thanks for your answers and sorry for dragging this, but I’m still missing your point or maybe we’re talking about different things here. I’m looking for ways to authenticate/authorize calls in Bubble. Not verify that a call comes from a specific source.

Edit: I never know the difference between authentication & authorization (and if it makes a difference here) so maybe safer: I want to log users in when they make a call :smiley:
I currently use tokens generated on login/signup but they are revoked at random and I’m looking for more stable solution to do this.

I think what @chris.williamson1996 has pointed out regarding using the Bubble auth flows is probably how most achieve this. The process might look like this:

  1. Your user enters their credentials to access your app into 3rd party provider
  2. You create an un authenticated backend workflow that logs the user in per step 1, using those credentials
  3. You then proceed to use this resource/webhook accordingly (as that user, with privacy rules applying accordingly)

I’m pretty sure @jacobgershkovich has a good YouTube video showcasing how to do something similar. Definitely check that out for full steps.

There’s other ways to do it but believe this is what’s cited in the manual.

I’ve been testing a method where a user can generate their token in my app, then use that token via the 3rd party as a means of granting access through a webhook. That way I’m not asking someone to store their credentials in a third party app.

I accept this token in an un authenticated backend workflow and if the token corresponds to a user’s account/tenant (I.e. if Do a Search For finds a token that matches), it creates the resource with that account’s association. There’s nothing else the user can do with this token so if it was compromised then I feel there’s not a lot of risk involved (contrary to credentials being exposed).

I guess you could blend these things together and have an area in your app enabling to create a “webhook account”, with privacy rules restricting what they can do within your tenant. Then use the process flow as described above to get access to your app to accept the webhook. It will probably depend on the apps that you’re looking to support and what they can support!

Will look for it, thanks.

Why do you need an unauthenticated workflow if you store credentials in the 3rd party and you can log in with every call simply passing it in url (I think it worked this way or am I mistaken)?
Edit: Right, doesn’t log you in automatically so you need the action.
Anyway, I don’t want to have users expose their credentials, hence all this discussion.

Either I’m misunderstanding something, or this is what I do currently. Generate API token with the “Log user in” action, display it to user, and have them include it in the webhook setup (in the “?api_token=XXX” paramter) in the 3rd party system that makes a call to my endpoint.

Why do you accept the token in an unauthenticated workflow if with this token you can log a user in. Or are you talking here about some random generated string (and not bubble API token) that you store in the database and use to identify a user with “do a search for”. So then you’re never actually logging the user in?

I thought more about what you guys said and I believe I see 2 ways of understanding all that:


  1. Create an unauthenticated endpoint where users will pass an id in the url.

  1. Use “Make changes to a thing” and search for the user based on the id passed in URL (without doing any actual changes).

  1. Then, in every subsequent call, using the information of whether the user was found or not as a condition.

Screenshot 2023-10-31 at 09.18.33

Is that correct?
But aren’t there are some problems with this approach? I think tried this when I was setting it all up (a long time ago):

  • This requires me to specify the parameters manually because if I use “Detect request data” I can’t specify the querystring parameter where users would pass the id. But then, if the request body has a nested structure it won’t work — there’s no way to specify it manually, is there? I need to use “Detect request data”. And then can’t identify the call.

Here, it’s more like a 2-step approach for users.

  1. First, users will need to send a test event to some “identification” endpoint. And if the webhook response body contains some id of their account in the 3rd party system, I’ll save it in the database.
  2. Then, in the actual webhook setup they will call another endpoint and I will use the previously collected id of their 3rd party system’s account to identify the user in my bubble app, and continue just as in the Method 1 above.

This indeed would solve the problem from the previous method but creates another one:

  • What if the request body doesn’t contain any account-specific id I can use to identify a user’s account in the 3rd party system?

In my case it contains just an event id which changes with every call.

Is any of these two methods something you had in mind? Because I believe neither of these methods works for me. Or am I still missing something?

  1. Have API Token data type with a random string attached to a User/Project/Company whatever.

  2. User calls[APIToken]

  3. If Do a search for API Token : count is 0 (or first item is empty), terminate the workflow

  4. If not, work out the relevant user/company/project from the API Token and do whatever you want.

To further increase security you could also require them to pass their User ID (and verify the User ID matches the API token). Also, apply standard checks on the request origin etc to verify it’s coming from that webhook provider rather than someone’s Postman app :slight_smile:

@georgecollier But this is what I described in the “Method 1” above, and I see this problem: