The mind is like a parachute. If it doesn't open, you're meat.

Adventures in Azure DevOps: iOS secrets

14 Jun 2019

This new-fangled (sic) mobile app development thing, I tell you. I have been hearing stories, horror stories.

For example, the "certificates for iOS applications" story. Pure horror. Grey hair overnight, stuff of nightmares.

And then they tell you you have to build these things in the cloud, on disposable VMs.

I have a rule when setting up projects for teams that aspire to the DevOps tag:

Just the repository

I should be able, with just the contents of the repository, to reconstruct the project, inclusive of development environment, production setup and released artifacts.

I will accept one exception to this rule and this is secrets. Under no circumstances should any type of secret, be that password, private key or certificate, end up in the repository.

At least that is the theory. To swing back to the title subject, handling of certificates in iOS app compilation has broken this rule in every single project I have seen to date. Admittedly, that number is in the low double digits.

Typically there will be a chosen deployment profile to be added to the repo for CI purposes and we will trust on the privacy of the repo, or the eventual expiration of the certificates.

So, finding out that Azure DevOps explicitly caters to exactly this case within the build pipelines is a very nice surprise.

Since the 2018 version there is a dedicated task (InstallAppleProvisioningProfile) for Apple provisioning profiles.

This is based on the secure files facility, which allows us to store secrets separately from the repos and use them in pipelines.

No exceptions to the rule

Back to Just the repository, just because I do not really like exceptions, especially exceptions that have a tendency to run amok.

Secrets are such an exception. You can get a lot of them: SSL certificates, signing certificates, SSH keys, Apple provisioning profiles, Android Keystore etc. A modern development environment catering to the cloud is useless without them.

A practical solution to this is something like KeePass, which is a password manager with no internet service to back it, but with a useful scripting interface.

The concept goes like this:

All secrets are kept in a KeePass database file, which is commited in the repo.

Whether you script secret retrieval from the KeePass DB to add it to Azure Devops (or whichever secret management service/tool you use), or just document their existence and prefered management solution I leave to you, dear reader.

That leaves us with one secret (the password/key to the KeePass database) to transmit over alternate channels.

Staying flexible

The KeePass DB approach also allows us to handle using the secrets locally with a bit of clever scripting.

If I want to follow my own rules, there needs to be a way to replicate the build locally, and just setting up XCode with my own key is not close enough a replica for my criteria (i.e. I still want to be able to produce a production build locally - just in case the cloud fails. Call me paranoid).

Using secure files introduces a deviation between local build and CI that cannot be replicated by the simple fact that secure files can only be downloaded with use of the Azure Devops pipeline task. There is no script alternative to allow you to get to the file outside a pipeline.

The bit of clever scripting would at least simulate the secure files function by retrieving the secret out of KeePass instead.

blog comments powered by Disqus