keeper_secrets_manager 17.1.0 → 17.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a75902de495889b3464731f65dc951d778b7b6cde7be9efd6360fde92da3d7e1
4
- data.tar.gz: 0e181c7f3bb27e2e43c57bfaf6690ddd3f0b2ecc7791fb9b62d900c3392ba865
3
+ metadata.gz: a4bd6d345590ff9f958814a482c10cb18dff351be76d9068f477183baf707d2e
4
+ data.tar.gz: 452a1bfcf84c267a3e9e6b5eee53f791ea14a2ad276f2fc2ba8b42a763f48e3b
5
5
  SHA512:
6
- metadata.gz: 35d50e5905926f05914d111465835dbe7996dc1c2de12480b092f9acc0569faab6140bce76811c2c085c5b4ea8875dff5d5f196555de95bd3dafc8c578dba606
7
- data.tar.gz: 5425415543c572dcc55029c83c2d37c17d471df72da10da1f4da32bed3661c74f3778e50db91bedad4d76a480c82eb8e2dfd0ef3cc4e249b6d1682c3f68dcfce
6
+ metadata.gz: 772bfaed3f3376b4e5aad8214fc99685c6168a92391865b83faac03a69d4e44bfd26d7a03d2052cc251fa2b70f1fb0e72a313e250678ddb6ba539dd666b3dfa2
7
+ data.tar.gz: ddf197159f9d56b79ad8eecf7ae74f2ccc8ccfb5642cc8f4d9dff57046a2f6c753f7cc8bd0e48d659819251fe89852573791aa69894a4bb0741a2dc6ce86fe59
data/CHANGELOG.md CHANGED
@@ -1,16 +1,79 @@
1
1
  # Changelog
2
2
 
3
- ## [Unreleased]
3
+ ## [17.2.0]
4
4
 
5
5
  ### Fixed
