6

I get the feeling I'm asking the wrong type of question here as it was not googleable within 30 seconds. Please let me know.

Anyway, I have my environment.ts and environment.prod.ts all set up with urls and api keys to backend and third party services. But I've read that it's not safe practice to keep API keys there. Where should I be putting them? If it's indeed somewhere else, what's the simplest way to do it?

Alexander Soare
  • 2,825
  • 3
  • 25
  • 53

1 Answers1

5

If I understand your question correctly, you're looking at two potential key misuse points here:

  1. Developers can accidentally use production keys while developing your app - this is easy enough to solve by storing your keys in your CI pipeline (assuming you've got one) and having it inject the correct secret into correct environment configuration. Some tools that can be of interest: Octopus, Hashicorp Vault. Developers then will only have development keys in their code base. Bear in mind - if you are using version control systems - it's not going to be enough to just delete your production codes and add a new commit - there are tools that let you search your commit history for accidentally exposed secrets, so you'll have to change your keys

  2. Users can reverse-engineer your app and extract keys from the code. This one is harder to tackle as it hugely depends on the OS, version and how you work with secrets. Generally you would like to avoid storing secrets in your app at all and rather obtain them when authenticating users. After that - you'd leverage your target OS secure local store features (keeping in mind that even that does not guarantee 100% protection). For 3rd party access, consider proxying the requests through your server to conceal the keys Some more inspiration can be found here

UPD to clarify your concerns re user interaction, consider this simplified workflow:

1) User issues an unauthenticated request to your backend /authorise endpoint that will check username, password and return a token1 (preferably JWT)

2) your app stores this token1 in local store on the device - this is the only secret that user will ever have access to and it's specific to that user

3) Your user makes an authenticated request using token1 to your /3rd-party-api-proxy

4) your server will validate the token1 from step3 and make the actual request to 3rd party using token2 that you never exposed.

5) your 3rd party request succeeds and you return data to the user.

with this flow your token2 never gets exposed and you always know which user requested access to 3rd party API (you can add logging, audit, and what not). There;s plenty of articles in the Internet on how to architect this thing, I just outlined very basic concepts here, hoping this gives you some food for thought.

timur
  • 14,239
  • 2
  • 11
  • 32
  • Thanks. This is a very low key project so I'm not thinking of doing anything fancy like injecting secrets (if that even is "fancy"). So I think the proxy thing makes sense. It just feels a bit weird to me though because a user can still... yeah you know. But I guess in the end I'm asking for something logically impossible here, which is not revealing any secrets while still letting any client access my service. I guess your answer solves my question. – Alexander Soare Dec 11 '19 at 20:09
  • 1
    Some extra clarification for point #2 (app / system design): client side apps are not secure. period end of story. When you see API guidelines that say "secure your development key", that can be interpreted as "do not put this in your front end codebase" for reason #2 that timur listed (and also for websites, any network requests can be inspected via dev tools). What I've done in these scenarios is create a simple sever side app that makes the call to 3rd party API with my dev key, and my web app calls my server side app. Agree completely with point #1 about development best practices – Chris Newman Dec 11 '19 at 20:18