strongdm.client

  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# Code generated by protogen. DO NOT EDIT.
 17
 18import base64
 19import copy
 20import datetime
 21import grpc
 22import hashlib
 23import hmac
 24import random
 25import time
 26from . import errors
 27from . import plumbing
 28from . import svc
 29
 30# These defaults are taken from AWS. Customization of these values
 31# is a future step in the API.
 32DEFAULT_BASE_RETRY_DELAY = 1  # 1 second
 33DEFAULT_MAX_RETRY_DELAY = 120  # 120 seconds
 34DEFAULT_RETRY_FACTOR = 1.6
 35DEFAULT_RETRY_JITTER = 0.2
 36API_VERSION = '2025-04-14'
 37USER_AGENT = 'strongdm-sdk-python/15.1.0'
 38
 39
 40class Client:
 41    '''Client interacts with the strongDM API.'''
 42    def __init__(self,
 43                 api_access_key,
 44                 api_secret,
 45                 host='app.strongdm.com:443',
 46                 insecure=False,
 47                 retry_rate_limit_errors=True,
 48                 page_limit=0):
 49        '''
 50        Create a new Client.
 51
 52        - api_access_key: the access key to authenticate with strongDM
 53        - api_secret: the secret key to authenticate with strongDM
 54        '''
 55        self.api_access_key = api_access_key.strip()
 56        self.api_secret = base64.b64decode(api_secret.strip())
 57        self.base_retry_delay = DEFAULT_BASE_RETRY_DELAY
 58        self.max_retry_delay = DEFAULT_MAX_RETRY_DELAY
 59        self.retry_factor = DEFAULT_RETRY_FACTOR
 60        self.retry_jitter = DEFAULT_RETRY_JITTER
 61        self.retry_rate_limit_errors = retry_rate_limit_errors
 62        self.snapshot_datetime = None
 63        self.page_limit = page_limit
 64
 65        try:
 66            if insecure:
 67                channel = grpc.insecure_channel(host)
 68            else:
 69                creds = grpc.ssl_channel_credentials()
 70                channel = grpc.secure_channel(host, creds)
 71        except Exception as e:
 72            raise plumbing.convert_error_to_porcelain(e) from e
 73        self.channel = channel
 74        self.access_requests = svc.AccessRequests(channel, self)
 75        '''
 76         AccessRequests are requests for access to a resource that may match a Workflow.
 77
 78        See `strongdm.svc.AccessRequests`.
 79        '''
 80        self.access_request_events_history = svc.AccessRequestEventsHistory(
 81            channel, self)
 82        '''
 83         AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.
 84
 85        See `strongdm.svc.AccessRequestEventsHistory`.
 86        '''
 87        self.access_requests_history = svc.AccessRequestsHistory(channel, self)
 88        '''
 89         AccessRequestsHistory provides records of all changes to the state of an AccessRequest.
 90
 91        See `strongdm.svc.AccessRequestsHistory`.
 92        '''
 93        self.account_attachments = svc.AccountAttachments(channel, self)
 94        '''
 95         AccountAttachments assign an account to a role.
 96
 97        See `strongdm.svc.AccountAttachments`.
 98        '''
 99        self.account_attachments_history = svc.AccountAttachmentsHistory(
100            channel, self)
101        '''
102         AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
103
104        See `strongdm.svc.AccountAttachmentsHistory`.
105        '''
106        self.account_grants = svc.AccountGrants(channel, self)
107        '''
108         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
109
110        See `strongdm.svc.AccountGrants`.
111        '''
112        self.account_grants_history = svc.AccountGrantsHistory(channel, self)
113        '''
114         AccountGrantsHistory records all changes to the state of an AccountGrant.
115
116        See `strongdm.svc.AccountGrantsHistory`.
117        '''
118        self.account_permissions = svc.AccountPermissions(channel, self)
119        '''
120         AccountPermissions records the granular permissions accounts have, allowing them to execute
121         relevant commands via StrongDM's APIs.
122
123        See `strongdm.svc.AccountPermissions`.
124        '''
125        self.account_resources = svc.AccountResources(channel, self)
126        '''
127         AccountResources enumerates the resources to which accounts have access.
128         The AccountResources service is read-only.
129
130        See `strongdm.svc.AccountResources`.
131        '''
132        self.account_resources_history = svc.AccountResourcesHistory(
133            channel, self)
134        '''
135         AccountResourcesHistory records all changes to the state of a AccountResource.
136
137        See `strongdm.svc.AccountResourcesHistory`.
138        '''
139        self.accounts = svc.Accounts(channel, self)
140        '''
141         Accounts are users that have access to strongDM. There are two types of accounts:
142         1. **Users:** humans who are authenticated through username and password or SSO.
143         2. **Service Accounts:** machines that are authenticated using a service token.
144         3. **Tokens** are access keys with permissions that can be used for authentication.
145
146        See `strongdm.svc.Accounts`.
147        '''
148        self.accounts_history = svc.AccountsHistory(channel, self)
149        '''
150         AccountsHistory records all changes to the state of an Account.
151
152        See `strongdm.svc.AccountsHistory`.
153        '''
154        self.activities = svc.Activities(channel, self)
155        '''
156         An Activity is a record of an action taken against a strongDM deployment, e.g.
157         a user creation, resource deletion, sso configuration change, etc. The Activities
158         service is read-only.
159
160        See `strongdm.svc.Activities`.
161        '''
162        self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
163            channel, self)
164        '''
165         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
166
167        See `strongdm.svc.ApprovalWorkflowApprovers`.
168        '''
169        self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory(
170            channel, self)
171        '''
172         ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.
173
174        See `strongdm.svc.ApprovalWorkflowApproversHistory`.
175        '''
176        self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self)
177        '''
178         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
179
180        See `strongdm.svc.ApprovalWorkflowSteps`.
181        '''
182        self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory(
183            channel, self)
184        '''
185         ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.
186
187        See `strongdm.svc.ApprovalWorkflowStepsHistory`.
188        '''
189        self.approval_workflows = svc.ApprovalWorkflows(channel, self)
190        '''
191         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
192         approvers and be approved or denied.
193
194        See `strongdm.svc.ApprovalWorkflows`.
195        '''
196        self.approval_workflows_history = svc.ApprovalWorkflowsHistory(
197            channel, self)
198        '''
199         ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.
200
201        See `strongdm.svc.ApprovalWorkflowsHistory`.
202        '''
203        self.control_panel = svc.ControlPanel(channel, self)
204        '''
205         ControlPanel contains all administrative controls.
206
207        See `strongdm.svc.ControlPanel`.
208        '''
209        self.health_checks = svc.HealthChecks(channel, self)
210        '''
211         HealthChecks lists the last healthcheck between each node and resource.
212         Note the unconventional capitalization here is to prevent having a collision with GRPC
213
214        See `strongdm.svc.HealthChecks`.
215        '''
216        self.identity_aliases = svc.IdentityAliases(channel, self)
217        '''
218         IdentityAliases assign an alias to an account within an IdentitySet.
219         The alias is used as the username when connecting to a identity supported resource.
220
221        See `strongdm.svc.IdentityAliases`.
222        '''
223        self.identity_aliases_history = svc.IdentityAliasesHistory(
224            channel, self)
225        '''
226         IdentityAliasesHistory records all changes to the state of a IdentityAlias.
227
228        See `strongdm.svc.IdentityAliasesHistory`.
229        '''
230        self.identity_sets = svc.IdentitySets(channel, self)
231        '''
232         A IdentitySet is a named grouping of Identity Aliases for Accounts.
233         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
234
235        See `strongdm.svc.IdentitySets`.
236        '''
237        self.identity_sets_history = svc.IdentitySetsHistory(channel, self)
238        '''
239         IdentitySetsHistory records all changes to the state of a IdentitySet.
240
241        See `strongdm.svc.IdentitySetsHistory`.
242        '''
243        self.managed_secrets = svc.ManagedSecrets(channel, self)
244        '''
245         ManagedSecret is a private vertical for creating, reading, updating,
246         deleting, listing and rotating the managed secrets in the secrets engines as
247         an authenticated user.
248
249        See `strongdm.svc.ManagedSecrets`.
250        '''
251        self.nodes = svc.Nodes(channel, self)
252        '''
253         Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:
254         - **Gateways** are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.
255         - **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.
256
257        See `strongdm.svc.Nodes`.
258        '''
259        self.nodes_history = svc.NodesHistory(channel, self)
260        '''
261         NodesHistory records all changes to the state of a Node.
262
263        See `strongdm.svc.NodesHistory`.
264        '''
265        self.organization_history = svc.OrganizationHistory(channel, self)
266        '''
267         OrganizationHistory records all changes to the state of an Organization.
268
269        See `strongdm.svc.OrganizationHistory`.
270        '''
271        self.peering_group_nodes = svc.PeeringGroupNodes(channel, self)
272        '''
273         PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.
274
275        See `strongdm.svc.PeeringGroupNodes`.
276        '''
277        self.peering_group_peers = svc.PeeringGroupPeers(channel, self)
278        '''
279         PeeringGroupPeers provides the building blocks necessary to link two peering groups.
280
281        See `strongdm.svc.PeeringGroupPeers`.
282        '''
283        self.peering_group_resources = svc.PeeringGroupResources(channel, self)
284        '''
285         PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.
286
287        See `strongdm.svc.PeeringGroupResources`.
288        '''
289        self.peering_groups = svc.PeeringGroups(channel, self)
290        '''
291         PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.
292
293        See `strongdm.svc.PeeringGroups`.
294        '''
295        self.policies = svc.Policies(channel, self)
296        '''
297         Policies are the collection of one or more statements that enforce fine-grained access
298         control for the users of an organization.
299
300        See `strongdm.svc.Policies`.
301        '''
302        self.policies_history = svc.PoliciesHistory(channel, self)
303        '''
304         PoliciesHistory records all changes to the state of a Policy.
305
306        See `strongdm.svc.PoliciesHistory`.
307        '''
308        self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self)
309        '''
310         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
311         The proxies within a cluster share the same key. One cluster can have
312         multiple keys in order to facilitate key rotation.
313
314        See `strongdm.svc.ProxyClusterKeys`.
315        '''
316        self.queries = svc.Queries(channel, self)
317        '''
318         A Query is a record of a single client request to a resource, such as a SQL query.
319         Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries.
320         The Queries service is read-only.
321
322        See `strongdm.svc.Queries`.
323        '''
324        self.remote_identities = svc.RemoteIdentities(channel, self)
325        '''
326         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
327
328        See `strongdm.svc.RemoteIdentities`.
329        '''
330        self.remote_identities_history = svc.RemoteIdentitiesHistory(
331            channel, self)
332        '''
333         RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
334
335        See `strongdm.svc.RemoteIdentitiesHistory`.
336        '''
337        self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self)
338        '''
339         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
340         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
341
342        See `strongdm.svc.RemoteIdentityGroups`.
343        '''
344        self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory(
345            channel, self)
346        '''
347         RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
348
349        See `strongdm.svc.RemoteIdentityGroupsHistory`.
350        '''
351        self.replays = svc.Replays(channel, self)
352        '''
353         A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session
354         (otherwise referred to as a query). The Replays service is read-only.
355
356        See `strongdm.svc.Replays`.
357        '''
358        self.resources = svc.Resources(channel, self)
359        '''
360         Resources are databases, servers, clusters, websites, or clouds that strongDM
361         delegates access to.
362
363        See `strongdm.svc.Resources`.
364        '''
365        self.resources_history = svc.ResourcesHistory(channel, self)
366        '''
367         ResourcesHistory records all changes to the state of a Resource.
368
369        See `strongdm.svc.ResourcesHistory`.
370        '''
371        self.role_resources = svc.RoleResources(channel, self)
372        '''
373         RoleResources enumerates the resources to which roles have access.
374         The RoleResources service is read-only.
375
376        See `strongdm.svc.RoleResources`.
377        '''
378        self.role_resources_history = svc.RoleResourcesHistory(channel, self)
379        '''
380         RoleResourcesHistory records all changes to the state of a RoleResource.
381
382        See `strongdm.svc.RoleResourcesHistory`.
383        '''
384        self.roles = svc.Roles(channel, self)
385        '''
386         A Role has a list of access rules which determine which Resources the members
387         of the Role have access to. An Account can be a member of multiple Roles via
388         AccountAttachments.
389
390        See `strongdm.svc.Roles`.
391        '''
392        self.roles_history = svc.RolesHistory(channel, self)
393        '''
394         RolesHistory records all changes to the state of a Role.
395
396        See `strongdm.svc.RolesHistory`.
397        '''
398        self.secret_stores = svc.SecretStores(channel, self)
399        '''
400         SecretStores are servers where resource secrets (passwords, keys) are stored.
401
402        See `strongdm.svc.SecretStores`.
403        '''
404        self.secret_engines = svc.SecretEngines(channel, self)
405        '''
406
407
408        See `strongdm.svc.SecretEngines`.
409        '''
410        self.secret_store_healths = svc.SecretStoreHealths(channel, self)
411        '''
412         SecretStoreHealths exposes health states for secret stores.
413
414        See `strongdm.svc.SecretStoreHealths`.
415        '''
416        self.secret_stores_history = svc.SecretStoresHistory(channel, self)
417        '''
418         SecretStoresHistory records all changes to the state of a SecretStore.
419
420        See `strongdm.svc.SecretStoresHistory`.
421        '''
422        self.workflow_approvers = svc.WorkflowApprovers(channel, self)
423        '''
424         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
425
426        See `strongdm.svc.WorkflowApprovers`.
427        '''
428        self.workflow_approvers_history = svc.WorkflowApproversHistory(
429            channel, self)
430        '''
431         WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.
432
433        See `strongdm.svc.WorkflowApproversHistory`.
434        '''
435        self.workflow_roles = svc.WorkflowRoles(channel, self)
436        '''
437         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
438         to request access to a resource via the workflow.
439
440        See `strongdm.svc.WorkflowRoles`.
441        '''
442        self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self)
443        '''
444         WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole
445
446        See `strongdm.svc.WorkflowRolesHistory`.
447        '''
448        self.workflows = svc.Workflows(channel, self)
449        '''
450         Workflows are the collection of rules that define the resources to which access can be requested,
451         the users that can request that access, and the mechanism for approving those requests which can either
452         be automatic approval or a set of users authorized to approve the requests.
453
454        See `strongdm.svc.Workflows`.
455        '''
456        self.workflows_history = svc.WorkflowsHistory(channel, self)
457        '''
458         WorkflowsHistory provides records of all changes to the state of a Workflow.
459
460        See `strongdm.svc.WorkflowsHistory`.
461        '''
462
463    def close(self):
464        '''Closes this Client and releases all resources held by it.
465
466        Closing the Client will immediately terminate all RPCs active with the
467        Client and it is not valid to invoke new RPCs with the Client.
468
469        This method is idempotent.
470        '''
471        self.channel.close()
472
473    def get_metadata(self, method_name, req):
474        return [
475            ('x-sdm-authentication', self.api_access_key),
476            ('x-sdm-signature', self.sign(method_name,
477                                          req.SerializeToString())),
478            ('x-sdm-api-version', API_VERSION),
479            ('x-sdm-user-agent', USER_AGENT),
480        ]
481
482    def sign(self, method_name, request_bytes):
483        def hmac_digest(key, msg_byte_string):
484            return hmac.new(key, msg=msg_byte_string,
485                            digestmod=hashlib.sha256).digest()
486
487        current_utc_date = datetime.datetime.now(
488            datetime.timezone.utc).strftime('%Y-%m-%d')
489        signing_key = hmac_digest(self.api_secret, current_utc_date.encode())
490        signing_key = hmac_digest(signing_key, b'sdm_api_v1')
491
492        hash = hashlib.sha256()
493
494        hash.update(method_name.encode())
495        hash.update(b'\n')
496        hash.update(request_bytes)
497
498        return base64.b64encode(hmac_digest(signing_key, hash.digest()))
499
500    def exponentialBackoff(self, retries, deadline=None):
501        def applyDeadline(delay, deadline):
502            if deadline is None:
503                return delay
504            remaining = deadline - time.time()
505            if remaining < 0:
506                return 0
507            return min(delay, remaining)
508
509        if retries == 0:
510            return applyDeadline(self.base_retry_delay, deadline)
511
512        backoff, max_delay = self.base_retry_delay, self.max_retry_delay
513        while backoff < max_delay and retries > 0:
514            backoff *= self.retry_factor
515            retries -= 1
516
517        if backoff > max_delay:
518            backoff = max_delay
519
520        # Randomize backoff delays so that if a cluster of requests start at
521        # the same time, they won't operate in lockstep.
522        backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1)
523        if backoff < 0:
524            return 0
525
526        return applyDeadline(backoff, deadline)
527
528    def shouldRetry(self, retries, err, deadline=None):
529        # Check if we've passed the deadline
530        if deadline is not None and time.time() >= deadline:
531            return False
532
533        if not isinstance(err, grpc.RpcError):
534            return False
535
536        if self.retry_rate_limit_errors and err.code(
537        ) == grpc.StatusCode.RESOURCE_EXHAUSTED:
538            return True
539
540        return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL
541                                 or err.code() == grpc.StatusCode.UNAVAILABLE)
542
543    def snapshot_at(self, snapshot_datetime):
544        '''
545        Constructs a read-only client that will provide historical data from the provided timestamp.
546
547        See `SnapshotClient`.
548        '''
549        client = copy.copy(self)
550        client.snapshot_datetime = snapshot_datetime
551        client.access_requests = svc.AccessRequests(client.channel, client)
552        client.account_attachments = svc.AccountAttachments(
553            client.channel, client)
554        client.account_grants = svc.AccountGrants(client.channel, client)
555        client.account_permissions = svc.AccountPermissions(
556            client.channel, client)
557        client.account_resources = svc.AccountResources(client.channel, client)
558        client.accounts = svc.Accounts(client.channel, client)
559        client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
560            client.channel, client)
561        client.approval_workflow_steps = svc.ApprovalWorkflowSteps(
562            client.channel, client)
563        client.approval_workflows = svc.ApprovalWorkflows(
564            client.channel, client)
565        client.identity_aliases = svc.IdentityAliases(client.channel, client)
566        client.identity_sets = svc.IdentitySets(client.channel, client)
567        client.nodes = svc.Nodes(client.channel, client)
568        client.policies = svc.Policies(client.channel, client)
569        client.proxy_cluster_keys = svc.ProxyClusterKeys(
570            client.channel, client)
571        client.remote_identities = svc.RemoteIdentities(client.channel, client)
572        client.remote_identity_groups = svc.RemoteIdentityGroups(
573            client.channel, client)
574        client.resources = svc.Resources(client.channel, client)
575        client.role_resources = svc.RoleResources(client.channel, client)
576        client.roles = svc.Roles(client.channel, client)
577        client.secret_stores = svc.SecretStores(client.channel, client)
578        client.workflow_approvers = svc.WorkflowApprovers(
579            client.channel, client)
580        client.workflow_roles = svc.WorkflowRoles(client.channel, client)
581        client.workflows = svc.Workflows(client.channel, client)
582        return SnapshotClient(client)
583
584
585class SnapshotClient:
586    '''SnapshotClient exposes methods to query historical records at a provided timestamp.'''
587    def __init__(self, client):
588        self.access_requests = svc.SnapshotAccessRequests(
589            client.access_requests)
590        '''
591         AccessRequests are requests for access to a resource that may match a Workflow.
592
593        See `strongdm.svc.SnapshotAccessRequests`.
594        '''
595        self.account_attachments = svc.SnapshotAccountAttachments(
596            client.account_attachments)
597        '''
598         AccountAttachments assign an account to a role.
599
600        See `strongdm.svc.SnapshotAccountAttachments`.
601        '''
602        self.account_grants = svc.SnapshotAccountGrants(client.account_grants)
603        '''
604         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
605
606        See `strongdm.svc.SnapshotAccountGrants`.
607        '''
608        self.account_permissions = svc.SnapshotAccountPermissions(
609            client.account_permissions)
610        '''
611         AccountPermissions records the granular permissions accounts have, allowing them to execute
612         relevant commands via StrongDM's APIs.
613
614        See `strongdm.svc.SnapshotAccountPermissions`.
615        '''
616        self.account_resources = svc.SnapshotAccountResources(
617            client.account_resources)
618        '''
619         AccountResources enumerates the resources to which accounts have access.
620         The AccountResources service is read-only.
621
622        See `strongdm.svc.SnapshotAccountResources`.
623        '''
624        self.accounts = svc.SnapshotAccounts(client.accounts)
625        '''
626         Accounts are users that have access to strongDM. There are two types of accounts:
627         1. **Users:** humans who are authenticated through username and password or SSO.
628         2. **Service Accounts:** machines that are authenticated using a service token.
629         3. **Tokens** are access keys with permissions that can be used for authentication.
630
631        See `strongdm.svc.SnapshotAccounts`.
632        '''
633        self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers(
634            client.approval_workflow_approvers)
635        '''
636         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
637
638        See `strongdm.svc.SnapshotApprovalWorkflowApprovers`.
639        '''
640        self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps(
641            client.approval_workflow_steps)
642        '''
643         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
644
645        See `strongdm.svc.SnapshotApprovalWorkflowSteps`.
646        '''
647        self.approval_workflows = svc.SnapshotApprovalWorkflows(
648            client.approval_workflows)
649        '''
650         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
651         approvers and be approved or denied.
652
653        See `strongdm.svc.SnapshotApprovalWorkflows`.
654        '''
655        self.identity_aliases = svc.SnapshotIdentityAliases(
656            client.identity_aliases)
657        '''
658         IdentityAliases assign an alias to an account within an IdentitySet.
659         The alias is used as the username when connecting to a identity supported resource.
660
661        See `strongdm.svc.SnapshotIdentityAliases`.
662        '''
663        self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets)
664        '''
665         A IdentitySet is a named grouping of Identity Aliases for Accounts.
666         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
667
668        See `strongdm.svc.SnapshotIdentitySets`.
669        '''
670        self.nodes = svc.SnapshotNodes(client.nodes)
671        '''
672         Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:
673         - **Gateways** are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.
674         - **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.
675
676        See `strongdm.svc.SnapshotNodes`.
677        '''
678        self.policies = svc.SnapshotPolicies(client.policies)
679        '''
680         Policies are the collection of one or more statements that enforce fine-grained access
681         control for the users of an organization.
682
683        See `strongdm.svc.SnapshotPolicies`.
684        '''
685        self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys(
686            client.proxy_cluster_keys)
687        '''
688         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
689         The proxies within a cluster share the same key. One cluster can have
690         multiple keys in order to facilitate key rotation.
691
692        See `strongdm.svc.SnapshotProxyClusterKeys`.
693        '''
694        self.remote_identities = svc.SnapshotRemoteIdentities(
695            client.remote_identities)
696        '''
697         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
698
699        See `strongdm.svc.SnapshotRemoteIdentities`.
700        '''
701        self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups(
702            client.remote_identity_groups)
703        '''
704         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
705         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
706
707        See `strongdm.svc.SnapshotRemoteIdentityGroups`.
708        '''
709        self.resources = svc.SnapshotResources(client.resources)
710        '''
711         Resources are databases, servers, clusters, websites, or clouds that strongDM
712         delegates access to.
713
714        See `strongdm.svc.SnapshotResources`.
715        '''
716        self.role_resources = svc.SnapshotRoleResources(client.role_resources)
717        '''
718         RoleResources enumerates the resources to which roles have access.
719         The RoleResources service is read-only.
720
721        See `strongdm.svc.SnapshotRoleResources`.
722        '''
723        self.roles = svc.SnapshotRoles(client.roles)
724        '''
725         A Role has a list of access rules which determine which Resources the members
726         of the Role have access to. An Account can be a member of multiple Roles via
727         AccountAttachments.
728
729        See `strongdm.svc.SnapshotRoles`.
730        '''
731        self.secret_stores = svc.SnapshotSecretStores(client.secret_stores)
732        '''
733         SecretStores are servers where resource secrets (passwords, keys) are stored.
734
735        See `strongdm.svc.SnapshotSecretStores`.
736        '''
737        self.workflow_approvers = svc.SnapshotWorkflowApprovers(
738            client.workflow_approvers)
739        '''
740         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
741
742        See `strongdm.svc.SnapshotWorkflowApprovers`.
743        '''
744        self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles)
745        '''
746         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
747         to request access to a resource via the workflow.
748
749        See `strongdm.svc.SnapshotWorkflowRoles`.
750        '''
751        self.workflows = svc.SnapshotWorkflows(client.workflows)
752        '''
753         Workflows are the collection of rules that define the resources to which access can be requested,
754         the users that can request that access, and the mechanism for approving those requests which can either
755         be automatic approval or a set of users authorized to approve the requests.
756
757        See `strongdm.svc.SnapshotWorkflows`.
758        '''
class Client:
 41class Client:
 42    '''Client interacts with the strongDM API.'''
 43    def __init__(self,
 44                 api_access_key,
 45                 api_secret,
 46                 host='app.strongdm.com:443',
 47                 insecure=False,
 48                 retry_rate_limit_errors=True,
 49                 page_limit=0):
 50        '''
 51        Create a new Client.
 52
 53        - api_access_key: the access key to authenticate with strongDM
 54        - api_secret: the secret key to authenticate with strongDM
 55        '''
 56        self.api_access_key = api_access_key.strip()
 57        self.api_secret = base64.b64decode(api_secret.strip())
 58        self.base_retry_delay = DEFAULT_BASE_RETRY_DELAY
 59        self.max_retry_delay = DEFAULT_MAX_RETRY_DELAY
 60        self.retry_factor = DEFAULT_RETRY_FACTOR
 61        self.retry_jitter = DEFAULT_RETRY_JITTER
 62        self.retry_rate_limit_errors = retry_rate_limit_errors
 63        self.snapshot_datetime = None
 64        self.page_limit = page_limit
 65
 66        try:
 67            if insecure:
 68                channel = grpc.insecure_channel(host)
 69            else:
 70                creds = grpc.ssl_channel_credentials()
 71                channel = grpc.secure_channel(host, creds)
 72        except Exception as e:
 73            raise plumbing.convert_error_to_porcelain(e) from e
 74        self.channel = channel
 75        self.access_requests = svc.AccessRequests(channel, self)
 76        '''
 77         AccessRequests are requests for access to a resource that may match a Workflow.
 78
 79        See `strongdm.svc.AccessRequests`.
 80        '''
 81        self.access_request_events_history = svc.AccessRequestEventsHistory(
 82            channel, self)
 83        '''
 84         AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.
 85
 86        See `strongdm.svc.AccessRequestEventsHistory`.
 87        '''
 88        self.access_requests_history = svc.AccessRequestsHistory(channel, self)
 89        '''
 90         AccessRequestsHistory provides records of all changes to the state of an AccessRequest.
 91
 92        See `strongdm.svc.AccessRequestsHistory`.
 93        '''
 94        self.account_attachments = svc.AccountAttachments(channel, self)
 95        '''
 96         AccountAttachments assign an account to a role.
 97
 98        See `strongdm.svc.AccountAttachments`.
 99        '''