6
- - `update_secret` now correctly encrypts record data before sending to server
7
- - `update_secret` now calls `finalize_secret_update` endpoint to persist changes
8
- - Local record's revision number is automatically refreshed after successful update
9
- - Consecutive updates on the same record object now work without manual refetching
10
- - `download_file` now properly respects SSL certificate verification settings and disables CRL checking
11
- - `upload_file` now uses correct `add_file` endpoint and includes required `ownerRecordRevision` in payload
12
- - `create_folder` now properly encrypts folder key with AES-CBC and sets correct parent_uid (nil for root-level folders)
13
- - Fixed AES-CBC encryption to not double-pad data (OpenSSL handles padding automatically)
6
+ - **KSM-1095**: `update_secret` now calls `complete_transaction` after staging the update, so changes are committed to the server rather than remaining in a staged state indefinitely; works for both `KeeperRecord` objects and plain hash inputs
7
+ - **KSM-1094**: `update_secret` no longer raises `NameError: undefined local variable 'record_uid'` when called with a `KeeperRecord` object; the revision refresh now correctly references `record.uid`
8
+ - **KSM-1096**: `download_thumbnail` no longer raises `NoMethodError` when passed a `KeeperFile` object; `KeeperFile` now exposes a `file_key` attribute and the method dispatches on type before attempting hash access
9
+ - **KSM-824**: `to_h` now always includes `custom` in the V3 API payload, even when the array is empty, matching Commander and Vault behavior
10
+ - **KSM-906**: Added IL5 region mapping (`IL5` `il5.keepersecurity.us`) to `KEEPER_SERVERS`
11
+ - **KSM-987**: `url_safe_str_to_bytes` and `base64_to_bytes` in `Utils` now raise `Error` when passed `nil`; all Base64 decoding in `core.rb` routes through `Utils`
12
+ - **KSM-1090**: `base64` and `logger` are now declared as explicit runtime dependencies in the gemspec; Ruby 4.0 removed these from the default standard library, so any clean install on Ruby 4.0+ previously raised `LoadError` on `require 'keeper_secrets_manager'`. Also removed a dead `require 'ostruct'` from `dto.rb`.
13
+ - **KSM-1070**: Fixed silent AES-CBC fallback in `decrypt_aes_gcm`: an AES-GCM authentication-tag failure now raises `DecryptionError` immediately rather than retrying decryption as AES-CBC; tampered or wrong-key ciphertext previously could produce output without any error.
14
+ - **KSM-685**: `CreateOptions.subfolder_uid` parameter is now correctly sent to the API when creating records
15
+ - **KSM-686**: Disaster recovery caching with `CachingPostFunction` is now implemented to match other SDKs; API response caching works for both `get_secret` and `get_folders` endpoints, and unused `@cache` and `@cache_expiry` instance variables are removed from `SecretsManager`
16
+ - **KSM-696**: Config storage file is now written with `0600` permissions (owner read/write only), preventing other local users from reading stored credentials
17
+ - **KSM-734**: Fixed notation lookup to deduplicate record shortcuts via `uniq { |r| r.uid }` before the ambiguity check; preserves genuine duplicate-title detection while preventing false ambiguity errors when both an original record and its shortcut are in scope
18
+ - **KSM-1088**: `delete_secret` and `delete_folder` now log an error for each record/folder whose `responseCode` is not `"ok"`, surfacing partial-failure details that were previously silently discarded
19
+ - **KSM-1091**: Invalid `proxy_url` now raises `ArgumentError` at initialization with a descriptive message; a URL with no host previously silently bypassed the proxy, and a fully malformed URL raised `NetworkError` at request time instead
20
+ - **KSM-1098**: `get_value`, `get_totp_code`, and `download_file` in `notation_enhancements` no longer raise `NoMethodError` when passed `nil`, an empty string, or a non-String value; `parse` itself now checks `is_a?(String)` before `empty?` to avoid `NoMethodError` for non-String inputs. `notation_enhancements` is now properly required from the main entry point.
21
+ - Fixed example files to use correct SDK APIs: `09_totp.rb` corrects `Totp` to `TOTP` and `generate()` to `generate_code()`; `01_quick_start.rb` uses the `secret.login` dynamic getter instead of hash access; `10_custom_caching.rb` uses `Utils.bytes_to_base64`
22
+ - Fixed badly anchored regular expression in `test/integration/test_totp.rb` that could cause false positives in test validation
23
+
24
+ ### Added
25
+ - **KSM-906**: `SecretsManager` now accepts the 4-part IL5 one-time token `IL5:clientKey:serverPublicKeyId:serverPublicKey`, registering the supplied EC P-256 server public key (keyId 20, outside the built-in 1–18 table) for ECIES transmission-key wrapping, and persists it as `serverPublicKey` in config so it survives restarts. Adds `server_public_key` / `server_public_key_id` constructor options (precedence: programmatic > token > config), a new `ConfigKeys::KEY_SERVER_PUBLIC_KEY`, malformed-OTT validation, and an actionable error when the backend rejects a configured custom key. Non-IL5 tokens are unchanged.
26
+ - **KSM-1013**: `KeeperRecordLink` (via `KeeperRecord#get_links`) wraps each raw `links` entry with never-raising typed accessors: permission booleans with an `allowedSettings` fallback (top-level wins), AES-256-GCM `get_decrypted_data`/`get_link_data`, and `meta`/`ai_settings`/`jit_settings` settings accessors. Adds a `request_links:` keyword to `get_secrets`. Purely additive; the raw `record.links` list is unchanged.
27
+ - **KSM-883**: On HTTP 403 `{"error":"throttled"}`, `post_query` now retries up to 5 times with exponentially increasing delays (11s, 22s, 44s, 88s, 176s) plus 0–25% jitter (one-sided), honoring `retry_after` from the response when present, and raises `ThrottledError` once retries are exhausted. Replaces the previous fixed 60-second sleep with no backoff, jitter, or retry cap.
28
+ - **KSM-1102**: Added `save(record, transaction_type: nil, links_to_remove: nil)` and `save_with_options(record, update_options)`: non-finalizing update aliases that use the stored record key without re-fetching and do not call `complete_transaction`
29
+ - **KSM-1101**: Added `inflate_field_value(uids, replace_fields)` and `get_inflate_ref_types(field_type)` for field-reference resolution; `addressRef` resolves to address fields, `cardRef` resolves to paymentCard/text/pinCode/address fields with recursive inflate
30
+ - **KSM-1100**: Added `get_notation_results` and `try_get_notation_results`: list-returning notation lookup that always returns `Array[String]`, returns all field values by default (no first-element shortcut), and JSON-serializes complex values
31
+ - **KSM-1099**: Added `create_secret_with_options(create_options, record_data, folders: nil)`: explicit options-based creation that accepts a pre-fetched folders list to avoid an extra `get_folders` network call; `create_secret` is unchanged
32
+ - **KSM-743**: Added transmission public key #18 for Gov Cloud Dev environment support
33
+ - **KSM-687**: Added DTO fields and PAM transaction support for complete SDK parity:
34
+ - `links` field to `KeeperRecord` for linked records support
35
+ - `is_editable` field to `KeeperRecord` to check edit permissions
36
+ - `inner_folder_uid` field to `KeeperRecord` for folder location tracking
37
+ - `thumbnail_url` and `last_modified` fields to `KeeperFile`
38
+ - `UpdateOptions` class with `transaction_type` and `links_to_remove` support
39
+ - `update_secret_with_options` method to support removing file links
40
+ - `request_links` option to `QueryOptions` for fetching linked records
41
+ - `download_thumbnail` method for downloading file thumbnails
42
+ - `expires_on` field to `SecretsManagerResponse`
43
+ - `complete_transaction(record_uid, rollback: false)` method for PAM rotation workflows
44
+ - `CompleteTransactionPayload` DTO class for transaction completion
45
+ - **KSM-692**: HTTP proxy support for enterprise environments:
46
+ - `proxy_url` initialization parameter for explicit proxy configuration
47
+ - `HTTPS_PROXY` / `https_proxy` environment variable support (automatic detection)
48
+ - Authenticated proxy support (username:password in URL)
49
+ - Proxy applies to all HTTP operations (API calls, file downloads, file uploads)
50
+ - **KSM-694**: Convenience methods for improved developer experience:
51
+ - `upload_file_from_path(owner_record_uid, file_path, file_title: nil)`: upload files directly from disk
52
+ - `try_get_notation(notation_uri)`: error-safe notation access (returns empty array on error)
53
+ - `KeeperSecretsManager.from_config(config_base64, options = {})`: convenience method for initializing from a base64 config string; complements `from_token()` and `from_file()` and provides parity with the .NET SDK's `GetVaultConfigFromConfigString()` pattern
54
+ - `KeeperSecretsManager::CachingPostFunction`: built-in disaster recovery caching
55
+ - `KeeperSecretsManager::Cache`: file-based cache management (save, load, clear); location configurable via `KSM_CACHE_DIR` environment variable
56
+ - Development console script (`bin/console`) for interactive SDK exploration using Pry REPL
57
+
58
+ ### Changed
59
+ - Documentation: Added Ruby SDK to root repository SDK comparison table
60
+ - **Test Coverage:**
61
+ - Added 5 new integration test files (test_pam_rotation.rb, test_proxy.rb, test_pam_linked_records.rb, test_caching.rb)
62
+ - Added 17 unit tests for caching functionality and 27 for new features (CompleteTransactionPayload, QueryOptions, proxy configuration, convenience methods)
63
+ - Enhanced test_file_operations.rb with thumbnail download and file link removal tests
64
+ - **Mock Infrastructure:** Implemented proper AES-256-GCM encryption in `mock_helper.rb`:
65
+ - Records now use proper AES-GCM encryption (was Base64 only)
66
+ - Folders use correct AES-CBC encryption for data
67
+ - Added transmission key encryption/decryption
68
+ - Added mock endpoints for transaction completion (finalize_secret_update, rollback_secret_update)
69
+ - Enabled complete offline testing without config.base64
70
+ - **Example Files:**
71
+ - Added `11_pam_linked_records.rb`: PAM resources with linked credentials and transaction workflow
72
+ - Added `12_proxy_usage.rb`: HTTP proxy configuration examples
73
+ - Updated `06_files.rb`: added `upload_file_from_path` convenience method example
74
+ - Updated `08_notation.rb`: added `try_get_notation` error-safe notation example
75
+ - Removed emojis from all example files for professional appearance
76
+ - **Dependencies:** Added base32 gem to test dependencies for TOTP support
14
77
 
