Hide chapters

iOS App Distribution & Best Practices

Before You Begin

Section 0: 3 chapters
Show chapters Hide chapters

Section I: iOS App Distribution & Best Practices

Section 1: 17 chapters
Show chapters Hide chapters

12. Managing Secrets
Written by Keegan Rush

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

You may not have known, but Emitron has a secret. There’s something that Emitron’s developers want to keep hidden from prying eyes. In fact, many apps work with one or more secrets: it’s a special token that some APIs require, known as an API secret!

A secret is private data that your app needs to function. It could be an API secret, also known as an API key, or a password to a particular service or tool, like database credentials.

Many web services require that you use a secret when accessing their API. An API key is a private token that’s unique to you. By providing your secret when making API calls, the owner of the API you’re using can verify your identity.

There could be one API key per app, or keys could be unique for each developer. They let the creators of an API know who is using (and possibly abusing) their service. For paid services, it lets the service provider charge based on your usage.

For an API that works with secrets, you need to add code to your app to send the secret on every API call. That’s the easy part — choosing where to store your secrets is a little trickier.

In this chapter, you’ll learn of some choices you can make when managing your secrets. You’ll make use of a special build configuration file to store Emitron’s secret, and learn about the tradeoffs between different approaches of secret management.

Along the way, you’ll pick up some new skills to use with build configuration files. So, time to get started!

Why secrets are secret

A secret is a sensitive piece of data, like a password, that you need to protect from prying eyes. Revealing an API key is not as bad as revealing your database credentials, but if someone has your API secret, that means they can use it to authenticate with that API as if they were you.

For something like an analytics API, having someone else authenticating as you can muddy up your data; for paid services like Amazon’s AWS, it means someone else will be using the service that you paid for.

Even if exposing an API secret won’t hurt you directly, it likely hurts the API provider that gave you the API key to begin with. So, it’s important that you keep it secure, because one day, you might be the one creating the API! :]

How secrets get exposed

Your API secrets could be exposed to three groups of people:

Secrets in Emitron

In Xcode, open AppDelegate.swift. In applicationDidFinishLaunching(_:), find the line that initializes guardpost:

guardpost = Guardpost(
  baseUrl: "",
  urlScheme: "com.razeware.emitron://",
  ssoSecret: "155bdf4d4f847e77aec11624ab9c17b4",
  persistenceStore: persistenceStore)
ssoSecret: "155bdf4d4f847e77aec11624ab9c17b4"

The problem with hard-coded secrets

Secrets are subject to change. The SSO Secret that’s hard-coded in AppDelegate.swift is only a sample; if you were building your own app with the API, you’d need your own secret.

Secrets in configuration files

By putting your secrets into a build configuration file, it becomes easier to change secrets based on build types.

Secrets and security

Keeping your secrets in a configuration file solves the problems mentioned above, but it still isn’t the most secure option out there.

Storing the SSO Secret

For the secrets configuration file, you’ll do something similar to Dev.xcconfig and Alpha.xcconfig.

SSO_SECRET = 155bdf4d4f847e77aec11624ab9c17b4

Applying the secrets configuration file

In the Project navigator, click on the Emitron project to reach the project screen. Make sure you’re on the project’s Info tab.

Configuration file imports

While setting the project’s configuration file to Secrets.xcconfig, you may have noticed that you can’t have multiple configuration files at the same level.

#include "./Secrets.xcconfig"

Referencing build settings in code

Unfortunately, your Swift code can’t directly access any build settings. But, your code can read values from your app’s Info.plist, which is a file containing special metadata for your app.

Adding the SSO Secret to Info.plist

You need to put the SSO Secret in Info.plist in order for it to be accessible in code.

Getting the value of the SSO Secret in code

Open AppDelegate.swift. In applicationDidFinishLaunching(_:), replace initialization of guardpost:

guardpost = Guardpost(
  baseUrl: "",
  urlScheme: "com.razeware.emitron://",
  ssoSecret: "155bdf4d4f847e77aec11624ab9c17b4",
  persistenceStore: persistenceStore)
// 1.
let ssoSecret = Bundle.main.object(
  forInfoDictionaryKey: "SSO_SECRET") as? String
guardpost = Guardpost(
  baseUrl: "",
  urlScheme: "com.razeware.emitron://",
  // 2.
  ssoSecret: ssoSecret ?? "",
  persistenceStore: persistenceStore)

Key points

  • Secrets don’t belong in code, but they can be stored in configuration files.
  • Leaking an API key isn’t as bad as leaking a database password, but you should take care with any secret.
  • You can create your own build settings and use them how you choose.
  • Build configuration files can import one another.
  • You can’t access build settings in Swift code directly, but you can access entries in your Info.plist.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2023 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now