Utility to generate a xcframework
for handling secure keys in iOS projects.
- Ruby 3.3.6 or higher
- iOS 13.0 or higher
- macOS 11.0 or higher
You can install the SecureKeys
utility using Homebrew using the following command:
brew tap derian-cordoba/secure-keys
brew install derian-cordoba/secure-keys/secure-keys
For more details, you can visit the homebrew-secure-keys repository.
Another way, you can install the SecureKeys
utility using gem
command:
gem install secure-keys
If you using bundler
you can add the secure-keys
gem to the Gemfile
:
gem 'secure-keys'
Then, you can install the gem using:
bundle install
For more information about the gem, you can visit the secure-keys page.
As first step, you need to determine the keys that you want to use in your iOS project. You can define the keys from Keychain or env variables.
The source is determined by the current platform local or CI / cloud using the CI
environment variable.
If the CI
environment variable is set to true
, the keys are read from the environment variables. Otherwise, the keys are read from the Keychain.
You can configure your keys like this:
- You need to define the
secure-keys
record in the Keychain with the key name and the key value.
The value for this key should be all the key names separated by a comma.
security add-generic-password -a "secure-keys" -s "secure-keys" -w "githubToken,apiKey"
If you want to use another keychain identifier, you can define an env variable named SECURE_KEYS_IDENTIFIER
to set the keychain identifier.
export SECURE_KEYS_IDENTIFIER="your-keychain-identifier"
security add-generic-password -a "$SECURE_KEYS_IDENTIFIER" -s "$SECURE_KEYS_IDENTIFIER" -w "githubToken,apiKey"
- You can add new keys using the
security
command.
security add-generic-password -a "secure-keys" -s "apiKey" -w "your-api-key"
Using custom keychain identifier:
security add-generic-password -a "$SECURE_KEYS_IDENTIFIER" -s "apiKey" -w "your-api-key"
- You can define the keys in the
.env
file or export the keys as environment variables.
export SECURE_KEYS_IDENTIFIER="github-token,api_key,firebaseToken"
export GITHUB_TOKEN="your-github-token"
export API_KEY="your-api-key"
export FIREBASETOKEN="your-firebase-token"
The key names are formatted in uppercase and replace the
-
with_
.
Important
If you want to use another demiliter, you can define an env variable named SECURE_KEYS_DELIMITER
to set the delimiter.
export SECURE_KEYS_DELIMITER="|"
export SECURE_KEYS_IDENTIFIER="github-token|api_key|firebaseToken"
To generate the SecureKeys.xcframework
use the secure-keys
command in the iOS project root directory.
Using global gem:
secure-keys
Using bundler:
bundle exec secure-keys
To get more information about the command, you can use the --help
option.
secure-keys --help
# Output
Usage: secure-keys [--options]
-h, --help Use the provided commands to select the params
--add-xcframework-to-target TARGET Add the xcframework to the target
-d, --delimiter DELIMITER The delimiter to use for the key access (default: ",")
-i, --identifier IDENTIFIER The identifier to use for the key access (default: "secure-keys")
--verbose Enable verbose mode (default: false)
-v, --version Show the secure-keys version
-x, --xcodeproj XCODEPROJ The Xcode project path (default: the first found Xcode project)
To avoid defining the SECURE_KEYS_IDENTIFIER
and SECURE_KEYS_DELIMITER
env variables, you can use the --identifier
and --delimiter
options.
secure-keys --identifier "your-keychain-or-env-variable-identifier" --delimiter "|"
Also, you can use the short options:
secure-keys -i "your-keychain-or-env-variable-identifier" -d "|"
Within the iOS project, you can use the SecureKeys
target dependency like:
import SecureKeys
// Using key directly in the code
let apiKey = SecureKey.apiKey.decryptedValue
// Using key from `SecureKey` enum
let someKey: String = key(for: .someKey)
// Alternative way to use key from `SecureKey` enum
let someKey: String = key(.someKey)
// Using raw value from `SecureKey` enum
let apiKey: SecureKey = "apiKey".secretKey
// Using raw value from `SecureKey` enum with decrypted value
let apiKey: String = "apiKey".secretKey.decryptedValue
// Using `key` method to get the key
let apiKey: String = .key(for: .apiKey)
From the secure-keys
command, you can use the --add-xcframework-to-target
option to add the SecureKeys.xcframework
to the iOS project.
secure-keys --add-xcframework-to-target "YourTargetName"
Also, you can specify your Xcode project path using the --xcodeproj
option.
secure-keys --add-xcframework-to-target "YourTargetName" --xcodeproj "/path/to/your/project.xcodeproj"
Important
By default, the xcodeproj path would be the first found Xcode project.
This command will generate the SecureKeys.xcframework
and add it to the iOS project.
- From the iOS project, click on the project target, select the
General
tab, and scroll down to theFrameworks, Libraries, and Embedded Content
section.
- Click on the
Add Other...
button and click on theAdd Files...
option.
- Navigate to the
keys
directory and select theSecureKeys.xcframework
folder.
Now the
SecureKeys.xcframework
is added to the iOS project.
- Click on the
Build settings
tab and search for theSearch Paths
section.
Add the path to the
SecureKeys.xcframework
in theFramework Search Paths
section.
$(inherited)
$(SRCROOT)/.secure-keys
The process when the script is executed is:
-
Create a
.secure-keys
directory. -
Create a temporary
Swift Package
in the.secure-keys
directory. -
Copy the
SecureKeys
source code to the temporarySwift Package
.public enum SecureKey { // MARK: - Cases case apiKey case someKey case unknown // MARK: - Properties /// The decrypted value of the key public var decryptedValue: String { switch self { case .apiKey: [1, 2, 4].decrypt(key: [248, 53, 26], iv: [148, 55, 47], tag: [119, 81]) case .someKey: [1, 2, 4].decrypt(key: [248, 53, 26], iv: [148, 55, 47], tag: [119, 81]) case .unknown: fatalError("Unknown key \(rawValue)") } } }
-
Generate the
SecureKeys.xcframework
using the temporarySwift Package
. -
Remove the temporary
Swift Package
.
This project is licensed under the MIT License.