15
78
  ## [17.1.0] - 2025-01-06
16
79
 
@@ -22,6 +85,14 @@
22
85
  - ECC key generation now correctly returns 32-byte raw private keys (was returning 121-byte DER format)
23
86
  - Client version now dynamically uses VERSION constant instead of hardcoded value
24
87
  - Fixed Tests
88
+ - `update_secret` now correctly encrypts record data before sending to server
89
+ - `update_secret` now calls `finalize_secret_update` endpoint to persist changes
90
+ - Local record's revision number is automatically refreshed after successful update
91
+ - Consecutive updates on the same record object now work without manual refetching
92
+ - `download_file` now properly respects SSL certificate verification settings and disables CRL checking
93
+ - `upload_file` now uses correct `add_file` endpoint and includes required `ownerRecordRevision` in payload
94
+ - `create_folder` now properly encrypts folder key with AES-CBC and sets correct parent_uid (nil for root-level folders)
95
+ - Fixed AES-CBC encryption to not double-pad data (OpenSSL handles padding automatically)
25
96
 
26
97
  ## [17.0.4] - 2025-10-20
27
98
 
@@ -57,4 +128,6 @@
57
128
 
58
129
  ### Notes
59
130
  - Version 17.0.0 to align with other Keeper SDKs
60
- - No runtime dependencies (base32 is optional)
131
+ - No runtime dependencies (base32 is optional)
132
+
133
+ [17.2.0]: https://github.com/Keeper-Security/secrets-manager/compare/ruby-sdk-v17.1.0...ruby-sdk-v17.2.0
data/Gemfile CHANGED
@@ -4,6 +4,9 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :development, :test do
7
+ gem 'base32', '~> 0.3' # Required for TOTP support in tests
8
+ gem 'dotenv', '~> 2.8'
9
+ gem 'pry', '~> 0.14'
7
10
  gem 'rake', '~> 13.0'
