cerbos 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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