100        self.account_attachments_history = svc.AccountAttachmentsHistory(
101            channel, self)
102        '''
103         AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
104
105        See `strongdm.svc.AccountAttachmentsHistory`.
106        '''
107        self.account_grants = svc.AccountGrants(channel, self)
108        '''
109         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
110
111        See `strongdm.svc.AccountGrants`.
112        '''
113        self.account_grants_history = svc.AccountGrantsHistory(channel, self)
114        '''
115         AccountGrantsHistory records all changes to the state of an AccountGrant.
116
117        See `strongdm.svc.AccountGrantsHistory`.
118        '''
119        self.account_permissions = svc.AccountPermissions(channel, self)
120        '''
121         AccountPermissions records the granular permissions accounts have, allowing them to execute
122         relevant commands via StrongDM's APIs.
123
124        See `strongdm.svc.AccountPermissions`.
125        '''
126        self.account_resources = svc.AccountResources(channel, self)
127        '''
128         AccountResources enumerates the resources to which accounts have access.
129         The AccountResources service is read-only.
130
131        See `strongdm.svc.AccountResources`.
132        '''
133        self.account_resources_history = svc.AccountResourcesHistory(
134            channel, self)
135        '''
136         AccountResourcesHistory records all changes to the state of a AccountResource.
137
138        See `strongdm.svc.AccountResourcesHistory`.
139        '''
140        self.accounts = svc.Accounts(channel, self)
141        '''
142         Accounts are users that have access to strongDM. There are two types of accounts:
143         1. **Users:** humans who are authenticated through username and password or SSO.
144         2. **Service Accounts:** machines that are authenticated using a service token.
145         3. **Tokens** are access keys with permissions that can be used for authentication.
146
147        See `strongdm.svc.Accounts`.
148        '''
149        self.accounts_history = svc.AccountsHistory(channel, self)
150        '''
151         AccountsHistory records all changes to the state of an Account.
152
153        See `strongdm.svc.AccountsHistory`.
154        '''
155        self.activities = svc.Activities(channel, self)
156        '''
157         An Activity is a record of an action taken against a strongDM deployment, e.g.
158         a user creation, resource deletion, sso configuration change, etc. The Activities
159         service is read-only.
160
161        See `strongdm.svc.Activities`.
162        '''
163        self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
164            channel, self)
165        '''
166         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
167
168        See `strongdm.svc.ApprovalWorkflowApprovers`.
169        '''
170        self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory(
171            channel, self)
172        '''
173         ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.
174
175        See `strongdm.svc.ApprovalWorkflowApproversHistory`.
176        '''
177        self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self)
178        '''
179         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
180
181        See `strongdm.svc.ApprovalWorkflowSteps`.
182        '''
183        self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory(
184            channel, self)
185        '''
186         ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.
187
188        See `strongdm.svc.ApprovalWorkflowStepsHistory`.
189        '''
190        self.approval_workflows = svc.ApprovalWorkflows(channel, self)
191        '''
192         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
193         approvers and be approved or denied.
194
195        See `strongdm.svc.ApprovalWorkflows`.
196        '''
197        self.approval_workflows_history = svc.ApprovalWorkflowsHistory(
198            channel, self)
199        '''
200         ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.
201
202        See `strongdm.svc.ApprovalWorkflowsHistory`.
203        '''
204        self.control_panel = svc.ControlPanel(channel, self)
205        '''
206         ControlPanel contains all administrative controls.
207
208        See `strongdm.svc.ControlPanel`.
209        '''
210        self.health_checks = svc.HealthChecks(channel, self)
211        '''
212         HealthChecks lists the last healthcheck between each node and resource.
213         Note the unconventional capitalization here is to prevent having a collision with GRPC
214
215        See `strongdm.svc.HealthChecks`.
216        '''
217        self.identity_aliases = svc.IdentityAliases(channel, self)
218        '''
219         IdentityAliases assign an alias to an account within an IdentitySet.
220         The alias is used as the username when connecting to a identity supported resource.
221
222        See `strongdm.svc.IdentityAliases`.
223        '''
224        self.identity_aliases_history = svc.IdentityAliasesHistory(
225            channel, self)
226        '''
227         IdentityAliasesHistory records all changes to the state of a IdentityAlias.
228
229        See `strongdm.svc.IdentityAliasesHistory`.
230        '''
231        self.identity_sets = svc.IdentitySets(channel, self)
232        '''
233         A IdentitySet is a named grouping of Identity Aliases for Accounts.
234         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
235
236        See `strongdm.svc.IdentitySets`.
237        '''
238        self.identity_sets_history = svc.IdentitySetsHistory(channel, self)
239        '''
240         IdentitySetsHistory records all changes to the state of a IdentitySet.
241
242        See `strongdm.svc.IdentitySetsHistory`.
243        '''
244        self.managed_secrets = svc.ManagedSecrets(channel, self)
245        '''
246         ManagedSecret is a private vertical for creating, reading, updating,
247         deleting, listing and rotating the managed secrets in the secrets engines as
248         an authenticated user.
249
250        See `strongdm.svc.ManagedSecrets`.
251        '''
252        self.nodes = svc.Nodes(channel, self)
253        '''
254         Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:
255         - **Gateways** are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.
256         - **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.
257
258        See `strongdm.svc.Nodes`.
259        '''
260        self.nodes_history = svc.NodesHistory(channel, self)
261        '''
262         NodesHistory records all changes to the state of a Node.
263
264        See `strongdm.svc.NodesHistory`.
265        '''
266        self.organization_history = svc.OrganizationHistory(channel, self)
267        '''
268         OrganizationHistory records all changes to the state of an Organization.
269
270        See `strongdm.svc.OrganizationHistory`.
271        '''
272        self.peering_group_nodes = svc.PeeringGroupNodes(channel, self)
273        '''
274         PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.
275
276        See `strongdm.svc.PeeringGroupNodes`.
277        '''
278        self.peering_group_peers = svc.PeeringGroupPeers(channel, self)
279        '''
280         PeeringGroupPeers provides the building blocks necessary to link two peering groups.
281
282        See `strongdm.svc.PeeringGroupPeers`.
283        '''
284        self.peering_group_resources = svc.PeeringGroupResources(channel, self)
285        '''
286         PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.
287
288        See `strongdm.svc.PeeringGroupResources`.
289        '''
290        self.peering_groups = svc.PeeringGroups(channel, self)
291        '''
292         PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.
293
294        See `strongdm.svc.PeeringGroups`.
295        '''
296        self.policies = svc.Policies(channel, self)
297        '''
298         Policies are the collection of one or more statements that enforce fine-grained access
299         control for the users of an organization.
300
301        See `strongdm.svc.Policies`.
302        '''
303        self.policies_history = svc.PoliciesHistory(channel, self)
304        '''
305         PoliciesHistory records all changes to the state of a Policy.
306
307        See `strongdm.svc.PoliciesHistory`.
308        '''
309        self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self)
310        '''
311         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
312         The proxies within a cluster share the same key. One cluster can have
313         multiple keys in order to facilitate key rotation.
314
315        See `strongdm.svc.ProxyClusterKeys`.
316        '''
317        self.queries = svc.Queries(channel, self)
318        '''
319         A Query is a record of a single client request to a resource, such as a SQL query.
320         Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries.
321         The Queries service is read-only.
322
323        See `strongdm.svc.Queries`.
324        '''
325        self.remote_identities = svc.RemoteIdentities(channel, self)
326        '''
327         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
328
329        See `strongdm.svc.RemoteIdentities`.
330        '''
331        self.remote_identities_history = svc.RemoteIdentitiesHistory(
332            channel, self)
333        '''
334         RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
335
336        See `strongdm.svc.RemoteIdentitiesHistory`.
337        '''
338        self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self)
339        '''
340         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
341         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
342
343        See `strongdm.svc.RemoteIdentityGroups`.
344        '''
345        self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory(
346            channel, self)
347        '''
348         RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
349
350        See `strongdm.svc.RemoteIdentityGroupsHistory`.
351        '''
352        self.replays = svc.Replays(channel, self)
353        '''
354         A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session
355         (otherwise referred to as a query). The Replays service is read-only.
356
357        See `strongdm.svc.Replays`.
358        '''
359        self.resources = svc.Resources(channel, self)
360        '''
361         Resources are databases, servers, clusters, websites, or clouds that strongDM
362         delegates access to.
363
364        See `strongdm.svc.Resources`.
365        '''
366        self.resources_history = svc.ResourcesHistory(channel, self)
367        '''
368         ResourcesHistory records all changes to the state of a Resource.
369
370        See `strongdm.svc.ResourcesHistory`.
371        '''
372        self.role_resources = svc.RoleResources(channel, self)
373        '''
374         RoleResources enumerates the resources to which roles have access.
375         The RoleResources service is read-only.
376
377        See `strongdm.svc.RoleResources`.
378        '''
379        self.role_resources_history = svc.RoleResourcesHistory(channel, self)
380        '''
381         RoleResourcesHistory records all changes to the state of a RoleResource.
382
383        See `strongdm.svc.RoleResourcesHistory`.
384        '''
385        self.roles = svc.Roles(channel, self)
386        '''
387         A Role has a list of access rules which determine which Resources the members
388         of the Role have access to. An Account can be a member of multiple Roles via
389         AccountAttachments.
390
391        See `strongdm.svc.Roles`.
392        '''
393        self.roles_history = svc.RolesHistory(channel, self)
394        '''
395         RolesHistory records all changes to the state of a Role.
396
397        See `strongdm.svc.RolesHistory`.
398        '''
399        self.secret_stores = svc.SecretStores(channel, self)
400        '''
401         SecretStores are servers where resource secrets (passwords, keys) are stored.
402
403        See `strongdm.svc.SecretStores`.
404        '''
405        self.secret_engines = svc.SecretEngines(channel, self)
406        '''
407
408
409        See `strongdm.svc.SecretEngines`.
410        '''
411        self.secret_store_healths = svc.SecretStoreHealths(channel, self)
412        '''
413         SecretStoreHealths exposes health states for secret stores.
414
415        See `strongdm.svc.SecretStoreHealths`.
416        '''
417        self.secret_stores_history = svc.SecretStoresHistory(channel, self)
418        '''
419         SecretStoresHistory records all changes to the state of a SecretStore.
420
421        See `strongdm.svc.SecretStoresHistory`.
422        '''
423        self.workflow_approvers = svc.WorkflowApprovers(channel, self)
424        '''
425         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
426
427        See `strongdm.svc.WorkflowApprovers`.
428        '''
429        self.workflow_approvers_history = svc.WorkflowApproversHistory(
430            channel, self)
431        '''
432         WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.
433
434        See `strongdm.svc.WorkflowApproversHistory`.
435        '''
436        self.workflow_roles = svc.WorkflowRoles(channel, self)
437        '''
438         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
439         to request access to a resource via the workflow.
440
441        See `strongdm.svc.WorkflowRoles`.
442        '''
443        self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self)
444        '''
445         WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole
446
447        See `strongdm.svc.WorkflowRolesHistory`.
448        '''
449        self.workflows = svc.Workflows(channel, self)
450        '''
451         Workflows are the collection of rules that define the resources to which access can be requested,
452         the users that can request that access, and the mechanism for approving those requests which can either
453         be automatic approval or a set of users authorized to approve the requests.
454
455        See `strongdm.svc.Workflows`.
456        '''
457        self.workflows_history = svc.WorkflowsHistory(channel, self)
458        '''
459         WorkflowsHistory provides records of all changes to the state of a Workflow.
460
461        See `strongdm.svc.WorkflowsHistory`.
462        '''
463
464    def close(self):
465        '''Closes this Client and releases all resources held by it.
466
467        Closing the Client will immediately terminate all RPCs active with the
468        Client and it is not valid to invoke new RPCs with the Client.
469
470        This method is idempotent.
471        '''
472        self.channel.close()
473
474    def get_metadata(self, method_name, req):
475        return [
476            ('x-sdm-authentication', self.api_access_key),
477            ('x-sdm-signature', self.sign(method_name,
478                                          req.SerializeToString())),
479            ('x-sdm-api-version', API_VERSION),
480            ('x-sdm-user-agent', USER_AGENT),
481        ]
482
483    def sign(self, method_name, request_bytes):
484        def hmac_digest(key, msg_byte_string):
485            return hmac.new(key, msg=msg_byte_string,
486                            digestmod=hashlib.sha256).digest()
487
488        current_utc_date = datetime.datetime.now(
489            datetime.timezone.utc).strftime('%Y-%m-%d')
490        signing_key = hmac_digest(self.api_secret, current_utc_date.encode())
491        signing_key = hmac_digest(signing_key, b'sdm_api_v1')
492
493        hash = hashlib.sha256()
494
495        hash.update(method_name.encode())
496        hash.update(b'\n')
497        hash.update(request_bytes)
498
499        return base64.b64encode(hmac_digest(signing_key, hash.digest()))
500
501    def exponentialBackoff(self, retries, deadline=None):
502        def applyDeadline(delay, deadline):
503            if deadline is None:
504                return delay
505            remaining = deadline - time.time()
506            if remaining < 0:
507                return 0
508            return min(delay, remaining)
509
510        if retries == 0:
511            return applyDeadline(self.base_retry_delay, deadline)
512
513        backoff, max_delay = self.base_retry_delay, self.max_retry_delay
514        while backoff < max_delay and retries > 0:
515            backoff *= self.retry_factor
516            retries -= 1
517
518        if backoff > max_delay:
519            backoff = max_delay
520
521        # Randomize backoff delays so that if a cluster of requests start at
522        # the same time, they won't operate in lockstep.
523        backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1)
524        if backoff < 0:
525            return 0
526
527        return applyDeadline(backoff, deadline)
528
529    def shouldRetry(self, retries, err, deadline=None):
530        # Check if we've passed the deadline
531        if deadline is not None and time.time() >= deadline:
532            return False
533
534        if not isinstance(err, grpc.RpcError):
535            return False
536
537        if self.retry_rate_limit_errors and err.code(
538        ) == grpc.StatusCode.RESOURCE_EXHAUSTED:
539            return True
540
541        return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL
542                                 or err.code() == grpc.StatusCode.UNAVAILABLE)
543
544    def snapshot_at(self, snapshot_datetime):
545        '''
546        Constructs a read-only client that will provide historical data from the provided timestamp.
547
548        See `SnapshotClient`.
549        '''
550        client = copy.copy(self)
551        client.snapshot_datetime = snapshot_datetime
552        client.access_requests = svc.AccessRequests(client.channel, client)
553        client.account_attachments = svc.AccountAttachments(
554            client.channel, client)
555        client.account_grants = svc.AccountGrants(client.channel, client)
556        client.account_permissions = svc.AccountPermissions(
557            client.channel, client)
558        client.account_resources = svc.AccountResources(client.channel, client)
559        client.accounts = svc.Accounts(client.channel, client)
560        client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
561            client.channel, client)
562        client.approval_workflow_steps = svc.ApprovalWorkflowSteps(
563            client.channel, client)
564        client.approval_workflows = svc.ApprovalWorkflows(
565            client.channel, client)
566        client.identity_aliases = svc.IdentityAliases(client.channel, client)
567        client.identity_sets = svc.IdentitySets(client.channel, client)
568        client.nodes = svc.Nodes(client.channel, client)
569        client.policies = svc.Policies(client.channel, client)
570        client.proxy_cluster_keys = svc.ProxyClusterKeys(
571            client.channel, client)
572        client.remote_identities = svc.RemoteIdentities(client.channel, client)
573        client.remote_identity_groups = svc.RemoteIdentityGroups(
574            client.channel, client)
575        client.resources = svc.Resources(client.channel, client)
576        client.role_resources = svc.RoleResources(client.channel, client)
577        client.roles = svc.Roles(client.channel, client)
578        client.secret_stores = svc.SecretStores(client.channel, client)
579        client.workflow_approvers = svc.WorkflowApprovers(
580            client.channel, client)
581        client.workflow_roles = svc.WorkflowRoles(client.channel, client)
582        client.workflows = svc.Workflows(client.channel, client)
583        return SnapshotClient(client)

