Class: Cerbos::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/cerbos/client.rb

Overview

A client for interacting with the Cerbos policy decision point (PDP) server over gRPC.

An instance of the client may be shared between threads. However, due to an issue in the underlying grpc gem, it's not possible to use the client before and after process forks. 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.

Instance Method Summary collapse

Constructor Details

#initialize(target, tls:, grpc_channel_args: {}, playground_instance: nil, timeout: nil) ⇒ Client

Create a client for interacting with the Cerbos PDP server over gRPC.

Examples:

Connect via TCP with no encryption

client = Cerbos::Client.new("localhost:3593", tls: false)

Connect via a Unix socket with no encryption

client = Cerbos::Client.new("unix:/var/run/cerbos.grpc.sock", tls: false)

Connect to the hosted demo PDP to experiment in the playground

client = Cerbos::Client.new("demo-pdp.cerbos.cloud", tls: Cerbos::TLS.new, playground_instance: "gE623b0180QlsG5a4QIN6UOZ6f3iSFW2")

Parameters:

  • target (String)

    Cerbos PDP server address ("host", "host:port", or "unix:/path/to/socket").

  • tls (TLS, MutualTLS, false)

    gRPC connection encryption settings (false for plaintext).

  • grpc_channel_args (Hash{String, Symbol => String, Integer}) (defaults to: {})

    low-level settings for the gRPC channel (see available keys in the gRPC documentation).

  • playground_instance (String, nil) (defaults to: nil)

    identifier of the playground instance to use when prototyping against the hosted demo PDP.

  • timeout (Numeric, nil) (defaults to: nil)

    timeout for gRPC calls, in seconds (nil to never time out).


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/cerbos/client.rb', line 26

def initialize(target, tls:, grpc_channel_args: {}, playground_instance: nil, timeout: nil)
  handle_errors do
    credentials = tls ? tls.to_channel_credentials : :this_channel_is_insecure

    unless playground_instance.nil?
      credentials = credentials.compose(GRPC::Core::CallCredentials.new(->(*) { {"playground-instance" => playground_instance} }))
    end

    channel_args = grpc_channel_args.merge({
      "grpc.primary_user_agent" => [grpc_channel_args["grpc.primary_user_agent"], "cerbos-sdk-ruby/#{VERSION}"].compact.join(" ")
    })

    @cerbos_service = Protobuf::Cerbos::Svc::V1::CerbosService::Stub.new(
      target,
      credentials,
      channel_args: channel_args,
      timeout: timeout
    )
  end
end

Instance Method Details

#check_resource(principal:, resource:, actions:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid) ⇒ Output::CheckResources::Result

Check a principal's permissions on a resource.

Examples:

decision = client.check_resource(
  principal: {id: "[email protected]", roles: ["USER"]},
  resource: {kind: "document", id: "1"},
  actions: ["view", "edit"]
)

decision.allow?("view") # => true

Parameters:

Returns:


66
67
68
69
70
71
72
73
74
75
76
# File 'lib/cerbos/client.rb', line 66

def check_resource(principal:, resource:, actions:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid)
  handle_errors do
    check_resources(
      principal: principal,
      resources: [Input::ResourceCheck.new(resource: resource, actions: actions)],
      aux_data: aux_data,
      include_metadata: ,
      request_id: request_id
    ).find_result(resource)
  end
end

#check_resources(principal:, resources:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid) ⇒ Output::CheckResources

Check a principal's permissions on a set of resources.

Examples:

decision = client.check_resources(
  principal: {id: "[email protected]", roles: ["USER"]},
  resources: [
    {
      resource: {kind: "document", id: "1"},
      actions: ["view", "edit"]
    },
    {
      resource: {kind: "image", id: "1"},
      actions: ["delete"]
    }
  ]
)

result.allow?(resource: {kind: "document", id: "1"}, action: "view") # => true

Parameters:

  • principal (Input::Principal, Hash)

    the principal to check.

  • resources (Array<Input::ResourceCheck, Hash>)

    the resources and actions to check.

  • aux_data (Input::AuxData, Hash, nil) (defaults to: nil)

    auxiliary data.

  • include_metadata (Boolean) (defaults to: false)

    true to include additional metadata (Output::CheckResources::Result::Metadata) in the results.

  • request_id (String) (defaults to: SecureRandom.uuid)

    identifier for tracing the request.

Returns:


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/cerbos/client.rb', line 104

def check_resources(principal:, resources:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid)
  handle_errors do
    request = Protobuf::Cerbos::Request::V1::CheckResourcesRequest.new(
      principal: Input.coerce_required(principal, Input::Principal).to_protobuf,
      resources: Input.coerce_array(resources, Input::ResourceCheck).map(&:to_protobuf),
      aux_data: Input.coerce_optional(aux_data, Input::AuxData)&.to_protobuf,
      include_meta: ,
      request_id: request_id
    )

    response = perform_request(@cerbos_service, :check_resources, request)

    Output::CheckResources.from_protobuf(response)
  end
end

#plan_resources(principal:, resource:, action:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid) ⇒ Output::PlanResources

Produce a query plan that can be used to obtain a list of resources on which a principal is allowed to perform a particular action.

Examples:

plan = client.plan_resources(
  principal: {id: "[email protected]", roles: ["USER"]},
  resource: {kind: "document"},
  action: "view"
)

plan.conditional? # => true
plan.condition # => #<Cerbos::Output::PlanResources::Expression ...>

Parameters:

  • principal (Input::Principal, Hash)

    the principal for whom to plan.

  • resource (Input::ResourceQuery, Hash)

    partial details of the resources for which to plan.

  • action (String)

    the action for which to plan.

  • aux_data (Input::AuxData, Hash, nil) (defaults to: nil)

    auxiliary data.

  • include_metadata (Boolean) (defaults to: false)

    true to include additional metadata (Output::CheckResources::Result::Metadata) in the results.

  • request_id (String) (defaults to: SecureRandom.uuid)

    identifier for tracing the request.

Returns:


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/cerbos/client.rb', line 140

def plan_resources(principal:, resource:, action:, aux_data: nil, include_metadata: false, request_id: SecureRandom.uuid)
  handle_errors do
    request = Protobuf::Cerbos::Request::V1::PlanResourcesRequest.new(
      principal: Input.coerce_required(principal, Input::Principal).to_protobuf,
      resource: Input.coerce_required(resource, Input::ResourceQuery).to_protobuf,
      action: action,
      aux_data: Input.coerce_optional(aux_data, Input::AuxData)&.to_protobuf,
      include_meta: ,
      request_id: request_id
    )

    response = perform_request(@cerbos_service, :plan_resources, request)

    Output::PlanResources.from_protobuf(response)
  end
end

#server_infoOutput::ServerInfo

Retrieve information about the Cerbos PDP server.

Returns:


160
161
162
163
164
165
166
167
168
# File 'lib/cerbos/client.rb', line 160

def server_info
  handle_errors do
    request = Protobuf::Cerbos::Request::V1::ServerInfoRequest.new

    response = perform_request(@cerbos_service, :server_info, request)

    Output::ServerInfo.from_protobuf(response)
  end
end