8
11
  gem 'rspec', '~> 3.12'
9
12
  gem 'rubocop', '~> 1.12.0'
data/README.md CHANGED
@@ -1,305 +1,110 @@
1
- # Keeper Secrets Manager Ruby SDK
2
-
3
- The Ruby SDK for Keeper Secrets Manager provides a flexible, dynamic interface for accessing and managing secrets stored in Keeper's zero-knowledge vault.
4
-
5
- ## Features
6
-
7
- - **Ruby 3.1+ Compatible**: Works with Chef, Puppet, and modern Ruby applications
8
- - **Dynamic Record Handling**: JavaScript-style flexible records with no rigid class hierarchies
9
- - **Minimal Dependencies**: Uses only Ruby standard library (no external runtime dependencies)
10
- - **Comprehensive Crypto**: Full encryption/decryption support using OpenSSL
11
- - **Multiple Storage Options**: In-memory, file-based, environment variables, and caching
12
- - **Notation Support**: Access specific fields using `keeper://` URI notation
13
- - **Field Helpers**: Optional convenience methods for common field types
1
+ ## Keeper Secrets Manager Ruby SDK
2
+
3
+ For more information see our official documentation page https://docs.keeper.io/secrets-manager/secrets-manager/developer-sdk-library/ruby-sdk
4
+
5
+ # Change Log
6
+
7
+ ## 17.2.0 - 2025-11-14
8
+ - KSM-685 - Fixed `CreateOptions.subfolder_uid` parameter API transmission
9
+ - KSM-686 - Implemented disaster recovery caching with `CachingPostFunction`
10
+ - KSM-687 - Added missing DTO fields for complete SDK parity (links, is_editable, inner_folder_uid, thumbnail_url, last_modified, expires_on)
11
+ - KSM-1013 - Added typed linked-credential accessors (`KeeperRecordLink` via `record.get_links`) and a `request_links:` option on `get_secrets`
12
+ - KSM-692 - Added HTTP proxy support for enterprise environments
13
+ - KSM-694 - Added convenience methods (`upload_file_from_path`, `try_get_notation`)
14
+ - KSM-696 - Fixed file permissions for Ruby SDK config files
15
+ - KSM-697 - Comprehensive unit test coverage improvements (+358 tests, 63.3% coverage)
16
+ - KSM-734 - Fixed notation lookup to handle duplicate UIDs from record shortcuts
17
+ - KSM-743 - Added transmission public key #18 for Gov Cloud Dev environment support
18
+ - Added `from_config()` convenience method for base64 config initialization
19
+ - Added `update_secret_with_options()` method for removing file links
20
+ - Added `download_thumbnail()` method for file thumbnails
21
+ - Added development console (`bin/console`) for interactive SDK exploration
22
+ - Fixed example files to use correct SDK APIs
23
+ - Improved mock infrastructure with proper AES-256-GCM encryption
24
+
25
+ ## 17.1.0 - 2025-01-06
26
+ - **BREAKING**: Minimum Ruby version increased to 3.1.0 (from 2.6.0)
27
+ - Fixed ECC key generation to return 32-byte raw private keys
28
+ - Fixed `update_secret` to correctly encrypt and persist changes
29
+ - Fixed `download_file` SSL certificate verification
30
+ - Fixed `upload_file` to use correct endpoint
31
+ - Fixed `create_folder` encryption and parent_uid handling
32
+
33
+ For full version history, see [CHANGELOG.md](CHANGELOG.md)
34
+
35
+ # Quick Start
14
36
 
