FREE TRIAL: Accelerate your app development career with Hacking with Swift+! >>

What's the right way to compile in app secrets?

Forums > macOS

So, I'm writing a Twitter client. The Twitter API wants me to have an app key and an app secret, so that Twitter can keep track of how badly my app is behaving versus others. These tokens need to be compiled in to the application, so they should be part of the source code somehow. However, I'd like to keep these out of the code repository, so that if I release the source code there aren't a zillion clones with code I know nothing about but which are still using my app credentials to access the API.

With other languages and other build environments, I've seen many different ways of solving this class of problem. A code generation build step, which reads the secrets out of an environment variable or a key store is one solution. Another is to inject the tokens directly during compilation, using pragmas, environment variables, and compiler flags (essentially rolling the code generation into the compilation step). Or even just putting the secret(s) in a file by themselves and not checking that file in to source control.

What is the Xcode + Swift way of solving this problem?

   

Also interested in this answer, in my current app that's in testing I have stored it in the Info.plist, accessed via

Bundle.main.object(forInfoDictionaryKey: "YourKey")

and not checking the Info.plist in, but that's not really a solution for a production app I don't think.

I was thinking of maybe having the app call an API on first launch and storing the key from their in UserDefaults

edit: just realised this is macOS forum, not even sure that's available in a macOS app..

   

I put this question in the macOS forum just because that's the app I'm working on, but the Bundle API applies across all the platforms. I'm currently thinking that you're on the right track, and based on this (old) Stack Overflow discussion I think the way to go is to put the secrets in their own file that is not checked in. So, instead of Info.plist, put the data in AppSecrets.plist and read it from there.

   

This approach would get round the repository issue but the file would still be in the packaged app, so especially on macOS just a right click and show package contents and your file and subsequently the API key/secret is exposed.

The API I am using costs money per request, so I don't think I will risk it.

   

Hmm. Yeah, that's a point I hadn't thought of. So the flow of behavior has to go something like this:

  1. app starting up
  2. connect to some repository of secret knowledge, proving that the app is the app and not a bad guy
  3. request the secret knowledge

In my enterprise development days, that repository of secret knowledge was a separate application running on the same hardware and compiled and installed by one of the few people trusted with the knowledge.

In your case, a phone app, you might create a web service that requires some public/private key and where the transport is wrapped through SSL. That sounds complicated, but it's really not that bad so long as your source isn't available -- you can compile the key in and if someone packet-sniffs the transaction all they'll get is enciphered bits. I've been looking at CryptoKit and Apple has made it way more understandable than the bouncycastle APIs I had to deal with in Java.

For a desktop app, I'm going to have to think about this for a bit.

1      

Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Get started

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.