replicate / replicate-swift

Swift client for Replicate
https://replicate.com
Apache License 2.0
157 stars 33 forks source link

API Key Security #77

Open ppoh71 opened 5 months ago

ppoh71 commented 5 months ago

The Disclaimer on security is misleading and will result in a high possibility of a compromised API Key:

"Don't store secrets in code or any other resources bundled with your app. Instead, fetch them from CloudKit or another server and store them in the keychain."

Even if you fetch the key from Cloudkit or any other server it will be exposed in your client and can be hijacked when you make API calls.

The API key should never be in your app! Your app should never connect to the API servers directly! This architecture is fundamentally unsafe!

You need a server where the key is safely stored that makes the calls to the replicate API.

You can use Lambda, Google/Firebase Function, Vercel ServerActions to do the job. Here is a tutorial on how I implement this for the OpenAI API. This scenario is basically the same for every API you want to use. https://medium.com/@makiex/how-to-safely-use-openai-in-your-app-with-firebase-cloud-functions-10a55ba95d11

This should be documented here somewhere.

mattt commented 5 months ago

@ppoh71 Thank you for sharing your thoughts. Proxying requests through another server is indeed a way to protect credentials for a web API. But in effect, that moves the problem of authorization and rate limiting to the proxy. An unauthenticated proxy endpoint has similar potential for abuse.

The suggestion to fetch credentials through CloudKit or another server protects against exfiltration from the binary itself, and offers a way to roll compromised credentials. And those credentials may be Replicate API tokens or for the proxy API. In either case, I think we agree that, 1) credentials shouldn't be included in an app bundle and, 2) any sensitive information should be stored in Keychain.

I think you're right that documentation for setting up a proxy and configuring the client to use that proxy would be helpful. That's been on my backlog of things to do, and I hope to do that soon.

ppoh71 commented 5 months ago

It´s a general problem that nearly every API has. Maybe you want to have a look at similar discussions going on: https://github.com/MacPaw/OpenAI/discussions/116

I am working on a server-side Firebase Functions solution for the OpenAI API which has the same challenge.

Solution: iOS Client -> Firebase Functions Server -> OpenAI stuff.

Here is a blog post about it: https://medium.com/firebase-developers/mastering-firebase-cloud-functions-and-openai-in-a-react-app-a-step-by-step-guide-1dfa58176009

My next project will use the replicate API so I will have to make something similar for replicate. I can share that here, might be helpful hopefully.

This is only one of many solutions but it takes away the extra layer of complexity needed for your own server/proxy.