Client interacts with the strongDM API.

Client( api_access_key, api_secret, host='app.strongdm.com:443', insecure=False, retry_rate_limit_errors=True, page_limit=0)
 43    def __init__(self,
 44                 api_access_key,
 45                 api_secret,
 46                 host='app.strongdm.com:443',
 47                 insecure=False,
 48                 retry_rate_limit_errors=True,
 49                 page_limit=0):
 50        '''
 51        Create a new Client.
 52
 53        - api_access_key: the access key to authenticate with strongDM
 54        - api_secret: the secret key to authenticate with strongDM
 55        '''
 56        self.api_access_key = api_access_key.strip()
 57        self.api_secret = base64.b64decode(api_secret.strip())
 58        self.base_retry_delay = DEFAULT_BASE_RETRY_DELAY
 59        self.max_retry_delay = DEFAULT_MAX_RETRY_DELAY
 60        self.retry_factor = DEFAULT_RETRY_FACTOR
 61        self.retry_jitter = DEFAULT_RETRY_JITTER
 62        self.retry_rate_limit_errors = retry_rate_limit_errors
 63        self.snapshot_datetime = None
 64        self.page_limit = page_limit
 65
 66        try:
 67            if insecure:
 68                channel = grpc.insecure_channel(host)
 69            else:
 70                creds = grpc.ssl_channel_credentials()
 71                channel = grpc.secure_channel(host, creds)
 72        except Exception as e:
 73            raise plumbing.convert_error_to_porcelain(e) from e
 74        self.channel = channel
 75        self.access_requests = svc.AccessRequests(channel, self)
 76        '''
 77         AccessRequests are requests for access to a resource that may match a Workflow.
 78
 79        See `strongdm.svc.AccessRequests`.
 80        '''
 81        self.access_request_events_history = svc.AccessRequestEventsHistory(
 82            channel, self)
 83        '''
 84         AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.
 85
 86        See `strongdm.svc.AccessRequestEventsHistory`.
 87        '''
 88        self.access_requests_history = svc.AccessRequestsHistory(channel, self)
 89        '''
 90         AccessRequestsHistory provides records of all changes to the state of an AccessRequest.
 91
 92        See `strongdm.svc.AccessRequestsHistory`.
 93        '''
 94        self.account_attachments = svc.AccountAttachments(channel, self)
 95        '''
 96         AccountAttachments assign an account to a role.
 97
 98        See `strongdm.svc.AccountAttachments`.
 99        '''
