strongdm 15.41.0 → 15.44.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: 5b1e9f52173a0bece622752999286e3fbefef573f7c9a8cee68fc6687e73414d
4
- data.tar.gz: 6cc7b1cc2900a86d9ecb939b67dff13189ced426becb976e110070d3b16efb9f
3
+ metadata.gz: ce4a3c69eb97f4b8a93947190db567417e1f4eefcdeaf18f15444159186c70d7
4
+ data.tar.gz: fffb501db75633dffc8c344a799fcabe2bc3f1ea2862be66d36f036631ea64d0
5
5
  SHA512:
6
- metadata.gz: 49280bb2ba6cb9925a9a8a6456cb05d3fcfd9fb26992e04490c82ea19f31ac0e158a5aa6883bc96a6a7be6a3d117dc0f34a5dc02bb7bf73ab9b9b5d21c803aa8
7
- data.tar.gz: 868450c0b94a863c315ee0a881c1d3d0627e2284eb3c28cc3682ee62f0c0566ce4a93afa0ba7f3cc5889a40281f0d1f2220f9d7652048b060e060e34c00b9146
6
+ metadata.gz: 8d58f24f7d86471d96c6bf8e497d1a5bffdfc04592cdf054a4c3742cb6db00c2666abf92234150588a0ef2cae3e2588a50ddd3837bb30254954af7b3578436be
7
+ data.tar.gz: 6d6ff726b001250e581d8a3f10dabba33a32821fc353058e7b19a9713ef6a8fd475310388eab3bc0a76045cfbd1346f4e135d28136ddaf0757489604f4deb627
data/.git/ORIG_HEAD CHANGED
@@ -1 +1 @@
1
- b20e3c16d138fc17c80e82311c7613a915bc3569
1
+ 1170439941e521c29339b4d2314cae0e1526759e
data/.git/index CHANGED
Binary file
data/.git/logs/HEAD CHANGED
@@ -1,3 +1,3 @@
1
- 0000000000000000000000000000000000000000 b20e3c16d138fc17c80e82311c7613a915bc3569 root <root@e35d0cf551cb.(none)> 1765963630 +0000 clone: from github.com:strongdm/strongdm-sdk-ruby.git
2
- b20e3c16d138fc17c80e82311c7613a915bc3569 b20e3c16d138fc17c80e82311c7613a915bc3569 root <root@e35d0cf551cb.(none)> 1765963630 +0000 checkout: moving from master to master
3
- b20e3c16d138fc17c80e82311c7613a915bc3569 b23f0912dbe900e5bd24222f9971c7820ddf128d root <root@e35d0cf551cb.(none)> 1765963630 +0000 merge origin/development: Fast-forward
1
+ 0000000000000000000000000000000000000000 1170439941e521c29339b4d2314cae0e1526759e root <root@4389641f949d.(none)> 1767894497 +0000 clone: from github.com:strongdm/strongdm-sdk-ruby.git
2
+ 1170439941e521c29339b4d2314cae0e1526759e 1170439941e521c29339b4d2314cae0e1526759e root <root@4389641f949d.(none)> 1767894497 +0000 checkout: moving from master to master
3
+ 1170439941e521c29339b4d2314cae0e1526759e 75a012035de3f39e75968747f1365c6f501d73d9 root <root@4389641f949d.(none)> 1767894497 +0000 merge origin/development: Fast-forward
@@ -1,2 +1,2 @@
1
- 0000000000000000000000000000000000000000 b20e3c16d138fc17c80e82311c7613a915bc3569 root <root@e35d0cf551cb.(none)> 1765963630 +0000 clone: from github.com:strongdm/strongdm-sdk-ruby.git
2
- b20e3c16d138fc17c80e82311c7613a915bc3569 b23f0912dbe900e5bd24222f9971c7820ddf128d root <root@e35d0cf551cb.(none)> 1765963630 +0000 merge origin/development: Fast-forward
1
+ 0000000000000000000000000000000000000000 1170439941e521c29339b4d2314cae0e1526759e root <root@4389641f949d.(none)> 1767894497 +0000 clone: from github.com:strongdm/strongdm-sdk-ruby.git
2
+ 1170439941e521c29339b4d2314cae0e1526759e 75a012035de3f39e75968747f1365c6f501d73d9 root <root@4389641f949d.(none)> 1767894497 +0000 merge origin/development: Fast-forward
@@ -1 +1 @@
1
- 0000000000000000000000000000000000000000 b20e3c16d138fc17c80e82311c7613a915bc3569 root <root@e35d0cf551cb.(none)> 1765963630 +0000 clone: from github.com:strongdm/strongdm-sdk-ruby.git
1
+ 0000000000000000000000000000000000000000 1170439941e521c29339b4d2314cae0e1526759e root <root@4389641f949d.(none)> 1767894497 +0000 clone: from github.com:strongdm/strongdm-sdk-ruby.git
data/.git/packed-refs CHANGED
@@ -1,6 +1,6 @@
1
1
  # pack-refs with: peeled fully-peeled sorted
