secure-keys 1.1.6 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,140 +1,168 @@
1
- <div style="display: flex; gap: 10px; padding-bottom: 20px;">
2
- <img src="https://img.shields.io/badge/version-1.1.6-cyan" alt="SecureKeys version">
1
+ # Secure Key Generator for iOS Projects
3
2
 
3
+ <div style="display: flex; gap: 10px; padding-bottom: 20px;">
4
+ <img src="https://img.shields.io/badge/version-1.2.0-cyan" alt="SecureKeys version">
4
5
  <img src="https://img.shields.io/badge/iOS-^13.0-blue" alt="iOS version 13.0">
5
-
6
6
  <img src="https://img.shields.io/badge/Ruby-^3.3.6-red" alt="Ruby version 3.3.6">
7
-
8
7
  </div>
9
8
 
10
- # Secure Key Generator for iOS projects
11
-
12
- Utility to generate a `xcframework` for handling secure keys in iOS projects.
9
+ `secure-keys` is a Ruby CLI that generates a `SecureKeys.xcframework` for iOS apps. It reads secret values from macOS Keychain on local machines or environment variables in CI, encrypts those values with AES-256-GCM, writes a Swift API, builds an XCFramework, and optionally adds that framework to an Xcode target.
13
10
 
14
- ### Prerequisites
11
+ ## Requirements
15
12
 
16
- - Ruby 3.3.6 or higher
17
- - iOS 13.0 or higher
18
- - macOS 11.0 or higher
13
+ - macOS 11.0 or later
14
+ - Ruby 3.3 or later
15
+ - Xcode command line tools
16
+ - iOS 13.0 or later
19
17
 
20
- ### Installation
18
+ ## Installation
21
19
 
22
- You can install the `SecureKeys` utility using Homebrew using the following command:
20
+ Install with Homebrew:
23
21
 
24
22
  ```bash
25
23
  brew tap derian-cordoba/secure-keys
26
-
27
24
  brew install derian-cordoba/secure-keys/secure-keys
28
25
  ```
29
26
 