100        self.account_attachments_history = svc.AccountAttachmentsHistory(
101            channel, self)
102        '''
103         AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
104
105        See `strongdm.svc.AccountAttachmentsHistory`.
106        '''
107        self.account_grants = svc.AccountGrants(channel, self)
108        '''
109         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
110
111        See `strongdm.svc.AccountGrants`.
112        '''
113        self.account_grants_history = svc.AccountGrantsHistory(channel, self)
114        '''
115         AccountGrantsHistory records all changes to the state of an AccountGrant.
116
117        See `strongdm.svc.AccountGrantsHistory`.
118        '''
119        self.account_permissions = svc.AccountPermissions(channel, self)
120        '''
121         AccountPermissions records the granular permissions accounts have, allowing them to execute
122         relevant commands via StrongDM's APIs.
123
124        See `strongdm.svc.AccountPermissions`.
125        '''
126        self.account_resources = svc.AccountResources(channel, self)
127        '''
128         AccountResources enumerates the resources to which accounts have access.
129         The AccountResources service is read-only.
130
131        See `strongdm.svc.AccountResources`.
132        '''
133        self.account_resources_history = svc.AccountResourcesHistory(
134            channel, self)
135        '''
136         AccountResourcesHistory records all changes to the state of a AccountResource.
137
138        See `strongdm.svc.AccountResourcesHistory`.
139        '''
140        self.accounts = svc.Accounts(channel, self)
141        '''
142         Accounts are users that have access to strongDM. There are two types of accounts:
143         1. **Users:** humans who are authenticated through username and password or SSO.
144         2. **Service Accounts:** machines that are authenticated using a service token.
145         3. **Tokens** are access keys with permissions that can be used for authentication.
146
147        See `strongdm.svc.Accounts`.
148        '''
149        self.accounts_history = svc.AccountsHistory(channel, self)
150        '''
151         AccountsHistory records all changes to the state of an Account.
152
153        See `strongdm.svc.AccountsHistory`.
154        '''
155        self.activities = svc.Activities(channel, self)
156        '''
157         An Activity is a record of an action taken against a strongDM deployment, e.g.
158         a user creation, resource deletion, sso configuration change, etc. The Activities
159         service is read-only.
160
161        See `strongdm.svc.Activities`.
162        '''
163        self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
164            channel, self)
165        '''
166         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
167
168        See `strongdm.svc.ApprovalWorkflowApprovers`.
169        '''
170        self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory(
171            channel, self)
172        '''
173         ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.
174
175        See `strongdm.svc.ApprovalWorkflowApproversHistory`.
176        '''
177        self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self)
178        '''
179         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
180
181        See `strongdm.svc.ApprovalWorkflowSteps`.
182        '''
183        self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory(
184            channel, self)
185        '''
186         ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.
187
188        See `strongdm.svc.ApprovalWorkflowStepsHistory`.
189        '''
190        self.approval_workflows = svc.ApprovalWorkflows(channel, self)
191        '''
192         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
193         approvers and be approved or denied.
194
195        See `strongdm.svc.ApprovalWorkflows`.
196        '''
197        self.approval_workflows_history = svc.ApprovalWorkflowsHistory(
198            channel, self)
199        '''
200         ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.
201
202        See `strongdm.svc.ApprovalWorkflowsHistory`.
203        '''
204        self.control_panel = svc.ControlPanel(channel, self)
205        '''
206         ControlPanel contains all administrative controls.
207
208        See `strongdm.svc.ControlPanel`.
209        '''
210        self.health_checks = svc.HealthChecks(channel, self)
211        '''
212         HealthChecks lists the last healthcheck between each node and resource.
213         Note the unconventional capitalization here is to prevent having a collision with GRPC
214
215        See `strongdm.svc.HealthChecks`.
216        '''
217        self.identity_aliases = svc.IdentityAliases(channel, self)
218        '''
219         IdentityAliases assign an alias to an account within an IdentitySet.
220         The alias is used as the username when connecting to a identity supported resource.
221
222        See `strongdm.svc.IdentityAliases`.
223        '''
224        self.identity_aliases_history = svc.IdentityAliasesHistory(
225            channel, self)
226        '''
227         IdentityAliasesHistory records all changes to the state of a IdentityAlias.
228
229        See `strongdm.svc.IdentityAliasesHistory`.
230        '''
231        self.identity_sets = svc.IdentitySets(channel, self)
232        '''
233         A IdentitySet is a named grouping of Identity Aliases for Accounts.
234         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
235
236        See `strongdm.svc.IdentitySets`.
237        '''
238        self.identity_sets_history = svc.IdentitySetsHistory(channel, self)
239        '''
240         IdentitySetsHistory records all changes to the state of a IdentitySet.
241
242        See `strongdm.svc.IdentitySetsHistory`.
243        '''
244        self.managed_secrets = svc.ManagedSecrets(channel, self)
245        '''
246         ManagedSecret is a private vertical for creating, reading, updating,
247         deleting, listing and rotating the managed secrets in the secrets engines as
248         an authenticated user.
249
250        See `strongdm.svc.ManagedSecrets`.
251        '''
252        self.nodes = svc.Nodes(channel, self)
253        '''
254         Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:
255         - **Gateways** are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.
256         - **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.
257
258        See `strongdm.svc.Nodes`.
259        '''
260        self.nodes_history = svc.NodesHistory(channel, self)
261        '''
262         NodesHistory records all changes to the state of a Node.
263
264        See `strongdm.svc.NodesHistory`.
265        '''
266        self.organization_history = svc.OrganizationHistory(channel, self)
267        '''
268         OrganizationHistory records all changes to the state of an Organization.
269
270        See `strongdm.svc.OrganizationHistory`.
271        '''
272        self.peering_group_nodes = svc.PeeringGroupNodes(channel, self)
273        '''
274         PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.
275
276        See `strongdm.svc.PeeringGroupNodes`.
277        '''
278        self.peering_group_peers = svc.PeeringGroupPeers(channel, self)
279        '''
280         PeeringGroupPeers provides the building blocks necessary to link two peering groups.
281
282        See `strongdm.svc.PeeringGroupPeers`.
283        '''
284        self.peering_group_resources = svc.PeeringGroupResources(channel, self)
285        '''
286         PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.
287
288        See `strongdm.svc.PeeringGroupResources`.
289        '''
290        self.peering_groups = svc.PeeringGroups(channel, self)
291        '''
292         PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.
293
294        See `strongdm.svc.PeeringGroups`.
295        '''
296        self.policies = svc.Policies(channel, self)
297        '''
298         Policies are the collection of one or more statements that enforce fine-grained access
299         control for the users of an organization.
300
301        See `strongdm.svc.Policies`.
302        '''
303        self.policies_history = svc.PoliciesHistory(channel, self)
304        '''
305         PoliciesHistory records all changes to the state of a Policy.
306
307        See `strongdm.svc.PoliciesHistory`.
308        '''
309        self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self)
310        '''
311         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
312         The proxies within a cluster share the same key. One cluster can have
313         multiple keys in order to facilitate key rotation.
314
315        See `strongdm.svc.ProxyClusterKeys`.
316        '''
317        self.queries = svc.Queries(channel, self)
318        '''
319         A Query is a record of a single client request to a resource, such as a SQL query.
320         Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries.
321         The Queries service is read-only.
322
323        See `strongdm.svc.Queries`.
324        '''
325        self.remote_identities = svc.RemoteIdentities(channel, self)
326        '''
327         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
328
329        See `strongdm.svc.RemoteIdentities`.
330        '''
331        self.remote_identities_history = svc.RemoteIdentitiesHistory(
332            channel, self)
333        '''
334         RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
335
336        See `strongdm.svc.RemoteIdentitiesHistory`.
337        '''
338        self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self)
339        '''
340         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
341         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
342
343        See `strongdm.svc.RemoteIdentityGroups`.
344        '''
345        self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory(
346            channel, self)
347        '''
348         RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
349
350        See `strongdm.svc.RemoteIdentityGroupsHistory`.
351        '''
352        self.replays = svc.Replays(channel, self)
353        '''
354         A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session
355         (otherwise referred to as a query). The Replays service is read-only.
356
357        See `strongdm.svc.Replays`.
358        '''
359        self.resources = svc.Resources(channel, self)
360        '''
361         Resources are databases, servers, clusters, websites, or clouds that strongDM
362         delegates access to.
363
364        See `strongdm.svc.Resources`.
365        '''
366        self.resources_history = svc.ResourcesHistory(channel, self)
367        '''
368         ResourcesHistory records all changes to the state of a Resource.
369
370        See `strongdm.svc.ResourcesHistory`.
371        '''
372        self.role_resources = svc.RoleResources(channel, self)
373        '''
374         RoleResources enumerates the resources to which roles have access.
375         The RoleResources service is read-only.
376
377        See `strongdm.svc.RoleResources`.
378        '''
379        self.role_resources_history = svc.RoleResourcesHistory(channel, self)
380        '''
381         RoleResourcesHistory records all changes to the state of a RoleResource.
382
383        See `strongdm.svc.RoleResourcesHistory`.
384        '''
385        self.roles = svc.Roles(channel, self)
386        '''
387         A Role has a list of access rules which determine which Resources the members
388         of the Role have access to. An Account can be a member of multiple Roles via
389         AccountAttachments.
390
391        See `strongdm.svc.Roles`.
392        '''
393        self.roles_history = svc.RolesHistory(channel, self)
394        '''
395         RolesHistory records all changes to the state of a Role.
396
397        See `strongdm.svc.RolesHistory`.
398        '''
399        self.secret_stores = svc.SecretStores(channel, self)
400        '''
401         SecretStores are servers where resource secrets (passwords, keys) are stored.
402
403        See `strongdm.svc.SecretStores`.
404        '''
405        self.secret_engines = svc.SecretEngines(channel, self)
406        '''
407
408
409        See `strongdm.svc.SecretEngines`.
410        '''
411        self.secret_store_healths = svc.SecretStoreHealths(channel, self)
412        '''
413         SecretStoreHealths exposes health states for secret stores.
414
415        See `strongdm.svc.SecretStoreHealths`.
416        '''
417        self.secret_stores_history = svc.SecretStoresHistory(channel, self)
418        '''
419         SecretStoresHistory records all changes to the state of a SecretStore.
420
421        See `strongdm.svc.SecretStoresHistory`.
422        '''
423        self.workflow_approvers = svc.WorkflowApprovers(channel, self)
424        '''
425         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
426
427        See `strongdm.svc.WorkflowApprovers`.
428        '''
429        self.workflow_approvers_history = svc.WorkflowApproversHistory(
430            channel, self)
431        '''
432         WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.
433
434        See `strongdm.svc.WorkflowApproversHistory`.
435        '''
436        self.workflow_roles = svc.WorkflowRoles(channel, self)
437        '''
438         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
439         to request access to a resource via the workflow.
440
441        See `strongdm.svc.WorkflowRoles`.
442        '''
443        self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self)
444        '''
445         WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole
446
447        See `strongdm.svc.WorkflowRolesHistory`.
448        '''
449        self.workflows = svc.Workflows(channel, self)
450        '''
451         Workflows are the collection of rules that define the resources to which access can be requested,
452         the users that can request that access, and the mechanism for approving those requests which can either
453         be automatic approval or a set of users authorized to approve the requests.
454
455        See `strongdm.svc.Workflows`.
456        '''
457        self.workflows_history = svc.WorkflowsHistory(channel, self)
458        '''
459         WorkflowsHistory provides records of all changes to the state of a Workflow.
460
461        See `strongdm.svc.WorkflowsHistory`.
462        '''