15
37
  ## Installation
16
38
 
17
- Add this line to your application's Gemfile:
18
-
19
- ```ruby
20
- gem 'keeper_secrets_manager'
21
- ```
22
-
23
- And then execute:
24
-
25
- ```bash
26
- $ bundle install
27
- ```
28
-
29
- Or install it yourself as:
30
-
31
39
  ```bash
32
- $ gem install keeper_secrets_manager
40
+ gem install keeper_secrets_manager
33
41
  ```
34
42
 
35
- ## Quick Start
36
-
37
- ### Initialize with One-Time Token
43
+ ## Basic Usage
38
44
 
39
45
  ```ruby
40
46
  require 'keeper_secrets_manager'
41
47
 
42
- # Initialize with one-time token
43
- token = "US:ONE_TIME_TOKEN_HERE"
44
- secrets_manager = KeeperSecretsManager.from_token(token)
45
-
46
- # Retrieve secrets
47
- records = secrets_manager.get_secrets
48
- records.each do |record|
49
- puts "#{record.title}: #{record.get_field_value_single('login')}"
50
- end
51
- ```
52
-
53
- ### Initialize with Existing Configuration
54
-
55
- ```ruby
56
- # From config file
48
+ # Initialize from config file
57
49
  secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
58
50
 
59
- # From environment (reads KSM_* variables)
60
- config = KeeperSecretsManager::Storage::EnvironmentStorage.new('KSM_')
61
- secrets_manager = KeeperSecretsManager.new(config: config)
62
- ```
63
-
64
- ## Dynamic Record Creation
65
-
66
- The Ruby SDK uses a flexible, JavaScript-style approach to records:
67
-
68
- ```ruby
69
- # Create record with hash syntax
70
- record = KeeperSecretsManager::Dto::KeeperRecord.new(
71
- title: 'My Server',
72
- type: 'login',
73
- fields: [
74
- { 'type' => 'login', 'value' => ['admin'] },
75
- { 'type' => 'password', 'value' => ['SecurePass123!'] },
76
- { 'type' => 'url', 'value' => ['https://example.com'] },
77
- {
78
- 'type' => 'host',
79
- 'value' => [{ 'hostName' => '192.168.1.1', 'port' => '22' }],
80
- 'label' => 'SSH Server'
81
- }
82
- ],
83
- custom: [
84
- { 'type' => 'text', 'label' => 'Environment', 'value' => ['Production'] }
85
- ]
86
- )
87
-
88
- # Dynamic field access
89
- puts record.login # => "admin"
90
- record.password = 'NewPassword123!'
51
+ # Get all secrets
52
+ records = secrets_manager.get_secrets
91
53
 
92
- # Set complex fields
93
- record.set_field('address', {
94
- 'street1' => '123 Main St',
95
- 'city' => 'New York',
96
- 'state' => 'NY',
97
- 'zip' => '10001'
98
- })
54
+ # Access secret fields
55
+ record = records.first
56
+ puts "Password: #{record.password}"
99
57
  ```