2
- b23f0912dbe900e5bd24222f9971c7820ddf128d refs/remotes/origin/development
3
- b20e3c16d138fc17c80e82311c7613a915bc3569 refs/remotes/origin/master
2
+ 75a012035de3f39e75968747f1365c6f501d73d9 refs/remotes/origin/development
3
+ 1170439941e521c29339b4d2314cae0e1526759e refs/remotes/origin/master
4
4
  2e4fe8087177ddea9b3991ca499f758384839c89 refs/tags/untagged-84fd83a4484c785cce63
5
5
  04f604866214fab4d5663b5171a3e596331577bd refs/tags/v0.9.4
6
6
  6f9a7b75b345c65fb554884907b7060680c807b7 refs/tags/v0.9.5
@@ -128,6 +128,8 @@ e2a4215bd3bbfb822423e11e81b9ad47bef03840 refs/tags/v15.36.0
128
128
  740f705c286a25c2abae5a44b52fe330cc4e3e71 refs/tags/v15.39.0
129
129
  cf3b15b82cb0c4229609c07c870c6cb4fd38ef75 refs/tags/v15.4.0
130
130
  b20e3c16d138fc17c80e82311c7613a915bc3569 refs/tags/v15.40.0
131
+ b23f0912dbe900e5bd24222f9971c7820ddf128d refs/tags/v15.41.0
132
+ 1170439941e521c29339b4d2314cae0e1526759e refs/tags/v15.43.0
131
133
  0be2c5e7f7a90c49077548cb3a9bce234219b9f0 refs/tags/v15.5.0
132
134
  4b9cd43c5dda3f369b82b6a56132a5470ff9ff53 refs/tags/v15.6.0
133
135
  6e8e9210b26f02ebe925b8e81909ba42985cfde7 refs/tags/v15.7.0
@@ -1 +1 @@
1
- b23f0912dbe900e5bd24222f9971c7820ddf128d
1
+ 75a012035de3f39e75968747f1365c6f501d73d9
data/lib/constants.rb CHANGED
@@ -333,6 +333,7 @@ module SDM
333
333
  RESOURCE_LOCKED = "user locked a resource"
334
334
  RESOURCE_UNLOCKED = "user unlocked a resource"
335
335
  RESOURCE_FORCE_UNLOCKED = "admin force-unlocked a resource"
336
+ RESOURCE_LOCK_REJECTED = "user lock rejected for a resource"
336
337
  CONCURRENT_AUTHENTICATION_REVOKED_PER_ORG_SETTING = "concurrent authentications revoked per organization settings"
337
338
  PEERING_GROUP_TOGGLED = "peering group toggled"
338
339
  PEERING_GROUP_CREATED = "peering group created"
@@ -106,10 +106,11 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
106
106
  repeated :services, :string, 5
107
107
  repeated :include_tags, :message, 6, "v1.Tag"
