Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vdka/SecretsManager
A Swift Package to generate and use encrypted secrets in your app
https://github.com/vdka/SecretsManager
plugin secret-management secrets secrets-management secrets-manager swift swift-package-manager swift-package-manager-plugin swift-package-plugin
Last synced: about 23 hours ago
JSON representation
A Swift Package to generate and use encrypted secrets in your app
- Host: GitHub
- URL: https://github.com/vdka/SecretsManager
- Owner: vdka
- License: mit
- Created: 2022-10-01T07:29:29.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-04T00:55:54.000Z (8 months ago)
- Last Synced: 2024-11-07T15:03:17.577Z (9 days ago)
- Topics: plugin, secret-management, secrets, secrets-management, secrets-manager, swift, swift-package-manager, swift-package-manager-plugin, swift-package-plugin
- Language: Swift
- Homepage:
- Size: 8.79 KB
- Stars: 28
- Watchers: 1
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# SecretsManager
Effortless Secrets Management for Swift projects using Code Generation.
A simpler approach than using GYB files as outlined by the [NSHipster article](https://nshipster.com/secrets/#cosmic-brain-obfuscate-secrets-using-code-generation)
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.
```bash
#prefix ORGexport ORG_API_CLIENT_SECRET=hrFL6LpsGQPsEQdipfTSlosI6topYTfhLNCfIvbfUz5r6nc72DMRbLL3msjuAFnY
export ORG_ANALYTICS_KEY=dak37Qv5KGwNsQxVJxjJY2OtbUnGKXlm3mkDApSRfrAsTHQdFRSEfrA9yin5T4YT
export ORG_BACKEND_KEY='KwphtrRhgOXcRd=p!73QnrQLuOj=rx8edJhMy52sWeQPKMxOxA8hNcDrG9=XRvAw'
export ORG_LOGGER_KEY='oW7YQKg2eNcVjzRdmCtmgCCSBp2dpJlL5NC-Pj!asS5XdPG/--R2hE?/=I/TlotP'
```Using this plugin the following Swift code is generated and available directly to your targets
source code, no need for an import.```swift
// This file is automatically generatedimport 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](#usage)
for an example `.env` file.### Xcode Projects
> [Visual Guide](https://github.com/vdka/SecretsManager/wiki/Xcode-Integration)1. Add SecretsManager package
- When prompted to **Choose Package Products for SecretsManager** don't select any products
2. In **Targets > Build Phases** add `SecretsManagerPlugin` to **Run Build Tool Plug-ins**
3. Build, triggering a prompt to trust the plugin
- From the issue navigator you can goto the plugin and read the source code before trusting### Swift Package Manager
Add the following to your `Package.swift` files dependencies array:
```swift
.package(url: "https://github.com/vdka/SecretsManager.git", from: "1.0.0"),
```And to the targets Secrets should be available to, after their `dependencies`:
```swift
plugins: [
.plugin(name: "SecretsManagerPlugin", package: "SecretsManager"),
]
```### Xcode Cloud
When running in Xcode cloud you will want the secret values to come from the actual environment. In
order to tell the plugin which keys to read from the environment from you can create a `.env` file
that exports only the keys without associated values.```bash
#prefix ORGexport ORG_API_CLIENT_SECRET
export ORG_ANALYTICS_KEY
export ORG_BACKEND_KEY
export ORG_LOGGER_KEY
```## 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](https://nshipster.com/secrets/#universe-brain-client-secrecy-is-impossible).