100
58
 
101
- ## Notation Support
59
+ ## Linked Credentials (PAM)
102
60
 
103
- Access specific field values using Keeper notation:
61
+ PAM records can carry linked credentials. Request them with `request_links: true`, then use the typed `KeeperRecordLink` accessors returned by `record.get_links` (the raw entries remain available on `record.links`):
104
62
 
105
63
  ```ruby
106
- # Get password from record
107
- password = secrets_manager.get_notation("keeper://RECORD_UID/field/password")
108
-
109
- # Get specific property from complex field
110
- hostname = secrets_manager.get_notation("keeper://RECORD_UID/field/host[hostName]")
111
- port = secrets_manager.get_notation("keeper://RECORD_UID/field/host[port]")
64
+ records = secrets_manager.get_secrets(request_links: true)
112
65
 
113
- # Get custom field by label
114
- env = secrets_manager.get_notation("keeper://RECORD_UID/custom_field/Environment")
115
-
116
- # Access by record title
117
- url = secrets_manager.get_notation("keeper://My Login/field/url")
118
- ```
119
-
120
- ## Field Type Helpers
121
-
122
- Optional convenience methods for creating typed fields:
66
+ records.each do |record|
67
+ record.get_links.each do |link|
68
+ puts "-> #{link.record_uid} (path: #{link.path.inspect})"
123
69
 
124
- ```ruby
125
- # Using field helpers
126
- fields = [
127
- KeeperSecretsManager::FieldTypes::Helpers.login('username'),
128
- KeeperSecretsManager::FieldTypes::Helpers.password('SecurePass123!'),
129
- KeeperSecretsManager::FieldTypes::Helpers.host(
130
- hostname: '192.168.1.100',
131
- port: 22
132
- ),
133
- KeeperSecretsManager::FieldTypes::Helpers.name(
134
- first: 'John',
135
- last: 'Doe',
136
- middle: 'Q'
137
- )
138
- ]
70
+ # Permission booleans read allowedSettings when nested (e.g. on "meta" links)
71
+ puts " rotation allowed: #{link.allows_rotation?}"
72
+ puts " admin user: #{link.admin_user?}"
139
73
 
140
- record = KeeperSecretsManager::Dto::KeeperRecord.new(
141
- title: 'Server with Helpers',
142
- type: 'login',
143
- fields: fields.map(&:to_h)
144
- )
74
+ # Encrypted ai_settings / jit_settings decrypt with the owning record's key
75
+ ai = link.get_ai_settings_data(record.record_key)
76
+ puts " ai settings: #{ai.inspect}" if ai
77
+ end
78
+ end
145
79
  ```
146
80
 
147
- ## Storage Options
81
+ Accessors never raise — decode or decryption failures return `nil`/`false`.
148
82
 
149
- ### In-Memory Storage
150
- ```ruby
151
- storage = KeeperSecretsManager::Storage::InMemoryStorage.new
152
- ```
83
+ ## Proxy Support
153
84
 
154
- ### File Storage
155
- ```ruby
156
- storage = KeeperSecretsManager::Storage::FileStorage.new('keeper_config.json')
157
- ```
85
+ For enterprise environments behind HTTP proxies:
158
86
 