108
108
  repeated :exclude_tags, :message, 7, "v1.Tag"
109
- optional :project_number, :string, 20
110
- optional :provider_id, :string, 21
111
- optional :pool_id, :string, 22
112
109
  repeated :project_ids, :string, 23
110
+ optional :workload_project_number, :string, 24
111
+ optional :workload_project_id, :string, 25
112
+ optional :workload_provider_id, :string, 26
113
+ optional :workload_pool_id, :string, 27
113
114
  end
114
115
  end
115
116
  end
data/lib/grpc/plumbing.rb CHANGED
@@ -7178,12 +7178,13 @@ module SDM
7178
7178
  porcelain.id = (plumbing.id)
7179
7179
  porcelain.include_tags = convert_repeated_tag_to_porcelain(plumbing.include_tags)
7180
7180
  porcelain.name = (plumbing.name)
7181
- porcelain.pool_id = (plumbing.pool_id)
7182
7181
  porcelain.project_ids = (plumbing.project_ids)
7183
- porcelain.project_number = (plumbing.project_number)
7184
- porcelain.provider_id = (plumbing.provider_id)
7185
7182
  porcelain.scan_period = (plumbing.scan_period)
7186
7183
  porcelain.services = (plumbing.services)
7184
+ porcelain.workload_pool_id = (plumbing.workload_pool_id)
7185
+ porcelain.workload_project_id = (plumbing.workload_project_id)
7186
+ porcelain.workload_project_number = (plumbing.workload_project_number)
7187
+ porcelain.workload_provider_id = (plumbing.workload_provider_id)
7187
7188
  porcelain
7188
7189
  end
7189
7190
 
@@ -7197,12 +7198,13 @@ module SDM
7197
7198
  plumbing.id = (porcelain.id)
7198
7199
  plumbing.include_tags += convert_repeated_tag_to_plumbing(porcelain.include_tags)
7199
7200
  plumbing.name = (porcelain.name)
7200
- plumbing.pool_id = (porcelain.pool_id)
7201
7201
  plumbing.project_ids += (porcelain.project_ids)
7202
- plumbing.project_number = (porcelain.project_number)
7203
- plumbing.provider_id = (porcelain.provider_id)
7204
7202
  plumbing.scan_period = (porcelain.scan_period)
7205
7203
  plumbing.services += (porcelain.services)
7204
+ plumbing.workload_pool_id = (porcelain.workload_pool_id)
7205
+ plumbing.workload_project_id = (porcelain.workload_project_id)
7206
+ plumbing.workload_project_number = (porcelain.workload_project_number)
7207
+ plumbing.workload_provider_id = (porcelain.workload_provider_id)
7206
7208
  plumbing
7207
7209
  end
7208
7210
  def self.convert_repeated_gcp_connector_to_plumbing(porcelains)