Create a new Client.

  • api_access_key: the access key to authenticate with strongDM
  • api_secret: the secret key to authenticate with strongDM
access_requests

AccessRequests are requests for access to a resource that may match a Workflow.

See strongdm.svc.AccessRequests.

access_request_events_history

AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.

See strongdm.svc.AccessRequestEventsHistory.

access_requests_history

AccessRequestsHistory provides records of all changes to the state of an AccessRequest.

See strongdm.svc.AccessRequestsHistory.

account_attachments

AccountAttachments assign an account to a role.

See strongdm.svc.AccountAttachments.

account_attachments_history

AccountAttachmentsHistory records all changes to the state of an AccountAttachment.

See strongdm.svc.AccountAttachmentsHistory.

account_grants

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

See strongdm.svc.AccountGrants.

account_grants_history

AccountGrantsHistory records all changes to the state of an AccountGrant.

See strongdm.svc.AccountGrantsHistory.

account_permissions

AccountPermissions records the granular permissions accounts have, allowing them to execute relevant commands via StrongDM's APIs.

See strongdm.svc.AccountPermissions.

account_resources

AccountResources enumerates the resources to which accounts have access. The AccountResources service is read-only.

See strongdm.svc.AccountResources.

account_resources_history

AccountResourcesHistory records all changes to the state of a AccountResource.