159
- ### Environment Variables
160
87
  ```ruby
161
- # Reads from KSM_* environment variables (read-only)
162
- storage = KeeperSecretsManager::Storage::EnvironmentStorage.new('KSM_')
163
- ```
164
-
165
- ### Caching Storage
166
- ```ruby
167
- # Wrap any storage with caching (600 second TTL)
168
- base_storage = KeeperSecretsManager::Storage::FileStorage.new('config.json')
169
- storage = KeeperSecretsManager::Storage::CachingStorage.new(base_storage, 600)
170
- ```
171
-
172
- ## CRUD Operations
173
-
174
- ### Create Record
175
- ```ruby
176
- record = KeeperSecretsManager::Dto::KeeperRecord.new(
177
- title: 'New Record',
178
- type: 'login',
179
- fields: [
180
- { 'type' => 'login', 'value' => ['user'] },
181
- { 'type' => 'password', 'value' => ['pass'] }
182
- ]
88
+ # Method 1: Explicit proxy_url parameter
89
+ secrets_manager = KeeperSecretsManager.from_file(
90
+ 'keeper_config.json',
91
+ proxy_url: 'http://proxy.company.com:8080'
183
92
  )
184
93
 
185
- record_uid = secrets_manager.create_secret(record)
186
- ```
187
-
188
- ### Update Record
189
- ```ruby
190
- # Get existing record
191
- record = secrets_manager.get_secret_by_title("My Record")
192
-
193
- # Update fields
194
- record.set_field('password', 'NewPassword123!')
195
- record.notes = "Updated on #{Time.now}"
196
-
197
- # Save changes
198
- secrets_manager.update_secret(record)
199
- ```
200
-
201
- ### Delete Records
202
- ```ruby
203
- # Delete single record
204
- secrets_manager.delete_secret('RECORD_UID')
205
-
206
- # Delete multiple records
207
- secrets_manager.delete_secret(['UID1', 'UID2', 'UID3'])
208
- ```
209
-
210
- ### Folder Operations
211
- ```ruby
212
- # Get all folders
213
- folders = secrets_manager.get_folders
214
-
215
- # Create folder
216
- folder_uid = secrets_manager.create_folder('New Folder', parent_uid: 'PARENT_UID')
217
-
218
- # Update folder
219
- secrets_manager.update_folder(folder_uid, 'Renamed Folder')
220
-
221
- # Delete folder
222
- secrets_manager.delete_folder(folder_uid, force: true)
223
-
224
- # Folder hierarchy features
225
- fm = secrets_manager.folder_manager
226
-
227
- # Build folder tree structure
228
- tree = fm.build_folder_tree
229
-
230
- # Get folder path from root
231
- path = secrets_manager.get_folder_path(folder_uid) # "Parent/Child/Grandchild"
232
-
233
- # Find folder by name
234
- folder = secrets_manager.find_folder_by_name("Finance")
235
- folder = secrets_manager.find_folder_by_name("Finance", parent_uid: "parent_uid")
236
-
237
- # Get folder relationships
238
- ancestors = fm.get_ancestors(folder_uid) # [parent, grandparent, ...]
239
- descendants = fm.get_descendants(folder_uid) # [children, grandchildren, ...]
240
-
241
- # Print folder tree to console
242
- fm.print_tree
243
- ```
244
-
245
- ## Error Handling
246
-
247
- ```ruby
248
- begin
249
- records = secrets_manager.get_secrets
250
- rescue KeeperSecretsManager::AuthenticationError => e
251
- puts "Authentication failed: #{e.message}"
252
- rescue KeeperSecretsManager::NetworkError => e
253
- puts "Network error: #{e.message}"
254
- rescue KeeperSecretsManager::Error => e
255
- puts "General error: #{e.message}"
256
- end
257
- ```
258
-
259
- ## Configuration
260
-
261
- The SDK can be configured through various options:
262
-
263
- ```ruby
264
- secrets_manager = KeeperSecretsManager.new(
265
- config: storage,
266
- hostname: 'keepersecurity.eu', # EU datacenter
267
- verify_ssl_certs: true, # Verify SSL certificates
268
- logger: Logger.new(STDOUT), # Custom logger
269
- log_level: Logger::DEBUG # Log level
94
+ # Method 2: Authenticated proxy
95
+ secrets_manager = KeeperSecretsManager.from_file(
96
+ 'keeper_config.json',
97
+ proxy_url: 'http://username:password@proxy.company.com:8080'
270
98
  )
271
- ```
272
-
273
- ## Development
274
99
 
275
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
276
-
277
- To install this gem onto your local machine, run `bundle exec rake install`.
278
-
279
- ## Testing
280
-
281
- ```bash
282
- # Run all tests
283
- bundle exec rake spec
284
-
285
- # Run unit tests only
286
- bundle exec rake unit
287
-
288
- # Run with coverage
289
- bundle exec rake coverage
290
-
291
- # Run linter
292
- bundle exec rubocop
100
+ # Method 3: HTTPS_PROXY environment variable (recommended)
101
+ # export HTTPS_PROXY=http://proxy.company.com:8080
102
+ secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
103
+ # Proxy auto-detected from environment
293
104
  ```