@@ -0,0 +1,200 @@
1
+ # Copyright 2020 StrongDM Inc
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+
16
+ # @internal Code generated by protogen. DO NOT EDIT.
17
+
18
+ require "openssl"
19
+ require_relative "./grpc/plumbing"
20
+
21
+ module SDM
22
+ # MethodInterceptor provides a generic hook system for modifying
23
+ # requests and responses before/after gRPC calls
24
+ class MethodInterceptor
25
+ def initialize(client)
26
+ @client = client
27
+ @before_hooks = {}
28
+ @after_hooks = {}
29
+ end
30
+
31
+ # Register a hook to run before a method call
32
+ # method_name: "ServiceName.MethodName" (e.g., "ManagedSecrets.Create")
33
+ # block: receives (service_instance, request) and should return modified request
34
+ def before(method_name, &block)
35
+ @before_hooks[method_name] = block
36
+ end
37
+
38
+ # Register a hook to run after a method call
39
+ # method_name: "ServiceName.MethodName"
40
+ # block: receives (service_instance, request, response) and should return modified response
41
+ def after(method_name, &block)
42
+ @after_hooks[method_name] = block
43
+ end
44
+
45
+ # Execute before hooks for a method
46
+ def execute_before(method_name, service_instance, request)
47
+ hook = @before_hooks[method_name]
48
+ return request unless hook
49
+ hook.call(service_instance, request)
50
+ end
51
+
52
+ # Execute after hooks for a method
53
+ def execute_after(method_name, service_instance, request, response)
54
+ hook = @after_hooks[method_name]
55
+ return response unless hook
56
+ hook.call(service_instance, request, response)
57
+ end
58
+ end
59
+
60
+ # SecretEncryptionInterceptor implements encryption for managed secrets
61
+ class SecretEncryptionInterceptor
62
+ def initialize(client)
63
+ @client = client
64
+ @public_key_cache = {}
65
+ @private_key = nil
66
+ end
67
+
68
+ # Lazy-load private key for retrievals
69
+ def private_key
70
+ @private_key ||= OpenSSL::PKey::RSA.new(4096)
71
+ end
72
+
73
+ # Cache a secret engine's public key
74
+ def cache_public_key(engine_id, public_key_pem)
75
+ return if public_key_pem.nil? || public_key_pem.empty?
76
+ @public_key_cache[engine_id] = OpenSSL::PKey::RSA.new(public_key_pem)
77
+ end
78
+
79
+ # Get cached public key
80
+ def get_public_key(engine_id)
81
+ @public_key_cache[engine_id]
82
+ end
83
+
84
+ # Encrypt data using RSA-OAEP with SHA256
85
+ def encrypt(public_key, plaintext)
86
+ return plaintext if plaintext.nil? || plaintext.empty?
87
+ public_key.encrypt(plaintext, rsa_padding_mode: "oaep", rsa_oaep_md: "sha256", rsa_mgf1_md: "sha256")
88
+ end
89
+
90
+ # Decrypt data using RSA-OAEP with SHA256
91
+ def decrypt(ciphertext)
92
+ return ciphertext if ciphertext.nil? || ciphertext.empty?
93
+ private_key.decrypt(ciphertext, rsa_padding_mode: "oaep", rsa_oaep_md: "sha256", rsa_mgf1_md: "sha256")
94
+ end
95
+
96
+ # Export public key in PEM format
97
+ def export_public_key
98
+ private_key.public_key.to_pem
99
+ end
100
+
101
+ # Setup hooks on the interceptor
102
+ def setup(interceptor)
103
+ setup_managed_secrets_hooks(interceptor)
104
+ setup_secret_engines_hooks(interceptor)
105
+ end
106
+
107
+ private
108
+
109
+ def setup_managed_secrets_hooks(interceptor)
110
+ # Hook for ManagedSecrets.Create - encrypt before sending
111
+ interceptor.before("ManagedSecrets.Create") do |service, req|
112
+ secret = req.managed_secret
113
+ if secret && !secret.value.nil? && !secret.value.empty? && !secret.secret_engine_id.nil?
114
+ # Try to get public key from cache or fetch it
115
+ pub_key = get_public_key(secret.secret_engine_id)
116
+ if pub_key.nil?
117
+ begin
118
+ @client.secret_engines.get(secret.secret_engine_id)
119
+ pub_key = get_public_key(secret.secret_engine_id)
120
+ rescue
121
+ # If fetch fails, let server handle it
122
+ end
123
+ end
124
+
125
+ # Encrypt if we have the key
126
+ if pub_key
127
+ secret.value = encrypt(pub_key, secret.value)
128
+ end
129
+ end
130
+ req
131
+ end
132
+
133
+ # Hook for ManagedSecrets.Update - encrypt before sending
134
+ interceptor.before("ManagedSecrets.Update") do |service, req|
135
+ secret = req.managed_secret
136
+ if secret && !secret.value.nil? && !secret.value.empty? && !secret.secret_engine_id.nil?
137
+ pub_key = get_public_key(secret.secret_engine_id)
138
+ if pub_key.nil?
139
+ begin
140
+ @client.secret_engines.get(secret.secret_engine_id)
141
+ pub_key = get_public_key(secret.secret_engine_id)
142
+ rescue
143
+ # If fetch fails, let server handle it
144
+ end
145
+ end
146
+
147
+ if pub_key
148
+ secret.value = encrypt(pub_key, secret.value)
149
+ end
150
+ end
151
+ req
152
+ end
153
+
154
+ # Hook for ManagedSecrets.Retrieve - add public key and decrypt response
155
+ interceptor.before("ManagedSecrets.Retrieve") do |service, req|
156
+ if req.public_key.nil? || req.public_key.empty?
157
+ req.public_key = export_public_key
158
+ end
159
+ req
160
+ end
161
+
162
+ interceptor.after("ManagedSecrets.Retrieve") do |service, req, resp|
163
+ # Only decrypt if we provided the public key
164
+ if req.public_key == export_public_key
165
+ secret = resp.managed_secret
166
+ if secret && !secret.value.nil? && !secret.value.empty?
167
+ secret.value = decrypt(secret.value)
168
+ end
169
+ end
170
+ resp
171
+ end
172
+ end
173
+
174
+ def setup_secret_engines_hooks(interceptor)
175
+ # Hook for SecretEngines.Get - cache public key after response
176
+ interceptor.after("SecretEngines.Get") do |service, req, resp|
177
+ engine = Plumbing::convert_secret_engine_to_porcelain(resp.secret_engine)
178
+ if engine && !engine.id.nil? && !engine.public_key.nil?
179
+ cache_public_key(engine.id, engine.public_key)
180
+ end
181
+ resp
182
+ end
183
+ end
184
+ end
185
+
186
+ # EnumeratorInterceptor provides utilities for wrapping enumerators with hooks
187
+ module EnumeratorInterceptor
188
+ # Wraps an enumerator to cache secret engine public keys
189
+ def self.wrap_secret_engine_list(enumerator, encryption_interceptor)
190
+ Enumerator.new do |yielder|
191
+ enumerator.each do |engine|
192
+ if engine && !engine.id.nil? && !engine.public_key.nil?
193
+ encryption_interceptor.cache_public_key(engine.id, engine.public_key)
194
+ end
195
+ yielder << engine
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
@@ -6974,18 +6974,20 @@ module SDM
6974
6974
  attr_accessor :include_tags
