cerbos 0.7.0 → 0.8.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: '09d04980a1c08690efeeac6d04608e47e18def9b0f2ab6a5c256b4b22576464d'
4
- data.tar.gz: 61968be4473d1a480979d9e2d2af05f0911f1d8b4a8c90947d8dce72910565f7
3
+ metadata.gz: c6961d2c4bf6227d115dfa027f8823762bba4725c3d0dbe0c884ba2d69d0a253
4
+ data.tar.gz: 45d8c99f6aaeaa8aea2f30a0b0c4befbed70c6feb97f53f5f6c2288eada4919b
5
5
  SHA512:
6
- metadata.gz: 788ca1b6ff6c4e3a1ea71c791fef64f5802a89423d21dba5da7f91f7fc697ff91f1aa7ebcedab4d4bde807c531b3b13b4ac5e95a53b93d76c79077e214ecd54b
7
- data.tar.gz: 2115919d8cb958b0c347c09710d780d7748fec5933f65f4e91d2af7c937ec0e151ad7cfa808526213a788839ea8360fcfa153b94b9574d9ce6facabdca56fab1
6
+ metadata.gz: 50f06f8fc92658d6ade88f5ccfc92c899e8584aeb0c043faa1d350493645c49674ca0a1faff8484ba07d53f6243436622fb855fed1cdff47705d1dfde0c8c735
7
+ data.tar.gz: 2d440c072fb8554ed687004ca97ed1717e9735d031f385350da15ddf5bd52fe427837c5a330bbc2cb82bbdc3fcfe733f924bcb9cae1c597bed4eec5b79ebc490
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  No notable changes.
4
4
 
