Effortless Secrets Management for Swift projects using Code Generation.
A simpler approach than using GYB files as outlined by the NSHipster article
on Secret Management on iOS using Swift Build Tool Plugin (Swift 5.6+).
Features
Provides a convenient way to keep secrets out of source code
Encrypts Secrets when they are at rest in your applications binary
Provides convenient access through global Secrets
Run as manual Script, SPM plugin or Xcode plugin
Less than 250 lines of Swift
Usage
Use a .env bash script to export Secrets you want available to your source code.
Using this plugin the following Swift code is generated and available directly to your targets
source code, no need for an import.
// This file is automatically generated
import struct Foundation.Data
private func secret(_ secret: String) -> String {
let data = Data(base64Encoded: secret)
guard let data else {
fatalError("Failed to decode a secret!")
}
func decrypt(_ data: Data) -> String {
let key = Data(base64Encoded: "JbiOFqC+jH3l8pwCLE4Nca4f19M7YAbeTUo7rhnSSG7ctZMlc+dg5FI9o3zrSbCgFLtDd0uC9EcCC+jd6hlVDA==")!
var output: [UTF8.CodeUnit] = []
for (offset, ch) in data.enumerated() {
output.append(ch ^ key[offset % key.count])
}
return String(bytes: output, encoding: .utf8)!
}
return decrypt(data)
}
enum Secrets {
static let apiClientSecret = secret("TcrIWpby/A6io8xxaR9pGN55g4BXD3WXez5U3kCGLgaQ+9BDOpECggdHlg7dJ9OXJv8OJSnOuHRveIKoq187VQ==")
static let analyticsKey = secret("QdnlJZfv+kiutetMXx91J+RnvZliUkmqLx9V6VKKJAPv2PhhMpcztjRP4g+/AeHEUukQMi3wtX57Yobovi0MWA==")
static let backendKey = secret("bs/+ftTM3hWCvcRhfiowAY8o5IJVEleSOAVRk2uqcAu4//toCtJSlwVY8iygBMjvbPp7HwXhsDVFMtWFuG8Uew==")
static let loggerKey = secret("Su+5T/H160+AvP9URjRfFcNco75cI0WNDzoJymmYJCLp+9AII41BhSFuliSPGfePOZYRRSPHy2g/QseJhnYhXA==")
}
Setup
Requires Swift 5.6 (Xcode 13.3+)
Create a .env file in your root directory (alongside Package.swift or your *.xcodeproj).
You can define a prefix to strip from all your exported keys with #prefix. See Usage
for an example .env file.
This package doesn’t aim to keep your Secrets safe from intentional attacks. It’s aim is to make it
convenient to adopt best practice Secrets Management in Swift projects. It does this by ensuring
keeping your secrets out of your Source Code doesn’t sacrifice usability, and that when compiled
into your application, they are not stored in plaintext. Remember
Client Secrecy is Impossible.
SecretsManager
Effortless Secrets Management for Swift projects using Code Generation. A simpler approach than using GYB files as outlined by the NSHipster article on Secret Management on iOS using Swift Build Tool Plugin (Swift 5.6+).
Features
Secrets
Usage
Use a
.env
bash script to export Secrets you want available to your source code.Using this plugin the following Swift code is generated and available directly to your targets source code, no need for an import.
Setup
Create a
.env
file in your root directory (alongsidePackage.swift
or your*.xcodeproj
). You can define a prefix to strip from all your exported keys with#prefix
. See Usage for an example.env
file.Xcode Projects
SecretsManagerPlugin
to Run Build Tool Plug-insSwift Package Manager
Add the following to your
Package.swift
files dependencies array:And to the targets Secrets should be available to, after their
dependencies
:Security
This package doesn’t aim to keep your Secrets safe from intentional attacks. It’s aim is to make it convenient to adopt best practice Secrets Management in Swift projects. It does this by ensuring keeping your secrets out of your Source Code doesn’t sacrifice usability, and that when compiled into your application, they are not stored in plaintext. Remember Client Secrecy is Impossible.