6975
6975
  # Unique human-readable name of the Connector.
6976
6976
  attr_accessor :name
6977
- # PoolId is the GCP Workload Pool Identifier used to authenticate our JWT
6978
- attr_accessor :pool_id
6979
6977
  # ProjectIds is the list of GCP Projects the connector will scan
6980
6978
  attr_accessor :project_ids
6981
- # ProjectNumber is the GCP Project the Workload Pool is defined in
6982
- attr_accessor :project_number
6983
- # ProviderId is the GCP Workload Provider Identifier used to authenticate our JWT
6984
- attr_accessor :provider_id
6985
6979
  # ScanPeriod identifies which remote system this Connector discovers
6986
6980
  attr_accessor :scan_period
6987
6981
  # Services is a list of services this connector should scan.
6988
6982
  attr_accessor :services
6983
+ # WorkloadPoolId is the GCP Workload Pool Identifier used to authenticate our JWT
6984
+ attr_accessor :workload_pool_id
6985
+ # WorkloadProjectId is the GCP Project ID where the Workload Pool is defined
6986
+ attr_accessor :workload_project_id
6987
+ # WorkloadProjectNumber is the GCP Project Number where the Workload Pool is defined
6988
+ attr_accessor :workload_project_number
6989
+ # WorkloadProviderId is the GCP Workload Provider Identifier used to authenticate our JWT
6990
+ attr_accessor :workload_provider_id
6989
6991
 