5
+ ## [0.8.0] - 2024-01-12
6
+
7
+ ### Added
8
+
9
+ - `grpc_metadata` option to `Cerbos::Client` constructor and request methods to add gRPC metadata (a.k.a. HTTP headers) to requests to the policy decision point ([#132](https://github.com/cerbos/cerbos-sdk-ruby/pull/132))
10
+
5
11
  ## [0.7.0] - 2023-06-07
6
12
 
7
13
  ### Added
@@ -68,7 +74,8 @@ No notable changes.
68
74
 
69
75
  - Initial implementation of `Cerbos::Client` ([#2](https://github.com/cerbos/cerbos-sdk-ruby/pull/2))
70
76
 
71
- [Unreleased]: https://github.com/cerbos/cerbos-sdk-ruby/compare/v0.7.0...HEAD
77
+ [Unreleased]: https://github.com/cerbos/cerbos-sdk-ruby/compare/v0.8.0...HEAD
78
+ [0.8.0]: https://github.com/cerbos/cerbos-sdk-ruby/compare/v0.7.0...v0.8.0
72
79
  [0.7.0]: https://github.com/cerbos/cerbos-sdk-ruby/compare/v0.6.1...v0.7.0
73
80
  [0.6.1]: https://github.com/cerbos/cerbos-sdk-ruby/compare/v0.6.0...v0.6.1
74
81
  [0.6.0]: https://github.com/cerbos/cerbos-sdk-ruby/compare/v0.5.0...v0.6.0
data/lib/cerbos/client.rb CHANGED
@@ -4,14 +4,22 @@ module Cerbos
4
4
  # A client for interacting with the Cerbos policy decision point (PDP) server over gRPC.
5
5
  #
6
6
  # An instance of the client may be shared between threads.
7
- # However, due to [an issue in the underlying `grpc` gem](https://github.com/grpc/grpc/issues/8798), it's not possible to use the client before and after process forks.
8
- # If your application runs on a forking webserver (for example, Puma in clustered mode), then you'll need to ensure that you only create client instances in the child (worker) processes.
7
+ #
8
+ # Due to [a limitation in the underlying `grpc` gem](https://github.com/grpc/grpc/issues/8798), creating a client instance before a process fork is [only (experimentally) supported on Linux](https://github.com/grpc/grpc/pull/33430) and requires you to
9
+ # - have at least v1.57.0 of the `grpc` gem installed,
10
+ # - set the `GRPC_ENABLE_FORK_SUPPORT` environment variable to `1`,
11
+ # - call `GRPC.prefork` before forking,
12
+ # - call `GRPC.postfork_parent` in the parent process after forking, and
13
+ # - call `GRPC.postfork_child` in the child processes after forking.
14
+ #
15
+ # Otherwise, if your application runs on a forking webserver (for example, Puma in clustered mode), then you'll need to ensure that you only create client instances in the child (worker) processes.
9
16
  class Client
10
17
  # Create a client for interacting with the Cerbos PDP server over gRPC.
11
18
  #
12
19
  # @param target [String] Cerbos PDP server address (`"host"`, `"host:port"`, or `"unix:/path/to/socket"`).
13
20
  # @param tls [TLS, MutualTLS, false] gRPC connection encryption settings (`false` for plaintext).
14
21
  # @param grpc_channel_args [Hash{String, Symbol => String, Integer}] low-level settings for the gRPC channel (see [available keys in the gRPC documentation](https://grpc.github.io/grpc/core/group__grpc__arg__keys.html)).
22
+ # @param grpc_metadata [Hash{String, Symbol => String, Array<String>}] gRPC metadata (a.k.a. HTTP headers) to add to every request to the PDP.
15
23
  # @param on_validation_error [:return, :raise, #call] action to take when input fails schema validation (`:return` to return the validation errors in the response, `:raise` to raise {Error::ValidationFailed}, or a callback to invoke).
16
24
  # @param playground_instance [String, nil] identifier of the playground instance to use when prototyping against the hosted demo PDP.
17
25
  # @param timeout [Numeric, nil] timeout for gRPC calls, in seconds (`nil` to never time out).
@@ -30,7 +38,8 @@ module Cerbos
30
38
  #
31
39
  # @example Invoke a callback when input fails schema validation
32
40
  # client = Cerbos::Client.new("localhost:3593", tls: false, on_validation_error: ->(validation_errors) { do_something_with validation_errors })
33
- def initialize(target, tls:, grpc_channel_args: {}, on_validation_error: :return, playground_instance: nil, timeout: nil)
41
+ def initialize(target, tls:, grpc_channel_args: {}, grpc_metadata: {}, on_validation_error: :return, playground_instance: nil, timeout: nil)
42
+ @grpc_metadata = grpc_metadata.transform_keys(&:to_sym)
34
43
  @on_validation_error = on_validation_error
35
44
 
36
45
  handle_errors do
@@ -60,6 +69,7 @@ module Cerbos
60
69
  # @param action [String] the action to check.
61
70
  # @param aux_data [Input::AuxData, Hash, nil] auxiliary data.
62
71
  # @param request_id [String] identifier for tracing the request.
72
+ # @param grpc_metadata [Hash{String, Symbol => String, Array<String>}] gRPC metadata (a.k.a. HTTP headers) to add to the request.
63
73
  #
64
74
  # @return [Boolean]
65
75
  #
@@ -69,13 +79,14 @@ module Cerbos
69
79
  # resource: {kind: "document", id: "1"},
70
80
  # action: "view"
71
81
  # ) # => true
72
- def allow?(principal:, resource:, action:, aux_data: nil, request_id: SecureRandom.uuid)
82
+ def allow?(principal:, resource:, action:, aux_data: nil, request_id: SecureRandom.uuid, grpc_metadata: {})
73
83
  check_resource(
74
84
  principal: principal,
75
85
  resource: resource,
76
86
  actions: [action],
77
87
  aux_data: aux_data,
78
- request_id: request_id
88
+ request_id: request_id,
89
+ grpc_metadata: grpc_metadata
79
90
  ).allow?(action)
80
91
  end
81
92
 
@@ -87,6 +98,7 @@ module Cerbos
87
98
  # @param aux_data [Input::AuxData, Hash, nil] auxiliary data.
88
99
  # @param include_metadata [Boolean] `true` to include additional metadata ({Output::CheckResources::Result::Metadata}) in the results.
89
100
  # @param request_id [String] identifier for tracing the request.
101
+ # @param grpc_metadata [Hash{String, Symbol => String, Array<String>}] gRPC metadata (a.k.a. HTTP headers) to add to the request.
90
102
  #
91
103
  # @return [Output::CheckResources::Result]
92
104
  #
@@ -98,14 +110,15 @@ module Cerbos
98
110
  # )
99
111
  #
100
112
  # decision.allow?("view") # => true
101
- def check_resource(principal:, resource:, actions:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid)
113
+ def check_resource(principal:, resource:, actions:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid, grpc_metadata: {})
102
114
  handle_errors do
103
115
  check_resources(
104
116
  principal: principal,
105
117
  resources: [Input::ResourceCheck.new(resource: resource, actions: actions)],
106
118
  aux_data: aux_data,
107
119
  include_metadata: include_metadata,
108
- request_id: request_id
120
+ request_id: request_id,
121
+ grpc_metadata: grpc_metadata
109
122
  ).find_result(resource)
110
123
  end
111
124
  end
@@ -117,6 +130,7 @@ module Cerbos
117
130
  # @param aux_data [Input::AuxData, Hash, nil] auxiliary data.
118
131
  # @param include_metadata [Boolean] `true` to include additional metadata ({Output::CheckResources::Result::Metadata}) in the results.
119
132
  # @param request_id [String] identifier for tracing the request.
133
+ # @param grpc_metadata [Hash{String, Symbol => String, Array<String>}] gRPC metadata (a.k.a. HTTP headers) to add to the request.
120
134
  #
121
135
  # @return [Output::CheckResources]
122
136
  #
@@ -136,7 +150,7 @@ module Cerbos
136
150
  # )
137
151
  #
138
152
  # decision.allow?(resource: {kind: "document", id: "1"}, action: "view") # => true
139
- def check_resources(principal:, resources:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid)
153
+ def check_resources(principal:, resources:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid, grpc_metadata: {})
140
154
  handle_errors do
141
155
  request = Protobuf::Cerbos::Request::V1::CheckResourcesRequest.new(
142
156
  principal: Input.coerce_required(principal, Input::Principal).to_protobuf,
@@ -146,7 +160,7 @@ module Cerbos
146
160
  request_id: request_id
147
161
  )
148
162
 
149
- response = perform_request(@cerbos_service, :check_resources, request)
163
+ response = perform_request(@cerbos_service, :check_resources, request, grpc_metadata)
150
164
 
151
165
  Output::CheckResources.from_protobuf(response).tap do |output|
152
166
  handle_validation_errors output
@@ -162,6 +176,7 @@ module Cerbos
162
176
  # @param aux_data [Input::AuxData, Hash, nil] auxiliary data.
163
177
  # @param include_metadata [Boolean] `true` to include additional metadata ({Output::CheckResources::Result::Metadata}) in the results.
164
178
  # @param request_id [String] identifier for tracing the request.
179
+ # @param grpc_metadata [Hash{String, Symbol => String, Array<String>}] gRPC metadata (a.k.a. HTTP headers) to add to the request.
165
180
  #
166
181
  # @return [Output::PlanResources]
167
182
  #
@@ -174,7 +189,7 @@ module Cerbos
174
189
  #
175
190
  # plan.conditional? # => true
176
191
  # plan.condition # => #<Cerbos::Output::PlanResources::Expression ...>
177
- def plan_resources(principal:, resource:, action:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid)
192
+ def plan_resources(principal:, resource:, action:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid, grpc_metadata: {})
178
193
  handle_errors do
179
194
  request = Protobuf::Cerbos::Request::V1::PlanResourcesRequest.new(
180
195
  principal: Input.coerce_required(principal, Input::Principal).to_protobuf,
@@ -185,7 +200,7 @@ module Cerbos
185
200
  request_id: request_id
186
201
  )
187
202
 
188
- response = perform_request(@cerbos_service, :plan_resources, request)
203
+ response = perform_request(@cerbos_service, :plan_resources, request, grpc_metadata)
189
204
 
190
205
  Output::PlanResources.from_protobuf(response).tap do |output|
191
206
  handle_validation_errors output
@@ -195,12 +210,14 @@ module Cerbos
195
210
 
196
211
  # Retrieve information about the Cerbos PDP server.
197
212
  #
213
+ # @param grpc_metadata [Hash{String, Symbol => String, Array<String>}] gRPC metadata (a.k.a. HTTP headers) to add to the request.
214
+ #
198
215
  # @return [Output::ServerInfo]
199
- def server_info
216
+ def server_info(grpc_metadata: {})
200
217
  handle_errors do
201
218
  request = Protobuf::Cerbos::Request::V1::ServerInfoRequest.new
202
219
 
203
- response = perform_request(@cerbos_service, :server_info, request)
220
+ response = perform_request(@cerbos_service, :server_info, request, grpc_metadata)
204
221
 
205
222
  Output::ServerInfo.from_protobuf(response)
206
223
  end
@@ -231,8 +248,8 @@ module Cerbos
231
248
  @on_validation_error.call validation_errors
232
249
  end
233
250
 
234
- def perform_request(service, rpc, request)
235
- service.public_send(rpc, request)
251
+ def perform_request(service, rpc, request, metadata)
252
+ service.public_send(rpc, request, metadata: @grpc_metadata.merge(metadata.transform_keys(&:to_sym)))
236
253
  end
237
254
  end
238
255
  end
data/lib/cerbos/error.rb CHANGED
@@ -12,7 +12,7 @@ module Cerbos
12
12
 
13
13
  # @private
14
14
  def initialize(validation_errors)
15
- super "Input failed schema validation"
15
+ super("Input failed schema validation")
16
16
 
17
17
  @validation_errors = validation_errors
18
18
  end
@@ -48,7 +48,7 @@ module Cerbos
48
48
 
49
49
  # @private
50
50
  def initialize(code:, details:, metadata: {})
51
- super "gRPC error #{code}: #{details}"
51
+ super("gRPC error #{code}: #{details}")
52
52
 
53
53
  @code = code
54
54
  @details = details
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Cerbos
4
4
  # Current version of the `cerbos` gem.
5
- VERSION = "0.7.0"
5
+ VERSION = "0.8.0"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cerbos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cerbos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-07 00:00:00.000000000 Z
11
+ date: 2024-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc
@@ -77,7 +77,7 @@ licenses:
77
77
  metadata:
78
78
  bug_tracker_uri: https://github.com/cerbos/cerbos-sdk-ruby/issues
79
79
  changelog_uri: https://github.com/cerbos/cerbos-sdk-ruby/blob/main/CHANGELOG.md
80
- documentation_uri: https://www.rubydoc.info/gems/cerbos/0.7.0
80
+ documentation_uri: https://www.rubydoc.info/gems/cerbos/0.8.0
81
81
  homepage_uri: https://github.com/cerbos/cerbos-sdk-ruby
82
82
  source_code_uri: https://github.com/cerbos/cerbos-sdk-ruby
83
83
  rubygems_mfa_required: 'true'
@@ -96,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  requirements: []
99
- rubygems_version: 3.4.13
99
+ rubygems_version: 3.5.4
100
100
  signing_key:
101
101
  specification_version: 4
102
102
  summary: Client library for authorization via Cerbos