Class: SDM::Client

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

Overview

Client bundles all the services together and initializes them.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_access_key, api_secret_key, host: "api.strongdm.com:443", insecure: false) ⇒ Client

Creates a new strongDM API client.

Raises:

  • (TypeError)


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/strongdm.rb', line 31

def initialize(api_access_key, api_secret_key, host: "api.strongdm.com:443", insecure: false)
  raise TypeError, "client access key must be a string" unless api_access_key.kind_of?(String)
  raise TypeError, "client secret key must be a string" unless api_secret_key.kind_of?(String)
  raise TypeError, "client host must be a string" unless host.kind_of?(String)
  @api_access_key = api_access_key.strip
  @api_secret_key = Base64.strict_decode64(api_secret_key.strip)
  @max_retries = DEFAULT_MAX_RETRIES
  @base_retry_delay = DEFAULT_BASE_RETRY_DELAY
  @max_retry_delay = DEFAULT_MAX_RETRY_DELAY
  @account_attachments = AccountAttachments.new(host, insecure, self)
  @account_grants = AccountGrants.new(host, insecure, self)
  @accounts = Accounts.new(host, insecure, self)
  @control_panel = ControlPanel.new(host, insecure, self)
  @nodes = Nodes.new(host, insecure, self)
  @resources = Resources.new(host, insecure, self)
  @role_attachments = RoleAttachments.new(host, insecure, self)
  @role_grants = RoleGrants.new(host, insecure, self)
  @roles = Roles.new(host, insecure, self)
  @secret_stores = SecretStores.new(host, insecure, self)
  @_test_options = Hash.new
end

Instance Attribute Details

#_test_optionsObject (readonly)

Returns the value of attribute _test_options.



132
133
134
# File 'lib/strongdm.rb', line 132

def _test_options
  @_test_options
end

#account_attachmentsObject (readonly)

AccountAttachments assign an account to a role or composite role.



99
100
101
# File 'lib/strongdm.rb', line 99

def 
  @account_attachments
end

#account_grantsObject (readonly)

AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.



101
102
103
# File 'lib/strongdm.rb', line 101

def 
  @account_grants
end

#accountsObject (readonly)

Accounts are users that have access to strongDM. There are two types of accounts:

  1. Users: humans who are authenticated through username and password or SSO.

  2. **Service Accounts:** machines that are authenticated using a service token.



105
106
107
# File 'lib/strongdm.rb', line 105

def accounts
  @accounts
end

#api_access_keyObject (readonly)

API authentication token (read-only).



97
98
99
# File 'lib/strongdm.rb', line 97

def api_access_key
  @api_access_key
end

#base_retry_delayObject (readonly)

Returns the value of attribute base_retry_delay.



93
94
95
# File 'lib/strongdm.rb', line 93

def base_retry_delay
  @base_retry_delay
end

#control_panelObject (readonly)

ControlPanel contains all administrative controls.



107
108
109
# File 'lib/strongdm.rb', line 107

def control_panel
  @control_panel
end

#max_retriesObject (readonly)

Returns the value of attribute max_retries.



92
93
94
# File 'lib/strongdm.rb', line 92

def max_retries
  @max_retries
end

#max_retry_delayObject (readonly)

Returns the value of attribute max_retry_delay.



94
95
96
# File 'lib/strongdm.rb', line 94

def max_retry_delay
  @max_retry_delay
end

#nodesObject (readonly)

Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:

  • Gateways are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.

  • Relays are used to extend the strongDM network into segmented subnets. They provide access to databases and servers but do not listen for incoming connections.



111
112
113
# File 'lib/strongdm.rb', line 111

def nodes
  @nodes
end

#resourcesObject (readonly)

Returns the value of attribute resources.



113
114
115
# File 'lib/strongdm.rb', line 113

def resources
  @resources
end

#role_attachmentsObject (readonly)

RoleAttachments represent relationships between composite roles and the roles that make up those composite roles. When a composite role is attached to another role, the permissions granted to members of the composite role are augmented to include the permissions granted to members of the attached role.



118
119
120
# File 'lib/strongdm.rb', line 118

def role_attachments
  @role_attachments
end

#role_grantsObject (readonly)

RoleGrants represent relationships between composite roles and the roles that make up those composite roles. When a composite role is attached to another role, the permissions granted to members of the composite role are augmented to include the permissions granted to members of the attached role.



123
124
125
# File 'lib/strongdm.rb', line 123

def role_grants
  @role_grants
end

#rolesObject (readonly)

Roles are tools for controlling user access to resources. Each Role holds a list of resources which they grant access to. Composite roles are a special type of Role which have no resource associations of their own, but instead grant access to the combined resources associated with a set of child roles. Each user can be a member of one Role or composite role.



129
130
131
# File 'lib/strongdm.rb', line 129

def roles
  @roles
end

#secret_storesObject (readonly)

SecretStores are servers where resource secrets (passwords, keys) are stored.



131
132
133
# File 'lib/strongdm.rb', line 131

def secret_stores
  @secret_stores
end

Instance Method Details

#get_metadata(method_name, req) ⇒ Object



53
54
55
# File 'lib/strongdm.rb', line 53

def (method_name, req)
  return { 'x-sdm-authentication': @api_access_key, 'x-sdm-signature': self.sign(method_name, req.to_proto) }
end

#jitterSleep(iter) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/strongdm.rb', line 73

def jitterSleep(iter)
  dur_max = @base_retry_delay * 2 ** iter
  if (dur_max > @max_retry_delay)
    dur_max = @max_retry_delay
  end
  dur = rand() * dur_max
  sleep(dur)
end

#shouldRetry(iter, err) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/strongdm.rb', line 82

def shouldRetry(iter, err)
  if (iter >= @max_retries - 1)
    return false
  end
  if not err.is_a? GRPC::BadStatus
    return true
  end
  return err.code() == 13
end

#sign(method_name, msg_bytes) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/strongdm.rb', line 57

def sign(method_name, msg_bytes)
  current_utc_date = Time.now.utc
  date = sprintf("%04d-%02d-%02d", current_utc_date.year, current_utc_date.month, current_utc_date.day)

  signing_key = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, @api_secret_key, date)
  signing_key = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, signing_key, "sdm_api_v1")

  sha_req = Digest::SHA256.new
  sha_req << method_name
  sha_req << "\n"
  sha_req << msg_bytes
  request_hash = sha_req.digest

  return Base64.strict_encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, signing_key, request_hash))
end