30
- For more details, you can visit the [homebrew-secure-keys](https://github.com/derian-cordoba/homebrew-secure-keys) repository.
31
-
32
- Another way, you can install the `SecureKeys` utility using `gem` command:
27
+ Install with RubyGems:
33
28
 
34
29
  ```bash
35
30
  gem install secure-keys
36
31
  ```
37
32
 
38
- If you using `bundler` you can add the `secure-keys` gem to the `Gemfile`:
33
+ Install with Bundler:
39
34
 
40
35
  ```ruby
41
36
  gem 'secure-keys'
42
37
  ```
43
38
 
44
- Then, you can install the gem using:
45
-
46
39
  ```bash
47
40
  bundle install
48
41
  ```
49
42
 
50
- For more information about the gem, you can visit the [secure-keys](https://rubygems.org/gems/secure-keys) page.
43
+ ## Quick Start
44
+
45
+ From an iOS project root:
46
+
47
+ ```bash
48
+ security add-generic-password -a "secure-keys" -s "secure-keys" -w "apiKey,githubToken"
49
+ security add-generic-password -a "secure-keys" -s "apiKey" -w "your-api-key"
50
+ security add-generic-password -a "secure-keys" -s "githubToken" -w "your-github-token"
51
+
52
+ secure-keys
53
+ ```
54
+
55
+ The command creates `.secure-keys/SecureKeys.xcframework`.
51
56
 
52
- ## Usage
57
+ Use the generated framework from Swift:
53
58
 
54
- 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.
59
+ ```swift
60
+ import SecureKeys
55
61
 
56
- The source is determined by the current platform **local or CI / cloud** using the `CI` environment variable.
62
+ let apiKey = SecureKey.apiKey.decryptedValue
63
+ let githubToken = key(for: .githubToken)
64
+ ```
57
65
 
58
- 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.
66
+ ## How Secret Generation Works
59
67
 
60
- You can configure your keys like this:
68
+ `secure-keys` does not create third-party API keys for providers such as GitHub, Firebase, Stripe, or AWS. Those secrets must be created in their owning service first.
61
69
 
62
- ### From Keychain
70
+ The tool generates an iOS framework that contains encrypted copies of the secret values you provide:
63
71
 
64
- 1. You need to define the `secure-keys` record in the Keychain with the key name and the key value.
72
+ 1. Resolve the secret source:
73
+ - Local runs use macOS Keychain unless CI mode is enabled.
74
+ - CI runs use environment variables.
75
+ 2. Read the configured list of secret names.
76
+ 3. Read each secret value by name.
77
+ 4. Generate a random AES-256-GCM key for this build.
78
+ 5. Encrypt each secret value.
79
+ 6. Write a Swift `SecureKey` enum with encrypted byte arrays.
80
+ 7. Build `.secure-keys/SecureKeys.xcframework`.
81
+ 8. Remove temporary Swift package files.
65
82
 
66
- The value for this key should be all the key names separated by a comma.
83
+ ## Local Configuration With Keychain
84
+
85
+ The default Keychain service and account identifier is `secure-keys`.
86
+
87
+ Store the list of secret names:
67
88
 
68
89
  ```bash
69
90
  security add-generic-password -a "secure-keys" -s "secure-keys" -w "githubToken,apiKey"
70
91
  ```
71
92
 
72
- If you want to use another keychain identifier, you can define an env variable named `SECURE_KEYS_IDENTIFIER` to set the keychain identifier.
93
+ Store each secret value under the same Keychain service:
94
+
95
+ ```bash
96
+ security add-generic-password -a "secure-keys" -s "githubToken" -w "your-github-token"
97
+ security add-generic-password -a "secure-keys" -s "apiKey" -w "your-api-key"
98
+ ```
99
+
100
+ Use a custom Keychain identifier:
73
101
 
74
102
  ```bash
75
- export SECURE_KEYS_IDENTIFIER="your-keychain-identifier"
103
+ export SECURE_KEYS_IDENTIFIER="my-app-secrets"
76
104
 
77
105
  security add-generic-password -a "$SECURE_KEYS_IDENTIFIER" -s "$SECURE_KEYS_IDENTIFIER" -w "githubToken,apiKey"
106
+ security add-generic-password -a "$SECURE_KEYS_IDENTIFIER" -s "githubToken" -w "your-github-token"
107
+ security add-generic-password -a "$SECURE_KEYS_IDENTIFIER" -s "apiKey" -w "your-api-key"
78
108
  ```
79
109
 
80
- 2. You can add new keys using the `security` command.
110
+ Use a custom delimiter:
81
111
 
82
112
  ```bash
83
- security add-generic-password -a "secure-keys" -s "apiKey" -w "your-api-key"
113
+ export SECURE_KEYS_DELIMITER="|"
114
+ security add-generic-password -a "secure-keys" -s "secure-keys" -w "githubToken|apiKey"
84
115
  ```
85
116
 
86
- Using custom keychain identifier:
117
+ ## CI Configuration With Environment Variables
118
+
119
+ CI mode is enabled automatically when common CI variables are present, including `CI=true` and `GITHUB_ACTIONS=true`. You can also force it:
87
120
 
88
121
  ```bash
89
- security add-generic-password -a "$SECURE_KEYS_IDENTIFIER" -s "apiKey" -w "your-api-key"
122
+ secure-keys --ci
90
123
  ```
91
124
 
92
- ### Environment variables
93
-
94
- 1. You can define the keys in the `.env` file or export the keys as environment variables.
125
+ Set the list of secret names in `SECURE_KEYS_IDENTIFIER`:
95
126
 
96
127
  ```bash
97
128
  export SECURE_KEYS_IDENTIFIER="github-token,api_key,firebaseToken"
129
+ ```
130
+
131
+ Set each secret value as an environment variable. Secret names are looked up exactly first, then normalized by converting `-` to `_` and uppercasing.
98
132
 
133
+ ```bash
99
134
  export GITHUB_TOKEN="your-github-token"
100
135
  export API_KEY="your-api-key"
101
136
  export FIREBASETOKEN="your-firebase-token"
102
137
  ```
103
138
 
104
- > The key names are formatted in uppercase and replace the `-` with `_`.
105
-
106
- > [!IMPORTANT]
107
- > If you want to use another demiliter, you can define an env variable named `SECURE_KEYS_DELIMITER` to set the delimiter.
139
+ The `SECURE_KEYS_` prefix is also supported for secret values:
108
140
 
109
141
  ```bash
110
- export SECURE_KEYS_DELIMITER="|"
111
-
112
- export SECURE_KEYS_IDENTIFIER="github-token|api_key|firebaseToken"
142
+ export SECURE_KEYS_API_KEY="your-api-key"
113
143
  ```
114
144
 
115
- ### Ruby script
116
-
117
- To generate the `SecureKeys.xcframework` use the `secure-keys` command in the iOS project root directory.
118
-
119
- Using global gem:
145
+ You can store the list in a dedicated environment variable instead:
120
146
 
121
147
  ```bash
122
- secure-keys
148
+ export CUSTOM_SECRET_LIST="github-token,api_key"
149
+ secure-keys --ci --identifier CUSTOM_SECRET_LIST
123
150
  ```
124
151
 
125
- Using bundler:
152
+ Use a custom delimiter in CI:
126
153
 
127
154
  ```bash
128
- bundle exec secure-keys
155
+ export SECURE_KEYS_DELIMITER="|"
156
+ export SECURE_KEYS_IDENTIFIER="github-token|api_key|firebaseToken"
129
157
  ```
130
158
 
131
- To get more information about the command, you can use the `--help` option.
159
+ ## CLI Reference
132
160
 
133
161
  ```bash
134
162
  secure-keys --help
163
+ ```
135
164
 
136
- # Output
137
-
165
+ ```text
138
166
  Usage: secure-keys [--options]
139
167
 
140
168
  -h, --help Use the provided commands to select the params
@@ -147,172 +175,356 @@ Usage: secure-keys [--options]
147
175
  --xcframework Add the xcframework to the target
148
176
  ```
149
177
 
150
- To avoid defining the `SECURE_KEYS_IDENTIFIER` and `SECURE_KEYS_DELIMITER` env variables, you can use the `--identifier` and `--delimiter` options.
178
+ Examples:
179
+
180
+ ```bash
181
+ secure-keys
182
+ secure-keys --verbose
183
+ secure-keys --ci --identifier CUSTOM_SECRET_LIST
184
+ secure-keys --identifier "my-app-secrets" --delimiter "|"
185
+ secure-keys -i "my-app-secrets" -d "|"
186
+ ```
187
+
188
+ ## Xcode Integration
189
+
190
+ Generate the framework only:
191
+
192
+ ```bash
193
+ secure-keys
194
+ ```
195
+
196
+ Generate and add the framework to an Xcode target:
151
197
 
152
198
  ```bash
153
- secure-keys --identifier "your-keychain-or-env-variable-identifier" --delimiter "|"
199
+ secure-keys --xcframework --target "YourTargetName" --add
200
+ ```
201
+
202
+ Replace an existing framework reference:
203
+
204
+ ```bash
205
+ secure-keys --xcframework --target "YourTargetName" --replace
154
206
  ```
155
207
 
156
- Also, you can use the short options:
208
+ Add an already generated framework without rebuilding:
157
209
 
158
210
  ```bash
159
- secure-keys -i "your-keychain-or-env-variable-identifier" -d "|"
211
+ secure-keys --no-generate --xcframework --target "YourTargetName"
160
212
  ```
161
213
 
162
- ### iOS project
214
+ Select a project explicitly:
215
+
216
+ ```bash
217
+ secure-keys --xcframework --target "YourTargetName" --xcodeproj "/path/to/YourProject.xcodeproj"
218
+ ```
163
219
 
164
- Within the iOS project, you can use the `SecureKeys` target dependency like:
220
+ The same options can be configured with environment variables:
221
+
222
+ ```bash
223
+ export SECURE_KEYS_XCFRAMEWORK_TARGET="YourTargetName"
224
+ export SECURE_KEYS_XCFRAMEWORK_ADD=true
225
+ export SECURE_KEYS_XCFRAMEWORK_REPLACE=false
226
+ export SECURE_KEYS_XCFRAMEWORK_XCODEPROJ="/path/to/YourProject.xcodeproj"
227
+
228
+ secure-keys --xcframework
229
+ ```
230
+
231
+ Short environment variable names are also supported:
232
+
233
+ ```bash
234
+ export XCFRAMEWORK_TARGET="YourTargetName"
235
+ export XCFRAMEWORK_ADD=true
236
+ export XCFRAMEWORK_REPLACE=false
237
+ export XCFRAMEWORK_XCODEPROJ="/path/to/YourProject.xcodeproj"
238
+ ```
239
+
240
+ ### Manual Xcode Setup
241
+
242
+ If you do not use `--xcframework`, add the framework manually:
243
+
244
+ 1. Open the Xcode project target.
245
+ 2. Open `General`.
246
+ 3. Add `.secure-keys/SecureKeys.xcframework` to `Frameworks, Libraries, and Embedded Content`.
247
+ 4. Open `Build Settings`.
248
+ 5. Add `$(SRCROOT)/.secure-keys` to `Framework Search Paths`.
249
+
250
+ ## Swift API
251
+
252
+ The generated framework exposes `SecureKey`, `key(for:)`, `key(_:)`, and a `String.secretKey` helper.
165
253
 
166
254
  ```swift
167
255
  import SecureKeys
168
256
 
169
- // Using key directly in the code
170
257
  let apiKey = SecureKey.apiKey.decryptedValue
258
+ let githubToken = key(for: .githubToken)
259
+ let sameGithubToken = key(.githubToken)
260
+ let keyFromString: SecureKey = "apiKey".secretKey
261
+ let valueFromString = "apiKey".secretKey.decryptedValue
262
+ let staticValue = String.key(for: .apiKey)
263
+ ```
171
264
 
172
- // Using key from `SecureKey` enum
173
- let someKey: String = key(for: .someKey)
265
+ Generated key names are camelized for Swift enum cases:
174
266
 
175
- // Alternative way to use key from `SecureKey` enum
176
- let someKey: String = key(.someKey)
267
+ ```text
268
+ api-key -> SecureKey.apiKey
269
+ githubToken -> SecureKey.githubToken
270
+ ```
177
271
 
178
- // Using raw value from `SecureKey` enum
179
- let apiKey: SecureKey = "apiKey".secretKey
272
+ ## Output Files
180
273
 
181
- // Using raw value from `SecureKey` enum with decrypted value
182
- let apiKey: String = "apiKey".secretKey.decryptedValue
274
+ The main output is:
183
275
 
184
- // Using `key` method to get the key
185
- let apiKey: String = .key(for: .apiKey)
276
+ ```text
277
+ .secure-keys/SecureKeys.xcframework
186
278
  ```
187
279
 
188
- ## How to install the `SecureKeys.xcframework` in the iOS project
280
+ Temporary Swift package and build files are created under `.secure-keys` during generation and removed after the framework is built.
281
+
282
+ ## Security Notes
283
+
284
+ - Do not commit `.secure-keys/SecureKeys.xcframework` unless your release process intentionally requires it.
285
+ - Do not commit `.env` files or raw secret values.
286
+ - Treat app-bundled secrets as obfuscation, not as a perfect security boundary. A determined attacker can inspect a shipped app binary.
287
+ - Prefer server-side secret usage for highly sensitive credentials.
288
+ - Use environment-specific keys for development, staging, and production.
289
+ - Rotate keys regularly and revoke leaked credentials immediately.
290
+
291
+ ## Secret Scanning and Validation
292
+
293
+ `secure-keys` ships both a CLI and a Ruby API for validating individual secret values and scanning source files or git diffs for accidentally exposed credentials.
189
294
 
190
- ### Automatically
295
+ ### CLI
191
296
 
192
- > [!IMPORTANT]
193
- > You can see more information about the command using the `--help` option.
297
+ Scan the current directory:
194
298
 
195
299
  ```bash
196
- secure-keys --xcframework --help
300
+ secure-keys validate scan
301
+ ```
197
302
 
198
- # Output
199
- Usage: secure-keys --xcframework [--options]
303
+ Scan a specific path:
200
304
 
201
- -h, --help Use the provided commands to select the params
202
- --[no-]add Add the SecureKeys XCFramework to the Xcode project (default: true)
203
- -t, --target TARGET The target to add the xcframework
204
- -r, --replace Replace the existing xcframework in the Xcode project (default: false)
205
- -x, --xcodeproj XCODEPROJ The Xcode project path (default: the first found Xcode project)
305
+ ```bash
306
+ secure-keys validate scan ./src
206
307
  ```
207
308
 
208
- From the `secure-keys` command, you can use the `--xcframework` option to add the `SecureKeys.xcframework` to the iOS project.
309
+ Scan only staged git changes (useful as a pre-commit hook):
209
310
 
210
311
  ```bash
211
- secure-keys --xcframework --target "YourTargetName" --add
312
+ secure-keys validate scan --staged
212
313
  ```
213
314
 
214
- If you want to add the `SecureKeys.xcframework` to an iOS that already contains the `SecureKeys` source code, you can use the `--replace` option.
315
+ Save the report as JSON:
215
316
 
216
317
  ```bash
217
- secure-keys --xcframework --target "YourTargetName" --replace
318
+ secure-keys validate scan --output report.json
218
319
  ```
219
320
 
220
- > [!IMPORTANT]
221
- > If you don't need to generate the `SecureKeys.xcframework` every time, you can use the `--no-generate` option.
321
+ Override the file extensions and exclusions:
222
322
 
223
323
  ```bash
224
- secure-keys --no-generate --xcframework --target "YourTargetName"
324
+ secure-keys validate scan --extensions .rb,.swift,.go --excludes vendor,tmp,build
225
325
  ```
226
326
 
227
- Also, you can specify your Xcode project path using the `--xcodeproj` option.
327
+ Enable verbose output:
228
328
 
229
329
  ```bash
230
- secure-keys --xcframework --target "YourTargetName" --xcodeproj "/path/to/your/project.xcodeproj"
330
+ secure-keys validate scan --verbose
231
331
  ```
232
332
 
233
- > [!IMPORTANT]
234
- > By default, the xcodeproj path would be the first found Xcode project.
333
+ Full option reference:
235
334
 
236
- If you don't want to use the CLI options, you can configure some env variable to interact with the `secure-keys` command.
335
+ ```text
336
+ Usage: secure-keys validate scan [path] [--options]
237
337
 
238
- ```bash
239
- # e.g (Large version)
240
- export SECURE_KEYS_XCFRAMEWORK_TARGET="YourTargetName"
241
- export SECURE_KEYS_XCFRAMEWORK_ADD=true
242
- export SECURE_KEYS_XCFRAMEWORK_REPLACE=true
243
- export SECURE_KEYS_XCFRAMEWORK_XCODEPROJ="/path/to/your/project.xcodeproj"
338
+ -h, --help Show help for the scan subcommand
339
+ --staged Scan staged git changes instead of a directory (default: false)
340
+ -o, --output FILE Save the scan report as JSON to FILE
341
+ --extensions Comma-separated file extensions to scan (e.g. .rb,.swift)
342
+ --excludes Comma-separated directory names to exclude from the scan
343
+ --verbose Enable verbose output (default: false)
344
+ ```
244
345
 
245
- # e.g (Short version)
246
- export XCFRAMEWORK_TARGET="YourTargetName"
247
- export XCFRAMEWORK_ADD=true
248
- export XCFRAMEWORK_REPLACE=true
249
- export XCFRAMEWORK_XCODEPROJ="/path/to/your/project.xcodeproj"
346
+ Exit codes:
250
347
 
251
- # Run the command
252
- secure-keys --xcframework
348
+ | Code | Meaning |
349
+ |---|---|
350
+ | `0` | Scan completed with no findings |
351
+ | `1` | One or more secrets were detected |
352
+
353
+ ### Validating a Secret
354
+
355
+ `SecureKeys::Validation::Validator` checks a single value against a set of security rules and returns a `ValidationResult`.
356
+
357
+ ```ruby
358
+ require 'validation/validator'
359
+
360
+ validator = SecureKeys::Validation::Validator.new
361
+ result = validator.validate(key: :api_key, value: ENV['API_KEY'])
362
+
363
+ puts result.summary # ✅ api_key — no issues / ❌ api_key — 2 issue(s)
364
+ puts result.valid? # true / false
365
+ puts result.severity_level # :ok | :warning | :error | :critical
366
+ result.print # formatted report to stdout
367
+ ```
368
+
369
+ Available validation options:
370
+
371
+ | Option | Type | Default | Description |
372
+ |---|---|---|---|
373
+ | `check_entropy` | Boolean | `false` | Flag low-entropy (repetitive) values |
374
+ | `allow_production` | Boolean | `false` | Skip the production-key warning |
375
+ | `warn_on_pattern` | Boolean | `false` | Emit an informational notice when a pattern matches |
376
+
377
+ ```ruby
378
+ result = validator.validate(
379
+ key: :stripe_key,
380
+ value: ENV['STRIPE_KEY'],
381
+ options: { check_entropy: true, warn_on_pattern: true }
382
+ )
383
+ ```
384
+
385
+ Detect the type of a secret value:
386
+
387
+ ```ruby
388
+ info = validator.detect_type(value: 'ghp_abc...')
389
+ # => { type: :github_token, description: "GitHub Personal Access Token", severity: :high, ... }
390
+ ```
391
+
392
+ Get provider-specific security recommendations:
393
+
394
+ ```ruby
395
+ validator.recommendations(key: :githubToken)
396
+ # => ["Use GitHub Personal Access Tokens with minimal required scopes", ...]
397
+ ```
398
+
399
+ ### Scanning Files for Exposed Secrets
400
+
401
+ `SecureKeys::Validation::Scanner` scans source files or git diffs for credentials that match any of the 25+ built-in patterns.
402
+
403
+ Scan a directory:
404
+
405
+ ```ruby
406
+ require 'validation/scanner'
407
+
408
+ scanner = SecureKeys::Validation::Scanner.new
409
+ result = scanner.scan_directory(path: '.')
410
+
411
+ puts result.clean? # true if no findings
412
+ puts result.files_count # number of files scanned
413
+
414
+ result.findings.each { |f| puts f.to_s }
415
+ result.print if !result.clean?
416
+ ```
417
+
418
+ Scan only staged git changes (useful in a pre-commit hook):
419
+
420
+ ```ruby
421
+ result = scanner.scan_git_diff # staged only (default)
422
+ result = scanner.scan_git_diff(staged_only: false) # staged + unstaged
423
+ ```
424
+
425
+ Customize the scan at initialization or per call:
426
+
427
+ ```ruby
428
+ scanner = SecureKeys::Validation::Scanner.new(
429
+ options: {
430
+ extensions: ['.rb', '.swift', '.go'],
431
+ excludes: ['vendor', 'node_modules', '.git'],
432
+ max_depth: 5
433
+ }
434
+ )
253
435
  ```
254
436
 
255
- ### Manually
437
+ Filter findings by severity:
438
+
439
+ ```ruby
440
+ result.by_severity(severity: :critical).each { |f| puts f.to_s }
441
+ ```
256
442
 
257
- 1. From the iOS project, click on the project target, select the `General` tab, and scroll down to the `Frameworks, Libraries, and Embedded Content` section.
443
+ ### Detected Patterns
258
444
 
259
- ![Project Target](/docs/assets/add-xcframework-to-ios-project/first-step.png)
445
+ The scanner recognizes the following secret types out of the box:
260
446
 
261
- 2. Click on the `Add Other...` button and click on the `Add Files...` option.
447
+ | Pattern | Severity |
448
+ |---|---|
449
+ | GitHub personal / OAuth / App / refresh token | high |
450
+ | AWS access key ID | critical |
451
+ | AWS secret access key | critical |
452
+ | Google Cloud API key | high |
453
+ | Google OAuth token | high |
454
+ | Stripe secret key (live / test) | critical |
455
+ | Stripe publishable / restricted key | medium / high |
456
+ | Slack bot / app / webhook token | high / medium |
457
+ | JWT token | medium |
458
+ | PEM / RSA / EC / OpenSSH private key | critical |
459
+ | Generic API key assignment | medium |
460
+ | Generic secret / password assignment | medium |
461
+ | Firebase API key | medium |
462
+ | Twilio API key / Account SID | high / low |
463
+ | SendGrid API key | high |
464
+ | Mailchimp API key | medium |
465
+ | Square access token | high |
466
+ | PayPal Braintree access token | critical |
467
+ | Heroku API key | high |
468
+ | Base64-encoded secret | low |
469
+ | Suspicious assignment (catch-all) | low |
262
470
 
263
- ![Add Files](/docs/assets/add-xcframework-to-ios-project/second-step.png)
471
+ ### Validation Configuration
264
472
 
265
- 3. Navigate to the `keys` directory and select the `SecureKeys.xcframework` folder.
473
+ All thresholds can be overridden with environment variables. Both the bare name and the `SECURE_KEYS_` prefix are supported.
266
474
 
267
- ![Select SecureKeys.xcframework](/docs/assets/add-xcframework-to-ios-project/third-step.png)
475
+ | Environment variable | Default | Description |
476
+ |---|---|---|
477
+ | `SECURE_KEYS_API_KEY_LENGTH` | `20` | Minimum API key length |
478
+ | `SECURE_KEYS_TOKEN_LENGTH` | `20` | Minimum token length |
479
+ | `SECURE_KEYS_SECRET_LENGTH` | `16` | Minimum secret length |
480
+ | `SECURE_KEYS_PASSWORD_LENGTH` | `12` | Minimum password length |
481
+ | `SECURE_KEYS_KEY_LENGTH` | `16` | Minimum generic key length |
482
+ | `SECURE_KEYS_SCAN_EXTENSIONS` | `.swift,.rb,.py,.js,...` | Comma-separated file extensions to scan |
483
+ | `SECURE_KEYS_SCAN_EXCLUDES` | `.git,node_modules,Pods,...` | Comma-separated names to exclude |
484
+ | `SECURE_KEYS_MAX_SCAN_DEPTH` | `10` | Maximum directory traversal depth |
485
+ | `SECURE_KEYS_MIN_ENTROPY_THRESHOLD` | `3.0` | Shannon entropy threshold for `check_entropy` |
268
486
 
269
- > Now the `SecureKeys.xcframework` is added to the iOS project.
487
+ ## Troubleshooting
270
488
 
271
- ![Select SecureKeys.xcframework](/docs/assets/add-xcframework-to-ios-project/third-step-result.png)
489
+ `Error fetching the key from Keychain`
272
490
 
273
- 4. Click on the `Build settings` tab and search for the `Search Paths` section.
491
+ Verify the Keychain service, account, and identifier values. For the default configuration, the list must be stored with account `secure-keys` and service `secure-keys`.
274
492
 
275
- ![Search Paths](/docs/assets/add-xcframework-to-ios-project/fourth-step.png)
493
+ `Error fetching the key from ENV variables`
276
494
 
277
- > Add the path to the `SecureKeys.xcframework` in the `Framework Search Paths` section.
495
+ Verify CI mode is enabled and that each configured key has a matching environment variable. For example, `github-token` maps to `GITHUB_TOKEN`.
496
+
497
+ `xcodebuild` fails
498
+
499
+ Verify Xcode command line tools are installed and selected:
278
500
 
279
501
  ```bash
280
- $(inherited)
281
- $(SRCROOT)/.secure-keys
502
+ xcode-select -p
282
503
  ```
283
504
 
284
- ## How it works
505
+ `SecureKeys.xcframework` is not found by Xcode
285
506
 
286
- The process when the script is executed is:
507
+ Verify `$(SRCROOT)/.secure-keys` is present in `Framework Search Paths` and that the framework is attached to the correct target.
287
508
 
288
- 1. Create a `.secure-keys` directory.
289
- 2. Create a temporary `Swift Package` in the `.secure-keys` directory.
290
- 3. Copy the `SecureKeys` source code to the temporary `Swift Package`.
509
+ ## Development
291
510
 
292
- ```swift
293
- public enum SecureKey {
511
+ Install dependencies:
294
512
 
295
- // MARK: - Cases
513
+ ```bash
514
+ bundle install
515
+ ```
296
516
 
297
- case apiKey
298
- case someKey
299
- case unknown
517
+ Run the test suite:
300
518
 
301
- // MARK: - Properties
519
+ ```bash
520
+ bundle exec rspec
521
+ ```
302
522
 
303
- /// The decrypted value of the key
304
- public var decryptedValue: String {
305
- switch self {
306
- case .apiKey: [1, 2, 4].decrypt(key: [248, 53, 26], iv: [148, 55, 47], tag: [119, 81])
307
- case .someKey: [1, 2, 4].decrypt(key: [248, 53, 26], iv: [148, 55, 47], tag: [119, 81])
308
- case .unknown: fatalError("Unknown key \(rawValue)")
309
- }
310
- }
311
- }
312
- ```
523
+ Run the local CLI:
313
524
 
314
- 4. Generate the `SecureKeys.xcframework` using the temporary `Swift Package`.
315
- 5. Remove the temporary `Swift Package`.
525
+ ```bash
526
+ bundle exec ./bin/secure-keys --help
527
+ ```
316
528
 
317
529
  ## License
318
530