4

I am building an application that uses two legged authentication. I got an API key and API Secret, but now I am confused.

I am currently storing my api keys and secrets in a .yml file. But I would like to distribute the .app code, which will end up having the .yml file.

But the .app file will contain the .yml, file, which is bad since everyone will be able to see the API key and Secret.

How can I store the API key and Secret such that my application can access the key and secret without the users seeing it?

  • Related: [Protecting private API keys in applications](https://stackoverflow.com/questions/14570989/best-practice-for-storing-and-protecting-private-api-keys-in-applications) – Thomas Weller Apr 08 '21 at 15:51
  • The answers here seem to be focused on compiled applications. Yes, some could be applied to a Ruby or Python script. For example, I could set up a separate server to hold the keys and route requests through it; but, that seems like overkill for a 200-line script that wouldn't otherwise have any external infrastructure. – Zack Apr 08 '21 at 22:19

2 Answers2

2

The answer depends on a few variables:

  1. Is your source included?
  2. Is it possible to use a server to call the API for you? If so, can you also apply restrictions to the call that the server makes?
  3. Is using compiled code for where you store the key an option? If so, is it possible to obfuscate it?

Here are my suggestions for different scenarios from experience:

The source is not included and using a server is an option, and restrictions can be applied, however using compiled code is not an argument

Then use a server to make requests. Let's say you need to make a call to example.com/api/v1, and you want to call a specific function with a specific set of arguments, then you can only allow requests to that specific API, with that specific set of arguments, and that specific function. This way, it means nothing to a potential attacker since it only calls to one function and nothing else.

The source is not included, using a server is not an option, and compiled code is not an option either

Well, there's not much you can do, obfuscation is your best shot. The best way to do something like this is to hide it deep within your code, and make it obscure, etc., etc., etc.,

The source is included, using a server is not an option, but you can use compiled code

Use really obfuscated assembly and don't share the source for that if you can. For instance, you can have red herring instructions, and just like before, you should hide it deep in your code.

The source is not included, using a server is not an option, but you can use compiled code

For this it's the same as above, since the source for the assembly wouldn't be included

If I didn't list your scenario here, then feel free to comment and I'll edit my answer

zurgeg
  • 510
  • 6
  • 18
  • I'm thinking of a 200-line ruby script (possibly released as a gem). Thus (1) source is included, (2) using a server is not a practical option (the program isn't big/complex enough, (3) using compiled code is also not practical (it would be more complex than the script itself). – Zack Apr 11 '21 at 00:52
  • Hmm, can’t really help you there sadly. – zurgeg Apr 11 '21 at 00:53
0

While I consider the existing answer technically correct, it may be wroth pointing out that there are some security issues with hardcoding api keys in distributed software.

The nature of an API key is volatile, it is not designed to last forever.

What would happen if the API key is invalidated? Wouldn't that render all distributed software useless then? And what would happen if the API key has write privileges and is compromised? How could you distinguish between legit and malicious writes?

Even though I understand the overhead, a scenario were the end user can set dedicated keys, obtained by the end user itself, and a way to replace that initial key, would help with above two questions.

One of the API Key features is to be used by a machine that acts on behalf of a user, but if all the users are the same, this feature becomes meaningless.

castel
  • 158
  • 3
  • 9