See strongdm.svc.AccountResourcesHistory.

accounts

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.
  3. Tokens are access keys with permissions that can be used for authentication.

See strongdm.svc.Accounts.

accounts_history

AccountsHistory records all changes to the state of an Account.

See strongdm.svc.AccountsHistory.

activities

An Activity is a record of an action taken against a strongDM deployment, e.g. a user creation, resource deletion, sso configuration change, etc. The Activities service is read-only.

See strongdm.svc.Activities.

approval_workflow_approvers

ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep

See strongdm.svc.ApprovalWorkflowApprovers.

approval_workflow_approvers_history

ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.

See strongdm.svc.ApprovalWorkflowApproversHistory.

approval_workflow_steps

ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow

See strongdm.svc.ApprovalWorkflowSteps.

approval_workflow_steps_history

ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.

See strongdm.svc.ApprovalWorkflowStepsHistory.

approval_workflows

ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized approvers and be approved or denied.

See strongdm.svc.ApprovalWorkflows.

approval_workflows_history

ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.

See strongdm.svc.ApprovalWorkflowsHistory.

control_panel

ControlPanel contains all administrative controls.

See strongdm.svc.ControlPanel.

health_checks

HealthChecks lists the last healthcheck between each node and resource. Note the unconventional capitalization here is to prevent having a collision with GRPC

See strongdm.svc.HealthChecks.

identity_aliases

IdentityAliases assign an alias to an account within an IdentitySet. The alias is used as the username when connecting to a identity supported resource.

See strongdm.svc.IdentityAliases.

identity_aliases_history

IdentityAliasesHistory records all changes to the state of a IdentityAlias.

See strongdm.svc.IdentityAliasesHistory.

identity_sets

A IdentitySet is a named grouping of Identity Aliases for Accounts. An Account's relationship to a IdentitySet is defined via IdentityAlias objects.

See strongdm.svc.IdentitySets.

identity_sets_history

IdentitySetsHistory records all changes to the state of a IdentitySet.

See strongdm.svc.IdentitySetsHistory.

managed_secrets

ManagedSecret is a private vertical for creating, reading, updating, deleting, listing and rotating the managed secrets in the secrets engines as an authenticated user.

See strongdm.svc.ManagedSecrets.

nodes

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.

See strongdm.svc.Nodes.

nodes_history

NodesHistory records all changes to the state of a Node.

See strongdm.svc.NodesHistory.

organization_history

OrganizationHistory records all changes to the state of an Organization.

See strongdm.svc.OrganizationHistory.

peering_group_nodes

PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.

See strongdm.svc.PeeringGroupNodes.

peering_group_peers

PeeringGroupPeers provides the building blocks necessary to link two peering groups.

See strongdm.svc.PeeringGroupPeers.

peering_group_resources

PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.

See strongdm.svc.PeeringGroupResources.

peering_groups

PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.

See strongdm.svc.PeeringGroups.

policies

Policies are the collection of one or more statements that enforce fine-grained access control for the users of an organization.

See strongdm.svc.Policies.

policies_history

PoliciesHistory records all changes to the state of a Policy.

See strongdm.svc.PoliciesHistory.

proxy_cluster_keys

Proxy Cluster Keys are authentication keys for all proxies within a cluster. The proxies within a cluster share the same key. One cluster can have multiple keys in order to facilitate key rotation.

See strongdm.svc.ProxyClusterKeys.

queries

A Query is a record of a single client request to a resource, such as a SQL query. Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries. The Queries service is read-only.

See strongdm.svc.Queries.

remote_identities

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

See strongdm.svc.RemoteIdentities.

remote_identities_history

RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.

See strongdm.svc.RemoteIdentitiesHistory.

remote_identity_groups

A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.

See strongdm.svc.RemoteIdentityGroups.

remote_identity_groups_history

RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.

See strongdm.svc.RemoteIdentityGroupsHistory.

replays

A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session (otherwise referred to as a query). The Replays service is read-only.

See strongdm.svc.Replays.

resources

Resources are databases, servers, clusters, websites, or clouds that strongDM delegates access to.

See strongdm.svc.Resources.

resources_history

ResourcesHistory records all changes to the state of a Resource.

See strongdm.svc.ResourcesHistory.

role_resources

RoleResources enumerates the resources to which roles have access. The RoleResources service is read-only.

See strongdm.svc.RoleResources.

role_resources_history

RoleResourcesHistory records all changes to the state of a RoleResource.

See strongdm.svc.RoleResourcesHistory.

roles