294
105
 
295
- ## Contributing
296
-
297
- Bug reports and pull requests are welcome on GitHub at https://github.com/Keeper-Security/secrets-manager.
298
-
299
- ## License
300
-
301
- The gem is available as open source under the terms of the MIT License.
106
+ See `examples/ruby/12_proxy_usage.rb` for complete examples.
302
107
 
303
- ## Support
108
+ # Documentation
304
109
 
305
- For support, please visit https://docs.keeper.io/secrets-manager/ or contact sm@keepersecurity.com
110
+ For complete documentation, see: https://docs.keeper.io/secrets-manager/secrets-manager/developer-sdk-library/ruby-sdk
data/bin/console ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Interactive console for Keeper Secrets Manager Ruby SDK development
5
+
6
+ require 'bundler/setup'
7
+ require 'pry'
8
+
9
+ # Load the SDK from local source
10
+ require_relative '../lib/keeper_secrets_manager'
11
+
12
+ # Load environment variables if .env exists
13
+ begin
14
+ require 'dotenv/load'
15
+ puts "✓ Loaded environment variables from .env"
16
+ rescue LoadError
17
+ # dotenv not available, skip
18
+ end
19
+
20
+ # Helper message
21
+ puts "Keeper Secrets Manager Ruby SDK Console"
22
+ puts "=" * 60
23
+ puts "SDK loaded from: #{File.expand_path('../lib/keeper_secrets_manager.rb', __dir__)}"
24
+ puts "Version: #{KeeperSecretsManager::VERSION}"
25
+ puts
26
+
27
+ if ENV['KSM_CONFIG']
28
+ puts "Quick start:"
29
+ puts " storage = KeeperSecretsManager::Storage::InMemoryStorage.new(ENV['KSM_CONFIG'])"
30
+ puts " sm = KeeperSecretsManager.new(config: storage)"
31
+ puts " secrets = sm.get_secrets"
32
+ puts
33
+ puts "With caching:"
34
+ puts " sm = KeeperSecretsManager.new(config: storage, custom_post_function: KeeperSecretsManager::CachingPostFunction)"
35
+ puts
36
+ else
37
+ puts "No KSM_CONFIG found in environment"
38
+ puts "Set it in .env or export it before running"
39
+ puts
40
+ end
41
+
42
+ puts "Type 'ls KeeperSecretsManager' to explore the SDK"
43
+ puts "=" * 60
44
+ puts
45
+
46
+ # Start Pry REPL
47
+ Pry.start
@@ -0,0 +1,36 @@
1
+ require_relative 'lib/keeper_secrets_manager/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'keeper_secrets_manager'
5
+ spec.version = KeeperSecretsManager::VERSION
6
+ spec.authors = ['Keeper Security']
7
+ spec.email = ['sm@keepersecurity.com']
8
+
9
+ spec.summary = 'Keeper Secrets Manager SDK for Ruby'
10
+ spec.description = 'Ruby SDK for Keeper Secrets Manager - A zero-knowledge platform for managing and protecting infrastructure secrets'
11
+ spec.homepage = 'https://github.com/Keeper-Security/secrets-manager'
12
+ spec.license = 'MIT'
13
+ spec.required_ruby_version = '>= 3.1.0'
14
+
15
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = 'https://github.com/Keeper-Security/secrets-manager'
18
+ spec.metadata['changelog_uri'] = 'https://github.com/Keeper-Security/secrets-manager/blob/master/CHANGELOG.md'
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
24
+ end
25
+ end
26
+ spec.bindir = 'exe'
27
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ['lib']
29
+
30
+ # base64 and logger were default gems through Ruby 3.x; Ruby 4.0 unbundled them.
31
+ # Both are maintained by the Ruby core team — declaring them makes the implicit explicit.
32
+ spec.add_runtime_dependency 'base64'
33
+ spec.add_runtime_dependency 'logger'
34
+
35
+ # All development dependencies are in Gemfile
36
+ end