6990
6992
  def initialize(
6991
6993
  description: nil,
@@ -6993,24 +6995,26 @@ module SDM
6993
6995
  id: nil,
6994
6996
  include_tags: nil,
6995
6997
  name: nil,
6996
- pool_id: nil,
6997
6998
  project_ids: nil,
6998
- project_number: nil,
6999
- provider_id: nil,
7000
6999
  scan_period: nil,
7001
- services: nil
7000
+ services: nil,
7001
+ workload_pool_id: nil,
7002
+ workload_project_id: nil,
7003
+ workload_project_number: nil,
7004
+ workload_provider_id: nil
7002
7005
  )
7003
7006
  @description = description == nil ? "" : description
7004
7007
  @exclude_tags = exclude_tags == nil ? [] : exclude_tags
7005
7008
  @id = id == nil ? "" : id
7006
7009
  @include_tags = include_tags == nil ? [] : include_tags
7007
7010
  @name = name == nil ? "" : name
7008
- @pool_id = pool_id == nil ? "" : pool_id
7009
7011
  @project_ids = project_ids == nil ? [] : project_ids
7010
- @project_number = project_number == nil ? "" : project_number
7011
- @provider_id = provider_id == nil ? "" : provider_id
7012
7012
  @scan_period = scan_period == nil ? "" : scan_period
7013
7013
  @services = services == nil ? [] : services
7014
+ @workload_pool_id = workload_pool_id == nil ? "" : workload_pool_id
7015
+ @workload_project_id = workload_project_id == nil ? "" : workload_project_id
7016
+ @workload_project_number = workload_project_number == nil ? "" : workload_project_number
7017
+ @workload_provider_id = workload_provider_id == nil ? "" : workload_provider_id
7014
7018
  end
7015
7019
 
7016
7020
  def to_json(options = {})
data/lib/strongdm.rb CHANGED
@@ -16,6 +16,7 @@
16
16
  # @internal Code generated by protogen. DO NOT EDIT.
17
17
 
18
18
  require_relative "./svc"
19
+ require_relative "./interceptors"
19
20
  require "base64"
20
21
  require "grpc"
21
22
  require "openssl"
@@ -30,7 +31,7 @@ module SDM #:nodoc:
30
31
  DEFAULT_RETRY_FACTOR = 1.6
31
32
  DEFAULT_RETRY_JITTER = 0.2
32
33
  API_VERSION = "2025-04-14"
33
- USER_AGENT = "strongdm-sdk-ruby/15.41.0"
34
+ USER_AGENT = "strongdm-sdk-ruby/15.44.0"
34
35
  private_constant :DEFAULT_BASE_RETRY_DELAY, :DEFAULT_MAX_RETRY_DELAY, :DEFAULT_RETRY_FACTOR, :DEFAULT_RETRY_JITTER, :API_VERSION, :USER_AGENT
35
36
 
36
37
  # Creates a new strongDM API client.
@@ -47,6 +48,10 @@ module SDM #:nodoc:
47
48
  @page_limit = page_limit
48
49
  @retry_rate_limit_errors = retry_rate_limit_errors
49
50
  @snapshot_time = nil
51
+ # Initialize method interceptor for request/response hooks
52
+ @interceptor = MethodInterceptor.new(self)
53
+ @encryption_interceptor = SecretEncryptionInterceptor.new(self)
54
+ @encryption_interceptor.setup(@interceptor)
50
55
  begin
51
56
  if insecure
52
57
  @channel = GRPC::Core::Channel.new(host, {}, :this_channel_is_insecure)
@@ -234,6 +239,8 @@ module SDM #:nodoc:
234
239
  attr_reader :api_access_key
235
240
  # Optional timestamp at which to provide historical data
236
241
  attr_reader :snapshot_time
242
+ # Method interceptor for request/response hooks (read-only).
243
+ attr_reader :interceptor
237
244
  # AccessRequests are requests for access to a resource that may match a Workflow.
238
245
  #
239
246
  # See {AccessRequests}.