A Role has a list of access rules which determine which Resources the members of the Role have access to. An Account can be a member of multiple Roles via AccountAttachments.

See strongdm.svc.Roles.

roles_history

RolesHistory records all changes to the state of a Role.

See strongdm.svc.RolesHistory.

secret_stores

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

See strongdm.svc.SecretStores.

secret_engines
secret_store_healths

SecretStoreHealths exposes health states for secret stores.

See strongdm.svc.SecretStoreHealths.

secret_stores_history

SecretStoresHistory records all changes to the state of a SecretStore.

See strongdm.svc.SecretStoresHistory.

workflow_approvers

WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.

See strongdm.svc.WorkflowApprovers.

workflow_approvers_history

WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.

See strongdm.svc.WorkflowApproversHistory.

workflow_roles

WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of to request access to a resource via the workflow.

See strongdm.svc.WorkflowRoles.

workflow_roles_history

WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole

See strongdm.svc.WorkflowRolesHistory.

workflows

Workflows are the collection of rules that define the resources to which access can be requested, the users that can request that access, and the mechanism for approving those requests which can either be automatic approval or a set of users authorized to approve the requests.

See strongdm.svc.Workflows.

workflows_history

WorkflowsHistory provides records of all changes to the state of a Workflow.

See strongdm.svc.WorkflowsHistory.

def close(self)
464    def close(self):
465        '''Closes this Client and releases all resources held by it.
466
467        Closing the Client will immediately terminate all RPCs active with the
468        Client and it is not valid to invoke new RPCs with the Client.
469
470        This method is idempotent.
471        '''
472        self.channel.close()

Closes this Client and releases all resources held by it.

Closing the Client will immediately terminate all RPCs active with the Client and it is not valid to invoke new RPCs with the Client.

This method is idempotent.

def get_metadata(self, method_name, req)
474    def get_metadata(self, method_name, req):
475        return [
476            ('x-sdm-authentication', self.api_access_key),
477            ('x-sdm-signature', self.sign(method_name,
478                                          req.SerializeToString())),
479            ('x-sdm-api-version', API_VERSION),
480            ('x-sdm-user-agent', USER_AGENT),
481        ]
def sign(self, method_name, request_bytes)
483    def sign(self, method_name, request_bytes):
484        def hmac_digest(key, msg_byte_string):
485            return hmac.new(key, msg=msg_byte_string,
486                            digestmod=hashlib.sha256).digest()
487
488        current_utc_date = datetime.datetime.now(
489            datetime.timezone.utc).strftime('%Y-%m-%d')
490        signing_key = hmac_digest(self.api_secret, current_utc_date.encode())
491        signing_key = hmac_digest(signing_key, b'sdm_api_v1')
492
493        hash = hashlib.sha256()
494
495        hash.update(method_name.encode())
496        hash.update(b'\n')
497        hash.update(request_bytes)
498
499        return base64.b64encode(hmac_digest(signing_key, hash.digest()))
def exponentialBackoff(self, retries, deadline=None)
501    def exponentialBackoff(self, retries, deadline=None):
502        def applyDeadline(delay, deadline):
503            if deadline is None:
504                return delay
505            remaining = deadline - time.time()
506            if remaining < 0:
507                return 0
508            return min(delay, remaining)
509
510        if retries == 0:
511            return applyDeadline(self.base_retry_delay, deadline)
512
513        backoff, max_delay = self.base_retry_delay, self.max_retry_delay
514        while backoff < max_delay and retries > 0:
515            backoff *= self.retry_factor
516            retries -= 1
517
518        if backoff > max_delay:
519            backoff = max_delay
520
521        # Randomize backoff delays so that if a cluster of requests start at
522        # the same time, they won't operate in lockstep.
523        backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1)
524        if backoff < 0:
525            return 0
526
527        return applyDeadline(backoff, deadline)
def shouldRetry(self, retries, err, deadline=None)
529    def shouldRetry(self, retries, err, deadline=None):
530        # Check if we've passed the deadline
531        if deadline is not None and time.time() >= deadline:
532            return False
533
534        if not isinstance(err, grpc.RpcError):
535            return False
536
537        if self.retry_rate_limit_errors and err.code(
538        ) == grpc.StatusCode.RESOURCE_EXHAUSTED:
539            return True
540
541        return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL
542                                 or err.code() == grpc.StatusCode.UNAVAILABLE)
def snapshot_at(self, snapshot_datetime)
544    def snapshot_at(self, snapshot_datetime):
545        '''
546        Constructs a read-only client that will provide historical data from the provided timestamp.
547
548        See `SnapshotClient`.
549        '''
550        client = copy.copy(self)
551        client.snapshot_datetime = snapshot_datetime
552        client.access_requests = svc.AccessRequests(client.channel, client)
553        client.account_attachments = svc.AccountAttachments(
554            client.channel, client)
555        client.account_grants = svc.AccountGrants(client.channel, client)
556        client.account_permissions = svc.AccountPermissions(
557            client.channel, client)
558        client.account_resources = svc.AccountResources(client.channel, client)
559        client.accounts = svc.Accounts(client.channel, client)
560        client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
561            client.channel, client)
562        client.approval_workflow_steps = svc.ApprovalWorkflowSteps(
563            client.channel, client)
564        client.approval_workflows = svc.ApprovalWorkflows(
565            client.channel, client)
566        client.identity_aliases = svc.IdentityAliases(client.channel, client)
567        client.identity_sets = svc.IdentitySets(client.channel, client)
568        client.nodes = svc.Nodes(client.channel, client)
569        client.policies = svc.Policies(client.channel, client)
570        client.proxy_cluster_keys = svc.ProxyClusterKeys(
571            client.channel, client)
572        client.remote_identities = svc.RemoteIdentities(client.channel, client)
573        client.remote_identity_groups = svc.RemoteIdentityGroups(
574            client.channel, client)
575        client.resources = svc.Resources(client.channel, client)
576        client.role_resources = svc.RoleResources(client.channel, client)
577        client.roles = svc.Roles(client.channel, client)
578        client.secret_stores = svc.SecretStores(client.channel, client)
579        client.workflow_approvers = svc.WorkflowApprovers(
580            client.channel, client)
581        client.workflow_roles = svc.WorkflowRoles(client.channel, client)
582        client.workflows = svc.Workflows(client.channel, client)
583        return SnapshotClient(client)

Constructs a read-only client that will provide historical data from the provided timestamp.

See SnapshotClient.

class SnapshotClient:
586class SnapshotClient:
587    '''SnapshotClient exposes methods to query historical records at a provided timestamp.'''
588    def __init__(self, client):
589        self.access_requests = svc.SnapshotAccessRequests(
590            client.access_requests)
591        '''
592         AccessRequests are requests for access to a resource that may match a Workflow.
593
594        See `strongdm.svc.SnapshotAccessRequests`.
595        '''
596        self.account_attachments = svc.SnapshotAccountAttachments(
597            client.account_attachments)
598        '''
599         AccountAttachments assign an account to a role.
600
601        See `strongdm.svc.SnapshotAccountAttachments`.
602        '''
603        self.account_grants = svc.SnapshotAccountGrants(client.account_grants)
604        '''
605         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
606
607        See `strongdm.svc.SnapshotAccountGrants`.
608        '''
609        self.account_permissions = svc.SnapshotAccountPermissions(
610            client.account_permissions)
611        '''
612         AccountPermissions records the granular permissions accounts have, allowing them to execute
613         relevant commands via StrongDM's APIs.
614
615        See `strongdm.svc.SnapshotAccountPermissions`.
616        '''
617        self.account_resources = svc.SnapshotAccountResources(
618            client.account_resources)
619        '''
620         AccountResources enumerates the resources to which accounts have access.
621         The AccountResources service is read-only.
622
623        See `strongdm.svc.SnapshotAccountResources`.
624        '''
625        self.accounts = svc.SnapshotAccounts(client.accounts)
626        '''
627         Accounts are users that have access to strongDM. There are two types of accounts:
628         1. **Users:** humans who are authenticated through username and password or SSO.
629         2. **Service Accounts:** machines that are authenticated using a service token.
630         3. **Tokens** are access keys with permissions that can be used for authentication.
631
632        See `strongdm.svc.SnapshotAccounts`.
633        '''
634        self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers(
635            client.approval_workflow_approvers)
636        '''
637         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
638
639        See `strongdm.svc.SnapshotApprovalWorkflowApprovers`.
640        '''
641        self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps(
642            client.approval_workflow_steps)
643        '''
644         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
645
646        See `strongdm.svc.SnapshotApprovalWorkflowSteps`.
647        '''
648        self.approval_workflows = svc.SnapshotApprovalWorkflows(
649            client.approval_workflows)
650        '''
651         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
652         approvers and be approved or denied.
653
654        See `strongdm.svc.SnapshotApprovalWorkflows`.
655        '''
656        self.identity_aliases = svc.SnapshotIdentityAliases(
657            client.identity_aliases)
658        '''
659         IdentityAliases assign an alias to an account within an IdentitySet.
660         The alias is used as the username when connecting to a identity supported resource.
661
662        See `strongdm.svc.SnapshotIdentityAliases`.
663        '''
664        self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets)
665        '''
666         A IdentitySet is a named grouping of Identity Aliases for Accounts.
667         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
668
669        See `strongdm.svc.SnapshotIdentitySets`.
670        '''
671        self.nodes = svc.SnapshotNodes(client.nodes)
672        '''
673         Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:
674         - **Gateways** are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.
675         - **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.
676
677        See `strongdm.svc.SnapshotNodes`.
678        '''
679        self.policies = svc.SnapshotPolicies(client.policies)
680        '''
681         Policies are the collection of one or more statements that enforce fine-grained access
682         control for the users of an organization.
683
684        See `strongdm.svc.SnapshotPolicies`.
685        '''
686        self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys(
687            client.proxy_cluster_keys)
688        '''
689         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
690         The proxies within a cluster share the same key. One cluster can have
691         multiple keys in order to facilitate key rotation.
692
693        See `strongdm.svc.SnapshotProxyClusterKeys`.
694        '''
695        self.remote_identities = svc.SnapshotRemoteIdentities(
696            client.remote_identities)
697        '''
698         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
699
700        See `strongdm.svc.SnapshotRemoteIdentities`.
701        '''
702        self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups(
703            client.remote_identity_groups)
704        '''
705         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
706         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
707
708        See `strongdm.svc.SnapshotRemoteIdentityGroups`.
709        '''
710        self.resources = svc.SnapshotResources(client.resources)
711        '''
712         Resources are databases, servers, clusters, websites, or clouds that strongDM
713         delegates access to.
714
715        See `strongdm.svc.SnapshotResources`.
716        '''
717        self.role_resources = svc.SnapshotRoleResources(client.role_resources)
718        '''
719         RoleResources enumerates the resources to which roles have access.
720         The RoleResources service is read-only.
721
722        See `strongdm.svc.SnapshotRoleResources`.
723        '''
724        self.roles = svc.SnapshotRoles(client.roles)
725        '''
726         A Role has a list of access rules which determine which Resources the members
727         of the Role have access to. An Account can be a member of multiple Roles via
728         AccountAttachments.
729
730        See `strongdm.svc.SnapshotRoles`.
731        '''
732        self.secret_stores = svc.SnapshotSecretStores(client.secret_stores)
733        '''
734         SecretStores are servers where resource secrets (passwords, keys) are stored.
735
736        See `strongdm.svc.SnapshotSecretStores`.
737        '''
738        self.workflow_approvers = svc.SnapshotWorkflowApprovers(
739            client.workflow_approvers)
740        '''
741         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
742
743        See `strongdm.svc.SnapshotWorkflowApprovers`.
744        '''
745        self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles)
746        '''
747         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
748         to request access to a resource via the workflow.
749
750        See `strongdm.svc.SnapshotWorkflowRoles`.
751        '''
752        self.workflows = svc.SnapshotWorkflows(client.workflows)
753        '''
754         Workflows are the collection of rules that define the resources to which access can be requested,
755         the users that can request that access, and the mechanism for approving those requests which can either
756         be automatic approval or a set of users authorized to approve the requests.
757
758        See `strongdm.svc.SnapshotWorkflows`.
759        '''

