{"id":13750726,"url":"https://github.com/vdka/SecretsManager","last_synced_at":"2025-05-09T16:31:42.183Z","repository":{"id":63921216,"uuid":"543933805","full_name":"vdka/SecretsManager","owner":"vdka","description":"A Swift Package to generate and use encrypted secrets in your app","archived":false,"fork":false,"pushed_at":"2024-04-04T00:55:54.000Z","size":9,"stargazers_count":28,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-07T15:03:17.577Z","etag":null,"topics":["plugin","secret-management","secrets","secrets-management","secrets-manager","swift","swift-package-manager","swift-package-manager-plugin","swift-package-plugin"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vdka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-01T07:29:29.000Z","updated_at":"2024-10-06T09:25:19.000Z","dependencies_parsed_at":"2024-04-04T01:47:30.545Z","dependency_job_id":"77c5d816-0434-47ac-b5fc-40b561d697c7","html_url":"https://github.com/vdka/SecretsManager","commit_stats":{"total_commits":5,"total_committers":1,"mean_commits":5.0,"dds":0.0,"last_synced_commit":"7e7eb0304726a2d9788432a3b90d79817ce2f6e1"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdka%2FSecretsManager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdka%2FSecretsManager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdka%2FSecretsManager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdka%2FSecretsManager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vdka","download_url":"https://codeload.github.com/vdka/SecretsManager/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224869043,"owners_count":17383308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["plugin","secret-management","secrets","secrets-management","secrets-manager","swift","swift-package-manager","swift-package-manager-plugin","swift-package-plugin"],"created_at":"2024-08-03T08:00:45.230Z","updated_at":"2024-11-16T02:31:32.186Z","avatar_url":"https://github.com/vdka.png","language":"Swift","funding_links":[],"categories":["Frameworks with plugins"],"sub_categories":[],"readme":"# SecretsManager\n\nEffortless Secrets Management for Swift projects using Code Generation.\nA simpler approach than using GYB files as outlined by the [NSHipster article](https://nshipster.com/secrets/#cosmic-brain-obfuscate-secrets-using-code-generation) \non Secret Management on iOS using Swift Build Tool Plugin (Swift 5.6+).\n\n## Features\n\n- Provides a convenient way to keep secrets out of source code\n- Encrypts Secrets when they are at rest in your applications binary\n- Provides convenient access through global `Secrets`\n- Run as manual Script, SPM plugin or Xcode plugin\n- Less than 250 lines of Swift\n\n## Usage\n\nUse a `.env` bash script to export Secrets you want available to your source code.\n\n```bash\n#prefix ORG\n\nexport ORG_API_CLIENT_SECRET=hrFL6LpsGQPsEQdipfTSlosI6topYTfhLNCfIvbfUz5r6nc72DMRbLL3msjuAFnY\nexport ORG_ANALYTICS_KEY=dak37Qv5KGwNsQxVJxjJY2OtbUnGKXlm3mkDApSRfrAsTHQdFRSEfrA9yin5T4YT\nexport ORG_BACKEND_KEY='KwphtrRhgOXcRd=p!73QnrQLuOj=rx8edJhMy52sWeQPKMxOxA8hNcDrG9=XRvAw'\nexport ORG_LOGGER_KEY='oW7YQKg2eNcVjzRdmCtmgCCSBp2dpJlL5NC-Pj!asS5XdPG/--R2hE?/=I/TlotP'\n```\n\nUsing this plugin the following Swift code is generated and available directly to your  targets \nsource code, no need for an import.\n\n```swift\n// This file is automatically generated\n\nimport struct Foundation.Data\n\nprivate func secret(_ secret: String) -\u003e String {\n    let data = Data(base64Encoded: secret)\n    guard let data else {\n        fatalError(\"Failed to decode a secret!\")\n    }\n\n    func decrypt(_ data: Data) -\u003e String {\n        let key = Data(base64Encoded: \"JbiOFqC+jH3l8pwCLE4Nca4f19M7YAbeTUo7rhnSSG7ctZMlc+dg5FI9o3zrSbCgFLtDd0uC9EcCC+jd6hlVDA==\")!\n        var output: [UTF8.CodeUnit] = []\n        for (offset, ch) in data.enumerated() {\n            output.append(ch ^ key[offset % key.count])\n        }\n        return String(bytes: output, encoding: .utf8)!\n    }\n\n    return decrypt(data)\n}\n\nenum Secrets {\n    static let apiClientSecret = secret(\"TcrIWpby/A6io8xxaR9pGN55g4BXD3WXez5U3kCGLgaQ+9BDOpECggdHlg7dJ9OXJv8OJSnOuHRveIKoq187VQ==\")\n    static let analyticsKey = secret(\"QdnlJZfv+kiutetMXx91J+RnvZliUkmqLx9V6VKKJAPv2PhhMpcztjRP4g+/AeHEUukQMi3wtX57Yobovi0MWA==\")\n    static let backendKey = secret(\"bs/+ftTM3hWCvcRhfiowAY8o5IJVEleSOAVRk2uqcAu4//toCtJSlwVY8iygBMjvbPp7HwXhsDVFMtWFuG8Uew==\")\n    static let loggerKey = secret(\"Su+5T/H160+AvP9URjRfFcNco75cI0WNDzoJymmYJCLp+9AII41BhSFuliSPGfePOZYRRSPHy2g/QseJhnYhXA==\")\n}\n```\n\n## Setup\n\n\u003e Requires Swift 5.6 (Xcode 13.3+)\n\nCreate a `.env` file in your root directory (alongside `Package.swift` or your `*.xcodeproj`). \nYou can define a prefix to strip from all your exported keys with `#prefix`. See [Usage](#usage) \nfor an example `.env` file.\n\n### Xcode Projects\n\u003e [Visual Guide](https://github.com/vdka/SecretsManager/wiki/Xcode-Integration)\n\n1. Add SecretsManager package\n    - When prompted to **Choose Package Products for SecretsManager** don't select any products\n2. In **Targets \u003e Build Phases** add `SecretsManagerPlugin` to **Run Build Tool Plug-ins**\n3. Build, triggering a prompt to trust the plugin\n    - From the issue navigator you can goto the plugin and read the source code before trusting\n\n### Swift Package Manager\n\nAdd the following to your `Package.swift` files dependencies array:\n```swift\n.package(url: \"https://github.com/vdka/SecretsManager.git\", from: \"1.0.0\"),\n```\n\nAnd to the targets Secrets should be available to, after their `dependencies`: \n```swift\nplugins: [\n    .plugin(name: \"SecretsManagerPlugin\", package: \"SecretsManager\"),\n]\n```\n\n### Xcode Cloud\n\nWhen running in Xcode cloud you will want the secret values to come from the actual environment. In \norder to tell the plugin which keys to read from the environment from you can create a `.env` file \nthat exports only the keys without associated values.\n\n```bash\n#prefix ORG\n\nexport ORG_API_CLIENT_SECRET\nexport ORG_ANALYTICS_KEY\nexport ORG_BACKEND_KEY\nexport ORG_LOGGER_KEY\n```\n\n## Security\n\nThis package doesn't aim to keep your Secrets safe from intentional attacks. It's aim is to make it\nconvenient to adopt best practice Secrets Management in Swift projects. It does this by ensuring \nkeeping your secrets out of your Source Code doesn't sacrifice usability, and that when  compiled \ninto your application, they are not stored in plaintext. Remember\n[Client Secrecy is Impossible](https://nshipster.com/secrets/#universe-brain-client-secrecy-is-impossible).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdka%2FSecretsManager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvdka%2FSecretsManager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdka%2FSecretsManager/lists"}