šŸ”‘ Building an app that stores multiple user API keys - not just mine

To quote @josh in Request for a Security Q&A Guide

Thatā€™s precisely what I want to do. However, my experience is that API keys need to be saved in the database as plain text which means they are still viewable by me and anyone who gains unauthorized access to my editor or database. That doesnā€™t seem right :confused:

Also, and please correct me if I am wrong, there isnā€™t a way to actually add API keys stored in the Bubble db to an API call in a ā€œsecretā€ or ā€œprivateā€ wayā€¦ meaning that these keys would have to be added in as parameters which, according to @mishav, can be seen by routers or other prying eyes:

So is it really okay to save other userā€™s API keys in a bubble database? If so, then how do you do it so that the application creator canā€™t see them? And if thatā€™s not possible, is the only other way to achieve this with storing OAuth2 session tokens?
Thanks in advance :smiley:

2 Likes

@antony, since that was your post that Josh had responded to on all of your security questions, would you by any chance have any pointers here?

@eve, can you assist here? Or perhaps flag this thread for a response from engineering? Thanks in advance. :slight_smile:

Using Api connector or plugins, credentials can not be change dynamically unfortunately.

Plugins can be given API keys dynamically through the use of parameters, as I had mentioned.

Are you confirming that this canā€™t be done in a secure way?

Hi! Yeah, indeed would be cool to have a way to set secrets from users as environment variables, however thatā€™s very tricky to do in a way that not even the app maker can see it due to how encryption works.
In short, at the very moment the user pastes the key in the browser you could grab it since you control the page.
So in the end you can have they key one way or the another and your users have to trust you.

Privacy through untrusted setup (which means your users do not trust you) like that can only be achieved by installed, open source and build verifiable apps. Unless thereā€™s some innovation Iā€™m unaware of.

1 Like

It really depends on what type of key you are talking about.

If you are asking people to paste a key into your app, and then you are using that as a parameter on a URL ā€¦ it had better be for something fairly safe.

However it looks like you are talking about Oauth2 which is a very different thing.

The keys are in the Header, not the URL.

And in this case you are usually given a time limited token, which can be refreshed. If you donā€™t have the right credentials ā€¦ you canā€™t refresh. If the user revokes access - it canā€™t be refreshed.

So whilst you should be looking after the Token, they are, by design, limited in the damage they can do should they get into the wild.

Therefore, storing it in the database in text is probably no terrible thing. Particularly as you need other credentials as well.

The issue we have with Bubble is that we also have to store OUR creds in text.

I have asked several times that the ā€œsecretā€ implemented in the Server Side Plugins should be available in the API connector.

The way I have got round this before is to use a third party to hold the tokens (in this case auth0) or use a small webtask to run the call. This means the credentials are not all in Bubble.

Nigel! I was hoping you would chime in :slight_smile:

I see, so really the current ā€œsecurestā€ way to integrate 3rd party services for multiple users via their API keys is to use Oauth2. Store the temporary token in plain text. Refresh it as they need it.

Assuming a bad actor obtains short lived access to my application

Zues forbid, if someone gained unauthorized control of my bubble application, then they could commandeer OAuth2 tokens saved in plain text. But, because the tokens need to be refreshed and are scoped to my application, a bad actor could at most use them only from my service. So they would have to not only have access, but for long enough to write custom code which would have to execute on my app in production. As a result, they would have to push an update, which would at least leave a trace. Assuming the breach is detected quickly and I still have access to my application, then I change my passwords / editor access permissions PLUS roll back the update. At this point, the breach has hopefully been fully contained. wait a minute thatā€™s not true. Couldnā€™t someone potentially write malicious logic on the development version of my application. Then copy over OAuth2 tokens from the live database to development and execute their logic against those tokens? All without pushing anything into production?

Anyway, in general, if a bad actor locks me out of my bubble application, then Iā€™m assuming I need to immediately notify Bubble of the breach for my application to be turned off / restarted from a pre-breach save point? Whatā€™s the process look like (does Bubble do anything to confirm itā€™s really me asking for a reset instead of a bad actor)?

Assuming a bad actor pushes an update that has done malicious things for a few hours or days

Correct me if I am wrongā€¦ but the damage is done?.. if they took actions with OAuth2 tokens on my hypothetical customerā€™s Plaid, Coinbase, insert other financial service, account, then thatā€™s irreversible? Best I can do is remove the malicious workflows (plugins, whatever it may be)?

Standing back a bit

Am I crazy for asking these questions? Because Iā€™m under the impression that these are table stakes considerations for building any SaaSā€¦ not just one one bubble. When it comes to security, itā€™s not a question of ā€œIf a breachā€ will happen but ā€œwhen a breach happensā€ and I want to be confident that my app is built in a way and I have protocol in place to limit those liabilities. ā€¦ Please no one tell me that security should be an after thought one day when maybe my application has lots of users.

Hey, thanks for your message Vini :slight_smile:

I think I see what youā€™re saying. I guess my concern isnā€™t about whether I can get my users to trust me. They trust me. And if it were that simple, it wouldnā€™t matter much that I have access to their Stripe accounts, Social Security Number, which ever sensitive thingā€¦ because Iā€™m a good guy and Iā€™m not going to do anything dumb to loose their trust or ruin their lives.

No, my concern is how do I limit the damage that can result from someone not nice getting access to the sensitive things that my users have trusted me with.

ā€¦ but it looks like the answer to that is OAuth2 tokens.

Ah I didnā€™t meant specifically you, shouldā€™ve made it clear, ā€œtrusted/untrusted setupā€ is a term from cryptography. Untrusted would be more or less the same of the ā€œdouble blindā€ studies used in medicine out there. Not the actual trust between people.

Anyway, temporary tokens are good and as far as I know, Oauth refresh token isnā€™t (or shouldnā€™t be) exposed to the browser so it stays within Bubbleā€™s servers. So thatā€™s secure.

Ah, gotcha Vini! I apologize, I misunderstood. Thanks again for your message :slight_smile:

1 Like

Hi, were you able to find a way to dynamically use api keys?

Iā€™m trying to use different stripe api keys based the specific user and thought it might be similar to what you were trying to do.

Depending on your use case, you may be able to get away with using Stripe Connect. But if you absolutely need individual userā€™s Stripe API keys, then unfortunately I did not come up with a better solution than the one presented here :frowning: Sorry!

1 Like

We are working on a marketing automation platform that relies on Users being able to store api keys in Bubble.io along with a passcode so that we can ping their event system or CRM and move information back and forth. We also want to enable the User to send SMS/TXT to contacts or customers from the platform where we might connect to SendGrid and then they use DKIM, SPF, records via CNAME to allow us to send on behalf of their domain. Does not sound like Bubble is able to support that level of api connectivity, APIā€™s that are used in the development of the application are simple enough, APIā€™s that require USER ownership and inputs other than OAuth seems to be a different story.

1 Like

Thatā€™s, sadly, exactly right. And since bubble isnā€™t currently designed around this use case (in a single tenant app), API keys would have to be stored in the database as clear text (because there is no ā€œprivateā€ database field that can be accessed as needed here).

yes - this requires PathFix to implement well and for users of the automation platform to know how to configure their tools instead of using one we provide. Kind of a problem. Still quite a bit of automation the platform can do but it is reliant on the Users other apps (MailChimp or SendGrid or SendinBlue) accounts to be fully functional.

Hi, was this ever solved or any new features that deal with this?