SnapshotClient exposes methods to query historical records at a provided timestamp.

SnapshotClient(client)
588    def __init__(self, client):
589        self.access_requests = svc.SnapshotAccessRequests(
590            client.access_requests)
591        '''
592         AccessRequests are requests for access to a resource that may match a Workflow.
593
594        See `strongdm.svc.SnapshotAccessRequests`.
595        '''
596        self.account_attachments = svc.SnapshotAccountAttachments(
597            client.account_attachments)
598        '''
599         AccountAttachments assign an account to a role.
600
601        See `strongdm.svc.SnapshotAccountAttachments`.
602        '''
603        self.account_grants = svc.SnapshotAccountGrants(client.account_grants)
604        '''
605         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
606
607        See `strongdm.svc.SnapshotAccountGrants`.
608        '''
609        self.account_permissions = svc.SnapshotAccountPermissions(
610            client.account_permissions)
611        '''
612         AccountPermissions records the granular permissions accounts have, allowing them to execute
613         relevant commands via StrongDM's APIs.
614
615        See `strongdm.svc.SnapshotAccountPermissions`.
616        '''
617        self.account_resources = svc.SnapshotAccountResources(
618            client.account_resources)
619        '''
620         AccountResources enumerates the resources to which accounts have access.
621         The AccountResources service is read-only.
622
623        See `strongdm.svc.SnapshotAccountResources`.
624        '''
625        self.accounts = svc.SnapshotAccounts(client.accounts)
626        '''
627         Accounts are users that have access to strongDM. There are two types of accounts:
628         1. **Users:** humans who are authenticated through username and password or SSO.
629         2. **Service Accounts:** machines that are authenticated using a service token.
630         3. **Tokens** are access keys with permissions that can be used for authentication.
631
632        See `strongdm.svc.SnapshotAccounts`.
633        '''
634        self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers(
635            client.approval_workflow_approvers)
636        '''
637         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
638
639        See `strongdm.svc.SnapshotApprovalWorkflowApprovers`.
640        '''
641        self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps(
642            client.approval_workflow_steps)
643        '''
644         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
645
646        See `strongdm.svc.SnapshotApprovalWorkflowSteps`.
647        '''
648        self.approval_workflows = svc.SnapshotApprovalWorkflows(
649            client.approval_workflows)
650        '''
651         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
652         approvers and be approved or denied.
653
654        See `strongdm.svc.SnapshotApprovalWorkflows`.
655        '''
656        self.identity_aliases = svc.SnapshotIdentityAliases(
657            client.identity_aliases)
658        '''
659         IdentityAliases assign an alias to an account within an IdentitySet.
660         The alias is used as the username when connecting to a identity supported resource.
661
662        See `strongdm.svc.SnapshotIdentityAliases`.
663        '''
664        self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets)
665        '''
666         A IdentitySet is a named grouping of Identity Aliases for Accounts.
667         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
668
669        See `strongdm.svc.SnapshotIdentitySets`.
670        '''
671        self.nodes = svc.SnapshotNodes(client.nodes)
672        '''
673         Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:
674         - **Gateways** are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.
675         - **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.
676
677        See `strongdm.svc.SnapshotNodes`.
678        '''
679        self.policies = svc.SnapshotPolicies(client.policies)
680        '''
681         Policies are the collection of one or more statements that enforce fine-grained access
682         control for the users of an organization.
683
684        See `strongdm.svc.SnapshotPolicies`.
685        '''
686        self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys(
687            client.proxy_cluster_keys)
688        '''
689         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
690         The proxies within a cluster share the same key. One cluster can have
691         multiple keys in order to facilitate key rotation.
692
693        See `strongdm.svc.SnapshotProxyClusterKeys`.
694        '''
695        self.remote_identities = svc.SnapshotRemoteIdentities(
696            client.remote_identities)
697        '''
698         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
699
700        See `strongdm.svc.SnapshotRemoteIdentities`.
701        '''
702        self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups(
703            client.remote_identity_groups)
704        '''
705         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
706         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
707
708        See `strongdm.svc.SnapshotRemoteIdentityGroups`.
709        '''
710        self.resources = svc.SnapshotResources(client.resources)
711        '''
712         Resources are databases, servers, clusters, websites, or clouds that strongDM
713         delegates access to.
714
715        See `strongdm.svc.SnapshotResources`.
716        '''
717        self.role_resources = svc.SnapshotRoleResources(client.role_resources)
718        '''
719         RoleResources enumerates the resources to which roles have access.
720         The RoleResources service is read-only.
721
722        See `strongdm.svc.SnapshotRoleResources`.
723        '''
724        self.roles = svc.SnapshotRoles(client.roles)
725        '''
726         A Role has a list of access rules which determine which Resources the members
727         of the Role have access to. An Account can be a member of multiple Roles via
728         AccountAttachments.
729
730        See `strongdm.svc.SnapshotRoles`.
731        '''
732        self.secret_stores = svc.SnapshotSecretStores(client.secret_stores)
733        '''
734         SecretStores are servers where resource secrets (passwords, keys) are stored.
735
736        See `strongdm.svc.SnapshotSecretStores`.
737        '''
738        self.workflow_approvers = svc.SnapshotWorkflowApprovers(
739            client.workflow_approvers)
740        '''
741         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
742
743        See `strongdm.svc.SnapshotWorkflowApprovers`.
744        '''
745        self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles)
746        '''
747         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
748         to request access to a resource via the workflow.
749
750        See `strongdm.svc.SnapshotWorkflowRoles`.
751        '''
752        self.workflows = svc.SnapshotWorkflows(client.workflows)
753        '''
754         Workflows are the collection of rules that define the resources to which access can be requested,
755         the users that can request that access, and the mechanism for approving those requests which can either
756         be automatic approval or a set of users authorized to approve the requests.
757
758        See `strongdm.svc.SnapshotWorkflows`.
759        '''
access_requests

AccessRequests are requests for access to a resource that may match a Workflow.

See strongdm.svc.SnapshotAccessRequests.

account_attachments

AccountAttachments assign an account to a role.

See strongdm.svc.SnapshotAccountAttachments.

account_grants

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

See strongdm.svc.SnapshotAccountGrants.

account_permissions

AccountPermissions records the granular permissions accounts have, allowing them to execute relevant commands via StrongDM's APIs.

See strongdm.svc.SnapshotAccountPermissions.

account_resources

AccountResources enumerates the resources to which accounts have access. The AccountResources service is read-only.

See strongdm.svc.SnapshotAccountResources.

accounts

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.
  3. Tokens are access keys with permissions that can be used for authentication.

See strongdm.svc.SnapshotAccounts.

approval_workflow_approvers

ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep

See strongdm.svc.SnapshotApprovalWorkflowApprovers.

approval_workflow_steps

ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow

See strongdm.svc.SnapshotApprovalWorkflowSteps.

approval_workflows

ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized approvers and be approved or denied.

See strongdm.svc.SnapshotApprovalWorkflows.

identity_aliases

IdentityAliases assign an alias to an account within an IdentitySet. The alias is used as the username when connecting to a identity supported resource.

See strongdm.svc.SnapshotIdentityAliases.

identity_sets

A IdentitySet is a named grouping of Identity Aliases for Accounts. An Account's relationship to a IdentitySet is defined via IdentityAlias objects.

See strongdm.svc.SnapshotIdentitySets.

nodes

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.

See strongdm.svc.SnapshotNodes.

policies

Policies are the collection of one or more statements that enforce fine-grained access control for the users of an organization.

See strongdm.svc.SnapshotPolicies.

proxy_cluster_keys

Proxy Cluster Keys are authentication keys for all proxies within a cluster. The proxies within a cluster share the same key. One cluster can have multiple keys in order to facilitate key rotation.

See strongdm.svc.SnapshotProxyClusterKeys.

remote_identities

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

See strongdm.svc.SnapshotRemoteIdentities.

remote_identity_groups

A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.

See strongdm.svc.SnapshotRemoteIdentityGroups.

resources

Resources are databases, servers, clusters, websites, or clouds that strongDM delegates access to.

See strongdm.svc.SnapshotResources.

role_resources

RoleResources enumerates the resources to which roles have access. The RoleResources service is read-only.

See strongdm.svc.SnapshotRoleResources.

roles

A Role has a list of access rules which determine which Resources the members of the Role have access to. An Account can be a member of multiple Roles via AccountAttachments.

See strongdm.svc.SnapshotRoles.

secret_stores

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

See strongdm.svc.SnapshotSecretStores.

workflow_approvers

WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.

See strongdm.svc.SnapshotWorkflowApprovers.

workflow_roles

WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of to request access to a resource via the workflow.

See strongdm.svc.SnapshotWorkflowRoles.

workflows

Workflows are the collection of rules that define the resources to which access can be requested, the users that can request that access, and the mechanism for approving those requests which can either be automatic approval or a set of users authorized to approve the requests.

See strongdm.svc.SnapshotWorkflows.