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 collections
  20import copy
  21import datetime
  22import functools
  23import grpc
  24import hashlib
  25import hmac
  26import random
  27import re
  28import time
  29from . import errors
  30from . import plumbing
  31from . import svc
  32
  33from cryptography.hazmat.primitives.asymmetric import rsa, padding
  34from cryptography.hazmat.primitives import serialization, hashes
  35
  36# These defaults are taken from AWS. Customization of these values
  37# is a future step in the API.
  38DEFAULT_BASE_RETRY_DELAY = 1  # 1 second
  39DEFAULT_MAX_RETRY_DELAY = 120  # 120 seconds
  40DEFAULT_RETRY_FACTOR = 1.6
  41DEFAULT_RETRY_JITTER = 0.2
  42API_VERSION = '2025-04-14'
  43USER_AGENT = 'strongdm-sdk-python/16.15.0'
  44
  45method_regexp = re.compile(r'\W+')
  46
  47
  48class _ClientCallDetails(
  49        collections.namedtuple(
  50            "_ClientCallDetails",
  51            ("method", "timeout", "metadata", "credentials")),
  52        grpc.ClientCallDetails,
  53):
  54    """ _ClientCallDetails is used to override some of the attributes of the client_call_details in the interceptors"""
  55    pass
  56
  57
  58class _EncryptionInterceptor(grpc.UnaryUnaryClientInterceptor):
  59    """ _EncryptionInterceptor is used to add transparent encryption/decryption support for managed secrets"""
  60    def __init__(self, client):
  61        self.client = client
  62        self.public_key_cache = {}
  63
  64    def intercept_unary_unary(self, continuation, client_call_details,
  65                              request):
  66        method = method_regexp.sub("_", client_call_details.method.lower())
  67        callback = getattr(self, method, None)
  68        if callback is not None:
  69            return callback(continuation, client_call_details, request)
  70        return continuation(client_call_details, request)
  71
  72    @functools.cached_property
  73    def private_key(self):
  74        return rsa.generate_private_key(
  75            public_exponent=65537,
  76            key_size=4096,
  77        )
  78
  79    def _encrypt_secret(self, method, continuation, client_call_details,
  80                        request):
  81        secret = request.managed_secret
  82        if len(secret.value) != 0:
  83            if secret.secret_engine_id not in self.public_key_cache:
  84                try:
  85                    # fetch secret engine details to fill up self.public_key_cache
  86                    # if it fails the call to create/update will fail as well
  87                    self.client.secret_engines.get(secret.secret_engine_id)
  88                except errors.RPCError:
  89                    pass
  90            key = self.public_key_cache.get(secret.secret_engine_id)
  91            if key is not None:
  92                encrypted = key.encrypt(
  93                    secret.value,
  94                    padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),
  95                                 algorithm=hashes.SHA256(),
  96                                 label=None))
  97                secret.value = encrypted
  98            client_call_details = _ClientCallDetails(
  99                method=client_call_details.method,
 100                timeout=client_call_details.timeout,
 101                metadata=self.client.get_metadata(method, request),
 102                credentials=client_call_details.credentials)
 103        return continuation(client_call_details, request)
 104
 105    def _v1_managedsecrets_create(self, continuation, client_call_details,
 106                                  request):
 107        return self._encrypt_secret("ManagedSecrets.Create", continuation,
 108                                    client_call_details, request)
 109
 110    def _v1_managedsecrets_update(self, continuation, client_call_details,
 111                                  request):
 112        return self._encrypt_secret("ManagedSecrets.Update", continuation,
 113                                    client_call_details, request)
 114
 115    def _v1_managedsecrets_retrieve(self, continuation, client_call_details,
 116                                    request):
 117        if len(request.public_key) != 0:
 118            return continuation(client_call_details, request)
 119
 120        privKey = self.private_key
 121        request.public_key = privKey.public_key().public_bytes(
 122            serialization.Encoding.PEM,
 123            serialization.PublicFormat.SubjectPublicKeyInfo)
 124        client_call_details = _ClientCallDetails(
 125            method=client_call_details.method,
 126            timeout=client_call_details.timeout,
 127            metadata=self.client.get_metadata("ManagedSecrets.Retrieve",
 128                                              request),
 129            credentials=client_call_details.credentials)
 130        resp = continuation(client_call_details, request)
 131        if resp.code() != grpc.StatusCode.OK:
 132            return resp
 133        result = resp.result()
 134        plaintext = privKey.decrypt(
 135            result.managed_secret.value,
 136            padding.OAEP(
 137                mgf=padding.MGF1(algorithm=hashes.SHA256()),
 138                algorithm=hashes.SHA256(),
 139                label=None,
 140            ))
 141        result.managed_secret.value = plaintext
 142        return resp
 143
 144    def _v1_secretengines_get(self, continuation, client_call_details,
 145                              request):
 146        response = continuation(client_call_details, request)
 147        if response.code() != grpc.StatusCode.OK:
 148            return response
 149        result = response.result()
 150        engine = plumbing.convert_secret_engine_to_porcelain(
 151            result.secret_engine)
 152        engineKey = serialization.load_pem_public_key(engine.public_key)
 153        self.public_key_cache[engine.id] = engineKey
 154        return response
 155
 156    def _v1_secretengines_list(self, continuation, client_call_details,
 157                               request):
 158        response = continuation(client_call_details, request)
 159        if response.code() != grpc.StatusCode.OK:
 160            return response
 161        result = response.result()
 162        for plumbing_engine in result.secret_engines:
 163            engine = plumbing.convert_secret_engine_to_porcelain(
 164                plumbing_engine)
 165            engineKey = serialization.load_pem_public_key(engine.public_key)
 166            self.public_key_cache[engine.id] = engineKey
 167        return response
 168
 169
 170class Client:
 171    '''Client interacts with the strongDM API.'''
 172    def __init__(self,
 173                 api_access_key,
 174                 api_secret,
 175                 host='app.strongdm.com:443',
 176                 insecure=False,
 177                 retry_rate_limit_errors=True,
 178                 page_limit=0):
 179        '''
 180        Create a new Client.
 181
 182        - api_access_key: the access key to authenticate with strongDM
 183        - api_secret: the secret key to authenticate with strongDM
 184        '''
 185        self.api_access_key = api_access_key.strip()
 186        self.api_secret = base64.b64decode(api_secret.strip())
 187        self.base_retry_delay = DEFAULT_BASE_RETRY_DELAY
 188        self.max_retry_delay = DEFAULT_MAX_RETRY_DELAY
 189        self.retry_factor = DEFAULT_RETRY_FACTOR
 190        self.retry_jitter = DEFAULT_RETRY_JITTER
 191        self.retry_rate_limit_errors = retry_rate_limit_errors
 192        self.snapshot_datetime = None
 193        self.page_limit = page_limit
 194
 195        try:
 196            if insecure:
 197                channel = grpc.insecure_channel(host)
 198            else:
 199                creds = grpc.ssl_channel_credentials()
 200                channel = grpc.secure_channel(host, creds)
 201        except Exception as e:
 202            raise plumbing.convert_error_to_porcelain(e) from e
 203        channel = grpc.intercept_channel(channel, _EncryptionInterceptor(self))
 204        self.channel = channel
 205        self.access_requests = svc.AccessRequests(channel, self)
 206        '''
 207         AccessRequests are requests for access to a resource that may match a Workflow.
 208
 209        See `strongdm.svc.AccessRequests`.
 210        '''
 211        self.access_request_events_history = svc.AccessRequestEventsHistory(
 212            channel, self)
 213        '''
 214         AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.
 215
 216        See `strongdm.svc.AccessRequestEventsHistory`.
 217        '''
 218        self.access_requests_history = svc.AccessRequestsHistory(channel, self)
 219        '''
 220         AccessRequestsHistory provides records of all changes to the state of an AccessRequest.
 221
 222        See `strongdm.svc.AccessRequestsHistory`.
 223        '''
 224        self.account_attachments = svc.AccountAttachments(channel, self)
 225        '''
 226         AccountAttachments assign an account to a role.
 227
 228        See `strongdm.svc.AccountAttachments`.
 229        '''
 230        self.account_attachments_history = svc.AccountAttachmentsHistory(
 231            channel, self)
 232        '''
 233         AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
 234
 235        See `strongdm.svc.AccountAttachmentsHistory`.
 236        '''
 237        self.account_grants = svc.AccountGrants(channel, self)
 238        '''
 239         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
 240
 241        See `strongdm.svc.AccountGrants`.
 242        '''
 243        self.account_grants_history = svc.AccountGrantsHistory(channel, self)
 244        '''
 245         AccountGrantsHistory records all changes to the state of an AccountGrant.
 246
 247        See `strongdm.svc.AccountGrantsHistory`.
 248        '''
 249        self.account_permissions = svc.AccountPermissions(channel, self)
 250        '''
 251         AccountPermissions records the granular permissions accounts have, allowing them to execute
 252         relevant commands via StrongDM's APIs.
 253
 254        See `strongdm.svc.AccountPermissions`.
 255        '''
 256        self.account_resources = svc.AccountResources(channel, self)
 257        '''
 258         AccountResources enumerates the resources to which accounts have access.
 259         The AccountResources service is read-only.
 260
 261        See `strongdm.svc.AccountResources`.
 262        '''
 263        self.account_resources_history = svc.AccountResourcesHistory(
 264            channel, self)
 265        '''
 266         AccountResourcesHistory records all changes to the state of a AccountResource.
 267
 268        See `strongdm.svc.AccountResourcesHistory`.
 269        '''
 270        self.accounts = svc.Accounts(channel, self)
 271        '''
 272         Accounts are users that have access to strongDM. There are two types of accounts:
 273         1. **Users:** humans who are authenticated through username and password or SSO.
 274         2. **Service Accounts:** machines that are authenticated using a service token.
 275         3. **Tokens** are access keys with permissions that can be used for authentication.
 276
 277        See `strongdm.svc.Accounts`.
 278        '''
 279        self.accounts_groups = svc.AccountsGroups(channel, self)
 280        '''
 281         An AccountGroup links an account and a group.
 282
 283        See `strongdm.svc.AccountsGroups`.
 284        '''
 285        self.accounts_groups_history = svc.AccountsGroupsHistory(channel, self)
 286        '''
 287         AccountsGroupsHistory records all changes to the state of an AccountGroup.
 288
 289        See `strongdm.svc.AccountsGroupsHistory`.
 290        '''
 291        self.accounts_history = svc.AccountsHistory(channel, self)
 292        '''
 293         AccountsHistory records all changes to the state of an Account.
 294
 295        See `strongdm.svc.AccountsHistory`.
 296        '''
 297        self.activities = svc.Activities(channel, self)
 298        '''
 299         An Activity is a record of an action taken against a strongDM deployment, e.g.
 300         a user creation, resource deletion, sso configuration change, etc. The Activities
 301         service is read-only.
 302
 303        See `strongdm.svc.Activities`.
 304        '''
 305        self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
 306            channel, self)
 307        '''
 308         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
 309
 310        See `strongdm.svc.ApprovalWorkflowApprovers`.
 311        '''
 312        self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory(
 313            channel, self)
 314        '''
 315         ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.
 316
 317        See `strongdm.svc.ApprovalWorkflowApproversHistory`.
 318        '''
 319        self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self)
 320        '''
 321         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
 322
 323        See `strongdm.svc.ApprovalWorkflowSteps`.
 324        '''
 325        self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory(
 326            channel, self)
 327        '''
 328         ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.
 329
 330        See `strongdm.svc.ApprovalWorkflowStepsHistory`.
 331        '''
 332        self.approval_workflows = svc.ApprovalWorkflows(channel, self)
 333        '''
 334         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
 335         approvers and be approved or denied.
 336
 337        See `strongdm.svc.ApprovalWorkflows`.
 338        '''
 339        self.approval_workflows_history = svc.ApprovalWorkflowsHistory(
 340            channel, self)
 341        '''
 342         ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.
 343
 344        See `strongdm.svc.ApprovalWorkflowsHistory`.
 345        '''
 346        self.control_panel = svc.ControlPanel(channel, self)
 347        '''
 348         ControlPanel contains all administrative controls.
 349
 350        See `strongdm.svc.ControlPanel`.
 351        '''
 352        self.discovery_connectors = svc.DiscoveryConnectors(channel, self)
 353        '''
 354         A Discovery Connector is a configuration object for performing Resource
 355         Scans in remote systems such as AWS, GCP, Azure, and other systems.
 356
 357        See `strongdm.svc.DiscoveryConnectors`.
 358        '''
 359        self.granted_account_entitlements = svc.GrantedAccountEntitlements(
 360            channel, self)
 361        '''
 362         GrantedAccountEntitlements enumerates the resources to which an account has been granted access.
 363         The GrantedAccountEntitlements service is read-only.
 364
 365        See `strongdm.svc.GrantedAccountEntitlements`.
 366        '''
 367        self.granted_resource_entitlements = svc.GrantedResourceEntitlements(
 368            channel, self)
 369        '''
 370         GrantedResourceEntitlements enumerates the accounts that have been granted access to a given resource.
 371         The GrantedResourceEntitlements service is read-only.
 372
 373        See `strongdm.svc.GrantedResourceEntitlements`.
 374        '''
 375        self.granted_role_entitlements = svc.GrantedRoleEntitlements(
 376            channel, self)
 377        '''
 378         GrantedRoleEntitlements enumerates the resources to which a role grants access.
 379         The GrantedRoleEntitlements service is read-only.
 380
 381        See `strongdm.svc.GrantedRoleEntitlements`.
 382        '''
 383        self.roles = svc.Roles(channel, self)
 384        '''
 385         A Role has a list of access rules which determine which Resources the members
 386         of the Role have access to. An Account can be a member of multiple Roles via
 387         AccountAttachments.
 388
 389        See `strongdm.svc.Roles`.
 390        '''
 391        self.groups = svc.Groups(channel, self)
 392        '''
 393         A Group is a set of principals.
 394
 395        See `strongdm.svc.Groups`.
 396        '''
 397        self.groups_history = svc.GroupsHistory(channel, self)
 398        '''
 399         GroupsHistory records all changes to the state of a Group.
 400
 401        See `strongdm.svc.GroupsHistory`.
 402        '''
 403        self.groups_roles = svc.GroupsRoles(channel, self)
 404        '''
 405         A GroupRole is an assignment of a Group to a Role.
 406
 407        See `strongdm.svc.GroupsRoles`.
 408        '''
 409        self.groups_roles_history = svc.GroupsRolesHistory(channel, self)
 410        '''
 411         GroupsRolesHistory records all changes to the state of a GroupRole.
 412
 413        See `strongdm.svc.GroupsRolesHistory`.
 414        '''
 415        self.health_checks = svc.HealthChecks(channel, self)
 416        '''
 417         HealthChecks lists the last healthcheck between each node and resource.
 418         Note the unconventional capitalization here is to prevent having a collision with GRPC
 419
 420        See `strongdm.svc.HealthChecks`.
 421        '''
 422        self.identity_aliases = svc.IdentityAliases(channel, self)
 423        '''
 424         IdentityAliases assign an alias to an account within an IdentitySet.
 425         The alias is used as the username when connecting to a identity supported resource.
 426
 427        See `strongdm.svc.IdentityAliases`.
 428        '''
 429        self.identity_aliases_history = svc.IdentityAliasesHistory(
 430            channel, self)
 431        '''
 432         IdentityAliasesHistory records all changes to the state of a IdentityAlias.
 433
 434        See `strongdm.svc.IdentityAliasesHistory`.
 435        '''
 436        self.identity_sets = svc.IdentitySets(channel, self)
 437        '''
 438         A IdentitySet is a named grouping of Identity Aliases for Accounts.
 439         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
 440
 441        See `strongdm.svc.IdentitySets`.
 442        '''
 443        self.identity_sets_history = svc.IdentitySetsHistory(channel, self)
 444        '''
 445         IdentitySetsHistory records all changes to the state of a IdentitySet.
 446
 447        See `strongdm.svc.IdentitySetsHistory`.
 448        '''
 449        self.managed_secrets = svc.ManagedSecrets(channel, self)
 450        '''
 451         ManagedSecret is a private vertical for creating, reading, updating,
 452         deleting, listing and rotating the managed secrets in the secrets engines as
 453         an authenticated user.
 454
 455        See `strongdm.svc.ManagedSecrets`.
 456        '''
 457        self.nodes = svc.Nodes(channel, self)
 458        '''
 459         Nodes make up the StrongDM network, and allow your users to connect securely to your resources.
 460         There are three types of nodes:
 461         1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
 462         2. **Gateway:** a relay that also listens for connections from StrongDM clients
 463         3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources
 464
 465        See `strongdm.svc.Nodes`.
 466        '''
 467        self.nodes_history = svc.NodesHistory(channel, self)
 468        '''
 469         NodesHistory records all changes to the state of a Node.
 470
 471        See `strongdm.svc.NodesHistory`.
 472        '''
 473        self.organization_history = svc.OrganizationHistory(channel, self)
 474        '''
 475         OrganizationHistory records all changes to the state of an Organization.
 476
 477        See `strongdm.svc.OrganizationHistory`.
 478        '''
 479        self.peering_group_nodes = svc.PeeringGroupNodes(channel, self)
 480        '''
 481         PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.
 482
 483        See `strongdm.svc.PeeringGroupNodes`.
 484        '''
 485        self.peering_group_peers = svc.PeeringGroupPeers(channel, self)
 486        '''
 487         PeeringGroupPeers provides the building blocks necessary to link two peering groups.
 488
 489        See `strongdm.svc.PeeringGroupPeers`.
 490        '''
 491        self.peering_group_resources = svc.PeeringGroupResources(channel, self)
 492        '''
 493         PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.
 494
 495        See `strongdm.svc.PeeringGroupResources`.
 496        '''
 497        self.peering_groups = svc.PeeringGroups(channel, self)
 498        '''
 499         PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.
 500
 501        See `strongdm.svc.PeeringGroups`.
 502        '''
 503        self.policies = svc.Policies(channel, self)
 504        '''
 505         Policies are the collection of one or more statements that enforce fine-grained access
 506         control for the users of an organization.
 507
 508        See `strongdm.svc.Policies`.
 509        '''
 510        self.policies_history = svc.PoliciesHistory(channel, self)
 511        '''
 512         PoliciesHistory records all changes to the state of a Policy.
 513
 514        See `strongdm.svc.PoliciesHistory`.
 515        '''
 516        self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self)
 517        '''
 518         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
 519         The proxies within a cluster share the same key. One cluster can have
 520         multiple keys in order to facilitate key rotation.
 521
 522        See `strongdm.svc.ProxyClusterKeys`.
 523        '''
 524        self.queries = svc.Queries(channel, self)
 525        '''
 526         A Query is a record of a single client request to a resource, such as a SQL query.
 527         Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries.
 528         The Queries service is read-only.
 529
 530        See `strongdm.svc.Queries`.
 531        '''
 532        self.remote_identities = svc.RemoteIdentities(channel, self)
 533        '''
 534         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
 535
 536        See `strongdm.svc.RemoteIdentities`.
 537        '''
 538        self.remote_identities_history = svc.RemoteIdentitiesHistory(
 539            channel, self)
 540        '''
 541         RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
 542
 543        See `strongdm.svc.RemoteIdentitiesHistory`.
 544        '''
 545        self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self)
 546        '''
 547         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
 548         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
 549
 550        See `strongdm.svc.RemoteIdentityGroups`.
 551        '''
 552        self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory(
 553            channel, self)
 554        '''
 555         RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
 556
 557        See `strongdm.svc.RemoteIdentityGroupsHistory`.
 558        '''
 559        self.replays = svc.Replays(channel, self)
 560        '''
 561         A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session
 562         (otherwise referred to as a query). The Replays service is read-only.
 563
 564        See `strongdm.svc.Replays`.
 565        '''
 566        self.resources = svc.Resources(channel, self)
 567        '''
 568         Resources are databases, servers, clusters, websites, or clouds that strongDM
 569         delegates access to.
 570
 571        See `strongdm.svc.Resources`.
 572        '''
 573        self.resources_history = svc.ResourcesHistory(channel, self)
 574        '''
 575         ResourcesHistory records all changes to the state of a Resource.
 576
 577        See `strongdm.svc.ResourcesHistory`.
 578        '''
 579        self.role_resources = svc.RoleResources(channel, self)
 580        '''
 581         RoleResources enumerates the resources to which roles have access.
 582         The RoleResources service is read-only.
 583
 584        See `strongdm.svc.RoleResources`.
 585        '''
 586        self.role_resources_history = svc.RoleResourcesHistory(channel, self)
 587        '''
 588         RoleResourcesHistory records all changes to the state of a RoleResource.
 589
 590        See `strongdm.svc.RoleResourcesHistory`.
 591        '''
 592        self.roles_history = svc.RolesHistory(channel, self)
 593        '''
 594         RolesHistory records all changes to the state of a Role.
 595
 596        See `strongdm.svc.RolesHistory`.
 597        '''
 598        self.secret_stores = svc.SecretStores(channel, self)
 599        '''
 600         SecretStores are servers where resource secrets (passwords, keys) are stored.
 601
 602        See `strongdm.svc.SecretStores`.
 603        '''
 604        self.secret_engines = svc.SecretEngines(channel, self)
 605        '''
 606
 607
 608        See `strongdm.svc.SecretEngines`.
 609        '''
 610        self.secret_store_healths = svc.SecretStoreHealths(channel, self)
 611        '''
 612         SecretStoreHealths exposes health states for secret stores.
 613
 614        See `strongdm.svc.SecretStoreHealths`.
 615        '''
 616        self.secret_stores_history = svc.SecretStoresHistory(channel, self)
 617        '''
 618         SecretStoresHistory records all changes to the state of a SecretStore.
 619
 620        See `strongdm.svc.SecretStoresHistory`.
 621        '''
 622        self.workflow_approvers = svc.WorkflowApprovers(channel, self)
 623        '''
 624         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
 625
 626        See `strongdm.svc.WorkflowApprovers`.
 627        '''
 628        self.workflow_approvers_history = svc.WorkflowApproversHistory(
 629            channel, self)
 630        '''
 631         WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.
 632
 633        See `strongdm.svc.WorkflowApproversHistory`.
 634        '''
 635        self.workflow_roles = svc.WorkflowRoles(channel, self)
 636        '''
 637         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
 638         to request access to a resource via the workflow.
 639
 640        See `strongdm.svc.WorkflowRoles`.
 641        '''
 642        self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self)
 643        '''
 644         WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole
 645
 646        See `strongdm.svc.WorkflowRolesHistory`.
 647        '''
 648        self.workflows = svc.Workflows(channel, self)
 649        '''
 650         Workflows are the collection of rules that define the resources to which access can be requested,
 651         the users that can request that access, and the mechanism for approving those requests which can either
 652         be automatic approval or a set of users authorized to approve the requests.
 653
 654        See `strongdm.svc.Workflows`.
 655        '''
 656        self.workflows_history = svc.WorkflowsHistory(channel, self)
 657        '''
 658         WorkflowsHistory provides records of all changes to the state of a Workflow.
 659
 660        See `strongdm.svc.WorkflowsHistory`.
 661        '''
 662
 663    def close(self):
 664        '''Closes this Client and releases all resources held by it.
 665
 666        Closing the Client will immediately terminate all RPCs active with the
 667        Client and it is not valid to invoke new RPCs with the Client.
 668
 669        This method is idempotent.
 670        '''
 671        self.channel.close()
 672
 673    def get_metadata(self, method_name, req):
 674        return [
 675            ('x-sdm-authentication', self.api_access_key),
 676            ('x-sdm-signature', self.sign(method_name,
 677                                          req.SerializeToString())),
 678            ('x-sdm-api-version', API_VERSION),
 679            ('x-sdm-user-agent', USER_AGENT),
 680        ]
 681
 682    def sign(self, method_name, request_bytes):
 683        def hmac_digest(key, msg_byte_string):
 684            return hmac.new(key, msg=msg_byte_string,
 685                            digestmod=hashlib.sha256).digest()
 686
 687        current_utc_date = datetime.datetime.now(
 688            datetime.timezone.utc).strftime('%Y-%m-%d')
 689        signing_key = hmac_digest(self.api_secret, current_utc_date.encode())
 690        signing_key = hmac_digest(signing_key, b'sdm_api_v1')
 691
 692        hash = hashlib.sha256()
 693
 694        hash.update(method_name.encode())
 695        hash.update(b'\n')
 696        hash.update(request_bytes)
 697
 698        return base64.b64encode(hmac_digest(signing_key, hash.digest()))
 699
 700    def exponentialBackoff(self, retries, deadline=None):
 701        def applyDeadline(delay, deadline):
 702            if deadline is None:
 703                return delay
 704            remaining = deadline - time.time()
 705            if remaining < 0:
 706                return 0
 707            return min(delay, remaining)
 708
 709        if retries == 0:
 710            return applyDeadline(self.base_retry_delay, deadline)
 711
 712        backoff, max_delay = self.base_retry_delay, self.max_retry_delay
 713        while backoff < max_delay and retries > 0:
 714            backoff *= self.retry_factor
 715            retries -= 1
 716
 717        if backoff > max_delay:
 718            backoff = max_delay
 719
 720        # Randomize backoff delays so that if a cluster of requests start at
 721        # the same time, they won't operate in lockstep.
 722        backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1)
 723        if backoff < 0:
 724            return 0
 725
 726        return applyDeadline(backoff, deadline)
 727
 728    def shouldRetry(self, retries, err, deadline=None):
 729        # Check if we've passed the deadline
 730        if deadline is not None and time.time() >= deadline:
 731            return False
 732
 733        if not isinstance(err, grpc.RpcError):
 734            return False
 735
 736        if self.retry_rate_limit_errors and err.code(
 737        ) == grpc.StatusCode.RESOURCE_EXHAUSTED:
 738            return True
 739
 740        return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL
 741                                 or err.code() == grpc.StatusCode.UNAVAILABLE)
 742
 743    def snapshot_at(self, snapshot_datetime):
 744        '''
 745        Constructs a read-only client that will provide historical data from the provided timestamp.
 746
 747        See `SnapshotClient`.
 748        '''
 749        client = copy.copy(self)
 750        client.snapshot_datetime = snapshot_datetime
 751        client.access_requests = svc.AccessRequests(client.channel, client)
 752        client.account_attachments = svc.AccountAttachments(
 753            client.channel, client)
 754        client.account_grants = svc.AccountGrants(client.channel, client)
 755        client.account_permissions = svc.AccountPermissions(
 756            client.channel, client)
 757        client.account_resources = svc.AccountResources(client.channel, client)
 758        client.accounts = svc.Accounts(client.channel, client)
 759        client.accounts_groups = svc.AccountsGroups(client.channel, client)
 760        client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
 761            client.channel, client)
 762        client.approval_workflow_steps = svc.ApprovalWorkflowSteps(
 763            client.channel, client)
 764        client.approval_workflows = svc.ApprovalWorkflows(
 765            client.channel, client)
 766        client.discovery_connectors = svc.DiscoveryConnectors(
 767            client.channel, client)
 768        client.granted_account_entitlements = svc.GrantedAccountEntitlements(
 769            client.channel, client)
 770        client.granted_resource_entitlements = svc.GrantedResourceEntitlements(
 771            client.channel, client)
 772        client.granted_role_entitlements = svc.GrantedRoleEntitlements(
 773            client.channel, client)
 774        client.roles = svc.Roles(client.channel, client)
 775        client.groups = svc.Groups(client.channel, client)
 776        client.groups_roles = svc.GroupsRoles(client.channel, client)
 777        client.identity_aliases = svc.IdentityAliases(client.channel, client)
 778        client.identity_sets = svc.IdentitySets(client.channel, client)
 779        client.nodes = svc.Nodes(client.channel, client)
 780        client.policies = svc.Policies(client.channel, client)
 781        client.proxy_cluster_keys = svc.ProxyClusterKeys(
 782            client.channel, client)
 783        client.remote_identities = svc.RemoteIdentities(client.channel, client)
 784        client.remote_identity_groups = svc.RemoteIdentityGroups(
 785            client.channel, client)
 786        client.resources = svc.Resources(client.channel, client)
 787        client.role_resources = svc.RoleResources(client.channel, client)
 788        client.secret_stores = svc.SecretStores(client.channel, client)
 789        client.workflow_approvers = svc.WorkflowApprovers(
 790            client.channel, client)
 791        client.workflow_roles = svc.WorkflowRoles(client.channel, client)
 792        client.workflows = svc.Workflows(client.channel, client)
 793        return SnapshotClient(client)
 794
 795
 796class SnapshotClient:
 797    '''SnapshotClient exposes methods to query historical records at a provided timestamp.'''
 798    def __init__(self, client):
 799        self.access_requests = svc.SnapshotAccessRequests(
 800            client.access_requests)
 801        '''
 802         AccessRequests are requests for access to a resource that may match a Workflow.
 803
 804        See `strongdm.svc.SnapshotAccessRequests`.
 805        '''
 806        self.account_attachments = svc.SnapshotAccountAttachments(
 807            client.account_attachments)
 808        '''
 809         AccountAttachments assign an account to a role.
 810
 811        See `strongdm.svc.SnapshotAccountAttachments`.
 812        '''
 813        self.account_grants = svc.SnapshotAccountGrants(client.account_grants)
 814        '''
 815         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
 816
 817        See `strongdm.svc.SnapshotAccountGrants`.
 818        '''
 819        self.account_permissions = svc.SnapshotAccountPermissions(
 820            client.account_permissions)
 821        '''
 822         AccountPermissions records the granular permissions accounts have, allowing them to execute
 823         relevant commands via StrongDM's APIs.
 824
 825        See `strongdm.svc.SnapshotAccountPermissions`.
 826        '''
 827        self.account_resources = svc.SnapshotAccountResources(
 828            client.account_resources)
 829        '''
 830         AccountResources enumerates the resources to which accounts have access.
 831         The AccountResources service is read-only.
 832
 833        See `strongdm.svc.SnapshotAccountResources`.
 834        '''
 835        self.accounts = svc.SnapshotAccounts(client.accounts)
 836        '''
 837         Accounts are users that have access to strongDM. There are two types of accounts:
 838         1. **Users:** humans who are authenticated through username and password or SSO.
 839         2. **Service Accounts:** machines that are authenticated using a service token.
 840         3. **Tokens** are access keys with permissions that can be used for authentication.
 841
 842        See `strongdm.svc.SnapshotAccounts`.
 843        '''
 844        self.accounts_groups = svc.SnapshotAccountsGroups(
 845            client.accounts_groups)
 846        '''
 847         An AccountGroup links an account and a group.
 848
 849        See `strongdm.svc.SnapshotAccountsGroups`.
 850        '''
 851        self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers(
 852            client.approval_workflow_approvers)
 853        '''
 854         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
 855
 856        See `strongdm.svc.SnapshotApprovalWorkflowApprovers`.
 857        '''
 858        self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps(
 859            client.approval_workflow_steps)
 860        '''
 861         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
 862
 863        See `strongdm.svc.SnapshotApprovalWorkflowSteps`.
 864        '''
 865        self.approval_workflows = svc.SnapshotApprovalWorkflows(
 866            client.approval_workflows)
 867        '''
 868         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
 869         approvers and be approved or denied.
 870
 871        See `strongdm.svc.SnapshotApprovalWorkflows`.
 872        '''
 873        self.discovery_connectors = svc.SnapshotDiscoveryConnectors(
 874            client.discovery_connectors)
 875        '''
 876         A Discovery Connector is a configuration object for performing Resource
 877         Scans in remote systems such as AWS, GCP, Azure, and other systems.
 878
 879        See `strongdm.svc.SnapshotDiscoveryConnectors`.
 880        '''
 881        self.granted_account_entitlements = svc.SnapshotGrantedAccountEntitlements(
 882            client.granted_account_entitlements)
 883        '''
 884         GrantedAccountEntitlements enumerates the resources to which an account has been granted access.
 885         The GrantedAccountEntitlements service is read-only.
 886
 887        See `strongdm.svc.SnapshotGrantedAccountEntitlements`.
 888        '''
 889        self.granted_resource_entitlements = svc.SnapshotGrantedResourceEntitlements(
 890            client.granted_resource_entitlements)
 891        '''
 892         GrantedResourceEntitlements enumerates the accounts that have been granted access to a given resource.
 893         The GrantedResourceEntitlements service is read-only.
 894
 895        See `strongdm.svc.SnapshotGrantedResourceEntitlements`.
 896        '''
 897        self.granted_role_entitlements = svc.SnapshotGrantedRoleEntitlements(
 898            client.granted_role_entitlements)
 899        '''
 900         GrantedRoleEntitlements enumerates the resources to which a role grants access.
 901         The GrantedRoleEntitlements service is read-only.
 902
 903        See `strongdm.svc.SnapshotGrantedRoleEntitlements`.
 904        '''
 905        self.roles = svc.SnapshotRoles(client.roles)
 906        '''
 907         A Role has a list of access rules which determine which Resources the members
 908         of the Role have access to. An Account can be a member of multiple Roles via
 909         AccountAttachments.
 910
 911        See `strongdm.svc.SnapshotRoles`.
 912        '''
 913        self.groups = svc.SnapshotGroups(client.groups)
 914        '''
 915         A Group is a set of principals.
 916
 917        See `strongdm.svc.SnapshotGroups`.
 918        '''
 919        self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles)
 920        '''
 921         A GroupRole is an assignment of a Group to a Role.
 922
 923        See `strongdm.svc.SnapshotGroupsRoles`.
 924        '''
 925        self.identity_aliases = svc.SnapshotIdentityAliases(
 926            client.identity_aliases)
 927        '''
 928         IdentityAliases assign an alias to an account within an IdentitySet.
 929         The alias is used as the username when connecting to a identity supported resource.
 930
 931        See `strongdm.svc.SnapshotIdentityAliases`.
 932        '''
 933        self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets)
 934        '''
 935         A IdentitySet is a named grouping of Identity Aliases for Accounts.
 936         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
 937
 938        See `strongdm.svc.SnapshotIdentitySets`.
 939        '''
 940        self.nodes = svc.SnapshotNodes(client.nodes)
 941        '''
 942         Nodes make up the StrongDM network, and allow your users to connect securely to your resources.
 943         There are three types of nodes:
 944         1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
 945         2. **Gateway:** a relay that also listens for connections from StrongDM clients
 946         3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources
 947
 948        See `strongdm.svc.SnapshotNodes`.
 949        '''
 950        self.policies = svc.SnapshotPolicies(client.policies)
 951        '''
 952         Policies are the collection of one or more statements that enforce fine-grained access
 953         control for the users of an organization.
 954
 955        See `strongdm.svc.SnapshotPolicies`.
 956        '''
 957        self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys(
 958            client.proxy_cluster_keys)
 959        '''
 960         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
 961         The proxies within a cluster share the same key. One cluster can have
 962         multiple keys in order to facilitate key rotation.
 963
 964        See `strongdm.svc.SnapshotProxyClusterKeys`.
 965        '''
 966        self.remote_identities = svc.SnapshotRemoteIdentities(
 967            client.remote_identities)
 968        '''
 969         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
 970
 971        See `strongdm.svc.SnapshotRemoteIdentities`.
 972        '''
 973        self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups(
 974            client.remote_identity_groups)
 975        '''
 976         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
 977         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
 978
 979        See `strongdm.svc.SnapshotRemoteIdentityGroups`.
 980        '''
 981        self.resources = svc.SnapshotResources(client.resources)
 982        '''
 983         Resources are databases, servers, clusters, websites, or clouds that strongDM
 984         delegates access to.
 985
 986        See `strongdm.svc.SnapshotResources`.
 987        '''
 988        self.role_resources = svc.SnapshotRoleResources(client.role_resources)
 989        '''
 990         RoleResources enumerates the resources to which roles have access.
 991         The RoleResources service is read-only.
 992
 993        See `strongdm.svc.SnapshotRoleResources`.
 994        '''
 995        self.secret_stores = svc.SnapshotSecretStores(client.secret_stores)
 996        '''
 997         SecretStores are servers where resource secrets (passwords, keys) are stored.
 998
 999        See `strongdm.svc.SnapshotSecretStores`.
1000        '''
1001        self.workflow_approvers = svc.SnapshotWorkflowApprovers(
1002            client.workflow_approvers)
1003        '''
1004         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
1005
1006        See `strongdm.svc.SnapshotWorkflowApprovers`.
1007        '''
1008        self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles)
1009        '''
1010         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
1011         to request access to a resource via the workflow.
1012
1013        See `strongdm.svc.SnapshotWorkflowRoles`.
1014        '''
1015        self.workflows = svc.SnapshotWorkflows(client.workflows)
1016        '''
1017         Workflows are the collection of rules that define the resources to which access can be requested,
1018         the users that can request that access, and the mechanism for approving those requests which can either
1019         be automatic approval or a set of users authorized to approve the requests.
1020
1021        See `strongdm.svc.SnapshotWorkflows`.
1022        '''
class Client:
171class Client:
172    '''Client interacts with the strongDM API.'''
173    def __init__(self,
174                 api_access_key,
175                 api_secret,
176                 host='app.strongdm.com:443',
177                 insecure=False,
178                 retry_rate_limit_errors=True,
179                 page_limit=0):
180        '''
181        Create a new Client.
182
183        - api_access_key: the access key to authenticate with strongDM
184        - api_secret: the secret key to authenticate with strongDM
185        '''
186        self.api_access_key = api_access_key.strip()
187        self.api_secret = base64.b64decode(api_secret.strip())
188        self.base_retry_delay = DEFAULT_BASE_RETRY_DELAY
189        self.max_retry_delay = DEFAULT_MAX_RETRY_DELAY
190        self.retry_factor = DEFAULT_RETRY_FACTOR
191        self.retry_jitter = DEFAULT_RETRY_JITTER
192        self.retry_rate_limit_errors = retry_rate_limit_errors
193        self.snapshot_datetime = None
194        self.page_limit = page_limit
195
196        try:
197            if insecure:
198                channel = grpc.insecure_channel(host)
199            else:
200                creds = grpc.ssl_channel_credentials()
201                channel = grpc.secure_channel(host, creds)
202        except Exception as e:
203            raise plumbing.convert_error_to_porcelain(e) from e
204        channel = grpc.intercept_channel(channel, _EncryptionInterceptor(self))
205        self.channel = channel
206        self.access_requests = svc.AccessRequests(channel, self)
207        '''
208         AccessRequests are requests for access to a resource that may match a Workflow.
209
210        See `strongdm.svc.AccessRequests`.
211        '''
212        self.access_request_events_history = svc.AccessRequestEventsHistory(
213            channel, self)
214        '''
215         AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.
216
217        See `strongdm.svc.AccessRequestEventsHistory`.
218        '''
219        self.access_requests_history = svc.AccessRequestsHistory(channel, self)
220        '''
221         AccessRequestsHistory provides records of all changes to the state of an AccessRequest.
222
223        See `strongdm.svc.AccessRequestsHistory`.
224        '''
225        self.account_attachments = svc.AccountAttachments(channel, self)
226        '''
227         AccountAttachments assign an account to a role.
228
229        See `strongdm.svc.AccountAttachments`.
230        '''
231        self.account_attachments_history = svc.AccountAttachmentsHistory(
232            channel, self)
233        '''
234         AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
235
236        See `strongdm.svc.AccountAttachmentsHistory`.
237        '''
238        self.account_grants = svc.AccountGrants(channel, self)
239        '''
240         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
241
242        See `strongdm.svc.AccountGrants`.
243        '''
244        self.account_grants_history = svc.AccountGrantsHistory(channel, self)
245        '''
246         AccountGrantsHistory records all changes to the state of an AccountGrant.
247
248        See `strongdm.svc.AccountGrantsHistory`.
249        '''
250        self.account_permissions = svc.AccountPermissions(channel, self)
251        '''
252         AccountPermissions records the granular permissions accounts have, allowing them to execute
253         relevant commands via StrongDM's APIs.
254
255        See `strongdm.svc.AccountPermissions`.
256        '''
257        self.account_resources = svc.AccountResources(channel, self)
258        '''
259         AccountResources enumerates the resources to which accounts have access.
260         The AccountResources service is read-only.
261
262        See `strongdm.svc.AccountResources`.
263        '''
264        self.account_resources_history = svc.AccountResourcesHistory(
265            channel, self)
266        '''
267         AccountResourcesHistory records all changes to the state of a AccountResource.
268
269        See `strongdm.svc.AccountResourcesHistory`.
270        '''
271        self.accounts = svc.Accounts(channel, self)
272        '''
273         Accounts are users that have access to strongDM. There are two types of accounts:
274         1. **Users:** humans who are authenticated through username and password or SSO.
275         2. **Service Accounts:** machines that are authenticated using a service token.
276         3. **Tokens** are access keys with permissions that can be used for authentication.
277
278        See `strongdm.svc.Accounts`.
279        '''
280        self.accounts_groups = svc.AccountsGroups(channel, self)
281        '''
282         An AccountGroup links an account and a group.
283
284        See `strongdm.svc.AccountsGroups`.
285        '''
286        self.accounts_groups_history = svc.AccountsGroupsHistory(channel, self)
287        '''
288         AccountsGroupsHistory records all changes to the state of an AccountGroup.
289
290        See `strongdm.svc.AccountsGroupsHistory`.
291        '''
292        self.accounts_history = svc.AccountsHistory(channel, self)
293        '''
294         AccountsHistory records all changes to the state of an Account.
295
296        See `strongdm.svc.AccountsHistory`.
297        '''
298        self.activities = svc.Activities(channel, self)
299        '''
300         An Activity is a record of an action taken against a strongDM deployment, e.g.
301         a user creation, resource deletion, sso configuration change, etc. The Activities
302         service is read-only.
303
304        See `strongdm.svc.Activities`.
305        '''
306        self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
307            channel, self)
308        '''
309         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
310
311        See `strongdm.svc.ApprovalWorkflowApprovers`.
312        '''
313        self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory(
314            channel, self)
315        '''
316         ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.
317
318        See `strongdm.svc.ApprovalWorkflowApproversHistory`.
319        '''
320        self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self)
321        '''
322         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
323
324        See `strongdm.svc.ApprovalWorkflowSteps`.
325        '''
326        self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory(
327            channel, self)
328        '''
329         ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.
330
331        See `strongdm.svc.ApprovalWorkflowStepsHistory`.
332        '''
333        self.approval_workflows = svc.ApprovalWorkflows(channel, self)
334        '''
335         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
336         approvers and be approved or denied.
337
338        See `strongdm.svc.ApprovalWorkflows`.
339        '''
340        self.approval_workflows_history = svc.ApprovalWorkflowsHistory(
341            channel, self)
342        '''
343         ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.
344
345        See `strongdm.svc.ApprovalWorkflowsHistory`.
346        '''
347        self.control_panel = svc.ControlPanel(channel, self)
348        '''
349         ControlPanel contains all administrative controls.
350
351        See `strongdm.svc.ControlPanel`.
352        '''
353        self.discovery_connectors = svc.DiscoveryConnectors(channel, self)
354        '''
355         A Discovery Connector is a configuration object for performing Resource
356         Scans in remote systems such as AWS, GCP, Azure, and other systems.
357
358        See `strongdm.svc.DiscoveryConnectors`.
359        '''
360        self.granted_account_entitlements = svc.GrantedAccountEntitlements(
361            channel, self)
362        '''
363         GrantedAccountEntitlements enumerates the resources to which an account has been granted access.
364         The GrantedAccountEntitlements service is read-only.
365
366        See `strongdm.svc.GrantedAccountEntitlements`.
367        '''
368        self.granted_resource_entitlements = svc.GrantedResourceEntitlements(
369            channel, self)
370        '''
371         GrantedResourceEntitlements enumerates the accounts that have been granted access to a given resource.
372         The GrantedResourceEntitlements service is read-only.
373
374        See `strongdm.svc.GrantedResourceEntitlements`.
375        '''
376        self.granted_role_entitlements = svc.GrantedRoleEntitlements(
377            channel, self)
378        '''
379         GrantedRoleEntitlements enumerates the resources to which a role grants access.
380         The GrantedRoleEntitlements service is read-only.
381
382        See `strongdm.svc.GrantedRoleEntitlements`.
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.groups = svc.Groups(channel, self)
393        '''
394         A Group is a set of principals.
395
396        See `strongdm.svc.Groups`.
397        '''
398        self.groups_history = svc.GroupsHistory(channel, self)
399        '''
400         GroupsHistory records all changes to the state of a Group.
401
402        See `strongdm.svc.GroupsHistory`.
403        '''
404        self.groups_roles = svc.GroupsRoles(channel, self)
405        '''
406         A GroupRole is an assignment of a Group to a Role.
407
408        See `strongdm.svc.GroupsRoles`.
409        '''
410        self.groups_roles_history = svc.GroupsRolesHistory(channel, self)
411        '''
412         GroupsRolesHistory records all changes to the state of a GroupRole.
413
414        See `strongdm.svc.GroupsRolesHistory`.
415        '''
416        self.health_checks = svc.HealthChecks(channel, self)
417        '''
418         HealthChecks lists the last healthcheck between each node and resource.
419         Note the unconventional capitalization here is to prevent having a collision with GRPC
420
421        See `strongdm.svc.HealthChecks`.
422        '''
423        self.identity_aliases = svc.IdentityAliases(channel, self)
424        '''
425         IdentityAliases assign an alias to an account within an IdentitySet.
426         The alias is used as the username when connecting to a identity supported resource.
427
428        See `strongdm.svc.IdentityAliases`.
429        '''
430        self.identity_aliases_history = svc.IdentityAliasesHistory(
431            channel, self)
432        '''
433         IdentityAliasesHistory records all changes to the state of a IdentityAlias.
434
435        See `strongdm.svc.IdentityAliasesHistory`.
436        '''
437        self.identity_sets = svc.IdentitySets(channel, self)
438        '''
439         A IdentitySet is a named grouping of Identity Aliases for Accounts.
440         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
441
442        See `strongdm.svc.IdentitySets`.
443        '''
444        self.identity_sets_history = svc.IdentitySetsHistory(channel, self)
445        '''
446         IdentitySetsHistory records all changes to the state of a IdentitySet.
447
448        See `strongdm.svc.IdentitySetsHistory`.
449        '''
450        self.managed_secrets = svc.ManagedSecrets(channel, self)
451        '''
452         ManagedSecret is a private vertical for creating, reading, updating,
453         deleting, listing and rotating the managed secrets in the secrets engines as
454         an authenticated user.
455
456        See `strongdm.svc.ManagedSecrets`.
457        '''
458        self.nodes = svc.Nodes(channel, self)
459        '''
460         Nodes make up the StrongDM network, and allow your users to connect securely to your resources.
461         There are three types of nodes:
462         1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
463         2. **Gateway:** a relay that also listens for connections from StrongDM clients
464         3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources
465
466        See `strongdm.svc.Nodes`.
467        '''
468        self.nodes_history = svc.NodesHistory(channel, self)
469        '''
470         NodesHistory records all changes to the state of a Node.
471
472        See `strongdm.svc.NodesHistory`.
473        '''
474        self.organization_history = svc.OrganizationHistory(channel, self)
475        '''
476         OrganizationHistory records all changes to the state of an Organization.
477
478        See `strongdm.svc.OrganizationHistory`.
479        '''
480        self.peering_group_nodes = svc.PeeringGroupNodes(channel, self)
481        '''
482         PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.
483
484        See `strongdm.svc.PeeringGroupNodes`.
485        '''
486        self.peering_group_peers = svc.PeeringGroupPeers(channel, self)
487        '''
488         PeeringGroupPeers provides the building blocks necessary to link two peering groups.
489
490        See `strongdm.svc.PeeringGroupPeers`.
491        '''
492        self.peering_group_resources = svc.PeeringGroupResources(channel, self)
493        '''
494         PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.
495
496        See `strongdm.svc.PeeringGroupResources`.
497        '''
498        self.peering_groups = svc.PeeringGroups(channel, self)
499        '''
500         PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.
501
502        See `strongdm.svc.PeeringGroups`.
503        '''
504        self.policies = svc.Policies(channel, self)
505        '''
506         Policies are the collection of one or more statements that enforce fine-grained access
507         control for the users of an organization.
508
509        See `strongdm.svc.Policies`.
510        '''
511        self.policies_history = svc.PoliciesHistory(channel, self)
512        '''
513         PoliciesHistory records all changes to the state of a Policy.
514
515        See `strongdm.svc.PoliciesHistory`.
516        '''
517        self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self)
518        '''
519         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
520         The proxies within a cluster share the same key. One cluster can have
521         multiple keys in order to facilitate key rotation.
522
523        See `strongdm.svc.ProxyClusterKeys`.
524        '''
525        self.queries = svc.Queries(channel, self)
526        '''
527         A Query is a record of a single client request to a resource, such as a SQL query.
528         Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries.
529         The Queries service is read-only.
530
531        See `strongdm.svc.Queries`.
532        '''
533        self.remote_identities = svc.RemoteIdentities(channel, self)
534        '''
535         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
536
537        See `strongdm.svc.RemoteIdentities`.
538        '''
539        self.remote_identities_history = svc.RemoteIdentitiesHistory(
540            channel, self)
541        '''
542         RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
543
544        See `strongdm.svc.RemoteIdentitiesHistory`.
545        '''
546        self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self)
547        '''
548         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
549         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
550
551        See `strongdm.svc.RemoteIdentityGroups`.
552        '''
553        self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory(
554            channel, self)
555        '''
556         RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
557
558        See `strongdm.svc.RemoteIdentityGroupsHistory`.
559        '''
560        self.replays = svc.Replays(channel, self)
561        '''
562         A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session
563         (otherwise referred to as a query). The Replays service is read-only.
564
565        See `strongdm.svc.Replays`.
566        '''
567        self.resources = svc.Resources(channel, self)
568        '''
569         Resources are databases, servers, clusters, websites, or clouds that strongDM
570         delegates access to.
571
572        See `strongdm.svc.Resources`.
573        '''
574        self.resources_history = svc.ResourcesHistory(channel, self)
575        '''
576         ResourcesHistory records all changes to the state of a Resource.
577
578        See `strongdm.svc.ResourcesHistory`.
579        '''
580        self.role_resources = svc.RoleResources(channel, self)
581        '''
582         RoleResources enumerates the resources to which roles have access.
583         The RoleResources service is read-only.
584
585        See `strongdm.svc.RoleResources`.
586        '''
587        self.role_resources_history = svc.RoleResourcesHistory(channel, self)
588        '''
589         RoleResourcesHistory records all changes to the state of a RoleResource.
590
591        See `strongdm.svc.RoleResourcesHistory`.
592        '''
593        self.roles_history = svc.RolesHistory(channel, self)
594        '''
595         RolesHistory records all changes to the state of a Role.
596
597        See `strongdm.svc.RolesHistory`.
598        '''
599        self.secret_stores = svc.SecretStores(channel, self)
600        '''
601         SecretStores are servers where resource secrets (passwords, keys) are stored.
602
603        See `strongdm.svc.SecretStores`.
604        '''
605        self.secret_engines = svc.SecretEngines(channel, self)
606        '''
607
608
609        See `strongdm.svc.SecretEngines`.
610        '''
611        self.secret_store_healths = svc.SecretStoreHealths(channel, self)
612        '''
613         SecretStoreHealths exposes health states for secret stores.
614
615        See `strongdm.svc.SecretStoreHealths`.
616        '''
617        self.secret_stores_history = svc.SecretStoresHistory(channel, self)
618        '''
619         SecretStoresHistory records all changes to the state of a SecretStore.
620
621        See `strongdm.svc.SecretStoresHistory`.
622        '''
623        self.workflow_approvers = svc.WorkflowApprovers(channel, self)
624        '''
625         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
626
627        See `strongdm.svc.WorkflowApprovers`.
628        '''
629        self.workflow_approvers_history = svc.WorkflowApproversHistory(
630            channel, self)
631        '''
632         WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.
633
634        See `strongdm.svc.WorkflowApproversHistory`.
635        '''
636        self.workflow_roles = svc.WorkflowRoles(channel, self)
637        '''
638         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
639         to request access to a resource via the workflow.
640
641        See `strongdm.svc.WorkflowRoles`.
642        '''
643        self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self)
644        '''
645         WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole
646
647        See `strongdm.svc.WorkflowRolesHistory`.
648        '''
649        self.workflows = svc.Workflows(channel, self)
650        '''
651         Workflows are the collection of rules that define the resources to which access can be requested,
652         the users that can request that access, and the mechanism for approving those requests which can either
653         be automatic approval or a set of users authorized to approve the requests.
654
655        See `strongdm.svc.Workflows`.
656        '''
657        self.workflows_history = svc.WorkflowsHistory(channel, self)
658        '''
659         WorkflowsHistory provides records of all changes to the state of a Workflow.
660
661        See `strongdm.svc.WorkflowsHistory`.
662        '''
663
664    def close(self):
665        '''Closes this Client and releases all resources held by it.
666
667        Closing the Client will immediately terminate all RPCs active with the
668        Client and it is not valid to invoke new RPCs with the Client.
669
670        This method is idempotent.
671        '''
672        self.channel.close()
673
674    def get_metadata(self, method_name, req):
675        return [
676            ('x-sdm-authentication', self.api_access_key),
677            ('x-sdm-signature', self.sign(method_name,
678                                          req.SerializeToString())),
679            ('x-sdm-api-version', API_VERSION),
680            ('x-sdm-user-agent', USER_AGENT),
681        ]
682
683    def sign(self, method_name, request_bytes):
684        def hmac_digest(key, msg_byte_string):
685            return hmac.new(key, msg=msg_byte_string,
686                            digestmod=hashlib.sha256).digest()
687
688        current_utc_date = datetime.datetime.now(
689            datetime.timezone.utc).strftime('%Y-%m-%d')
690        signing_key = hmac_digest(self.api_secret, current_utc_date.encode())
691        signing_key = hmac_digest(signing_key, b'sdm_api_v1')
692
693        hash = hashlib.sha256()
694
695        hash.update(method_name.encode())
696        hash.update(b'\n')
697        hash.update(request_bytes)
698
699        return base64.b64encode(hmac_digest(signing_key, hash.digest()))
700
701    def exponentialBackoff(self, retries, deadline=None):
702        def applyDeadline(delay, deadline):
703            if deadline is None:
704                return delay
705            remaining = deadline - time.time()
706            if remaining < 0:
707                return 0
708            return min(delay, remaining)
709
710        if retries == 0:
711            return applyDeadline(self.base_retry_delay, deadline)
712
713        backoff, max_delay = self.base_retry_delay, self.max_retry_delay
714        while backoff < max_delay and retries > 0:
715            backoff *= self.retry_factor
716            retries -= 1
717
718        if backoff > max_delay:
719            backoff = max_delay
720
721        # Randomize backoff delays so that if a cluster of requests start at
722        # the same time, they won't operate in lockstep.
723        backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1)
724        if backoff < 0:
725            return 0
726
727        return applyDeadline(backoff, deadline)
728
729    def shouldRetry(self, retries, err, deadline=None):
730        # Check if we've passed the deadline
731        if deadline is not None and time.time() >= deadline:
732            return False
733
734        if not isinstance(err, grpc.RpcError):
735            return False
736
737        if self.retry_rate_limit_errors and err.code(
738        ) == grpc.StatusCode.RESOURCE_EXHAUSTED:
739            return True
740
741        return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL
742                                 or err.code() == grpc.StatusCode.UNAVAILABLE)
743
744    def snapshot_at(self, snapshot_datetime):
745        '''
746        Constructs a read-only client that will provide historical data from the provided timestamp.
747
748        See `SnapshotClient`.
749        '''
750        client = copy.copy(self)
751        client.snapshot_datetime = snapshot_datetime
752        client.access_requests = svc.AccessRequests(client.channel, client)
753        client.account_attachments = svc.AccountAttachments(
754            client.channel, client)
755        client.account_grants = svc.AccountGrants(client.channel, client)
756        client.account_permissions = svc.AccountPermissions(
757            client.channel, client)
758        client.account_resources = svc.AccountResources(client.channel, client)
759        client.accounts = svc.Accounts(client.channel, client)
760        client.accounts_groups = svc.AccountsGroups(client.channel, client)
761        client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
762            client.channel, client)
763        client.approval_workflow_steps = svc.ApprovalWorkflowSteps(
764            client.channel, client)
765        client.approval_workflows = svc.ApprovalWorkflows(
766            client.channel, client)
767        client.discovery_connectors = svc.DiscoveryConnectors(
768            client.channel, client)
769        client.granted_account_entitlements = svc.GrantedAccountEntitlements(
770            client.channel, client)
771        client.granted_resource_entitlements = svc.GrantedResourceEntitlements(
772            client.channel, client)
773        client.granted_role_entitlements = svc.GrantedRoleEntitlements(
774            client.channel, client)
775        client.roles = svc.Roles(client.channel, client)
776        client.groups = svc.Groups(client.channel, client)
777        client.groups_roles = svc.GroupsRoles(client.channel, client)
778        client.identity_aliases = svc.IdentityAliases(client.channel, client)
779        client.identity_sets = svc.IdentitySets(client.channel, client)
780        client.nodes = svc.Nodes(client.channel, client)
781        client.policies = svc.Policies(client.channel, client)
782        client.proxy_cluster_keys = svc.ProxyClusterKeys(
783            client.channel, client)
784        client.remote_identities = svc.RemoteIdentities(client.channel, client)
785        client.remote_identity_groups = svc.RemoteIdentityGroups(
786            client.channel, client)
787        client.resources = svc.Resources(client.channel, client)
788        client.role_resources = svc.RoleResources(client.channel, client)
789        client.secret_stores = svc.SecretStores(client.channel, client)
790        client.workflow_approvers = svc.WorkflowApprovers(
791            client.channel, client)
792        client.workflow_roles = svc.WorkflowRoles(client.channel, client)
793        client.workflows = svc.Workflows(client.channel, client)
794        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)
173    def __init__(self,
174                 api_access_key,
175                 api_secret,
176                 host='app.strongdm.com:443',
177                 insecure=False,
178                 retry_rate_limit_errors=True,
179                 page_limit=0):
180        '''
181        Create a new Client.
182
183        - api_access_key: the access key to authenticate with strongDM
184        - api_secret: the secret key to authenticate with strongDM
185        '''
186        self.api_access_key = api_access_key.strip()
187        self.api_secret = base64.b64decode(api_secret.strip())
188        self.base_retry_delay = DEFAULT_BASE_RETRY_DELAY
189        self.max_retry_delay = DEFAULT_MAX_RETRY_DELAY
190        self.retry_factor = DEFAULT_RETRY_FACTOR
191        self.retry_jitter = DEFAULT_RETRY_JITTER
192        self.retry_rate_limit_errors = retry_rate_limit_errors
193        self.snapshot_datetime = None
194        self.page_limit = page_limit
195
196        try:
197            if insecure:
198                channel = grpc.insecure_channel(host)
199            else:
200                creds = grpc.ssl_channel_credentials()
201                channel = grpc.secure_channel(host, creds)
202        except Exception as e:
203            raise plumbing.convert_error_to_porcelain(e) from e
204        channel = grpc.intercept_channel(channel, _EncryptionInterceptor(self))
205        self.channel = channel
206        self.access_requests = svc.AccessRequests(channel, self)
207        '''
208         AccessRequests are requests for access to a resource that may match a Workflow.
209
210        See `strongdm.svc.AccessRequests`.
211        '''
212        self.access_request_events_history = svc.AccessRequestEventsHistory(
213            channel, self)
214        '''
215         AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.
216
217        See `strongdm.svc.AccessRequestEventsHistory`.
218        '''
219        self.access_requests_history = svc.AccessRequestsHistory(channel, self)
220        '''
221         AccessRequestsHistory provides records of all changes to the state of an AccessRequest.
222
223        See `strongdm.svc.AccessRequestsHistory`.
224        '''
225        self.account_attachments = svc.AccountAttachments(channel, self)
226        '''
227         AccountAttachments assign an account to a role.
228
229        See `strongdm.svc.AccountAttachments`.
230        '''
231        self.account_attachments_history = svc.AccountAttachmentsHistory(
232            channel, self)
233        '''
234         AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
235
236        See `strongdm.svc.AccountAttachmentsHistory`.
237        '''
238        self.account_grants = svc.AccountGrants(channel, self)
239        '''
240         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
241
242        See `strongdm.svc.AccountGrants`.
243        '''
244        self.account_grants_history = svc.AccountGrantsHistory(channel, self)
245        '''
246         AccountGrantsHistory records all changes to the state of an AccountGrant.
247
248        See `strongdm.svc.AccountGrantsHistory`.
249        '''
250        self.account_permissions = svc.AccountPermissions(channel, self)
251        '''
252         AccountPermissions records the granular permissions accounts have, allowing them to execute
253         relevant commands via StrongDM's APIs.
254
255        See `strongdm.svc.AccountPermissions`.
256        '''
257        self.account_resources = svc.AccountResources(channel, self)
258        '''
259         AccountResources enumerates the resources to which accounts have access.
260         The AccountResources service is read-only.
261
262        See `strongdm.svc.AccountResources`.
263        '''
264        self.account_resources_history = svc.AccountResourcesHistory(
265            channel, self)
266        '''
267         AccountResourcesHistory records all changes to the state of a AccountResource.
268
269        See `strongdm.svc.AccountResourcesHistory`.
270        '''
271        self.accounts = svc.Accounts(channel, self)
272        '''
273         Accounts are users that have access to strongDM. There are two types of accounts:
274         1. **Users:** humans who are authenticated through username and password or SSO.
275         2. **Service Accounts:** machines that are authenticated using a service token.
276         3. **Tokens** are access keys with permissions that can be used for authentication.
277
278        See `strongdm.svc.Accounts`.
279        '''
280        self.accounts_groups = svc.AccountsGroups(channel, self)
281        '''
282         An AccountGroup links an account and a group.
283
284        See `strongdm.svc.AccountsGroups`.
285        '''
286        self.accounts_groups_history = svc.AccountsGroupsHistory(channel, self)
287        '''
288         AccountsGroupsHistory records all changes to the state of an AccountGroup.
289
290        See `strongdm.svc.AccountsGroupsHistory`.
291        '''
292        self.accounts_history = svc.AccountsHistory(channel, self)
293        '''
294         AccountsHistory records all changes to the state of an Account.
295
296        See `strongdm.svc.AccountsHistory`.
297        '''
298        self.activities = svc.Activities(channel, self)
299        '''
300         An Activity is a record of an action taken against a strongDM deployment, e.g.
301         a user creation, resource deletion, sso configuration change, etc. The Activities
302         service is read-only.
303
304        See `strongdm.svc.Activities`.
305        '''
306        self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
307            channel, self)
308        '''
309         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
310
311        See `strongdm.svc.ApprovalWorkflowApprovers`.
312        '''
313        self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory(
314            channel, self)
315        '''
316         ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.
317
318        See `strongdm.svc.ApprovalWorkflowApproversHistory`.
319        '''
320        self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self)
321        '''
322         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
323
324        See `strongdm.svc.ApprovalWorkflowSteps`.
325        '''
326        self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory(
327            channel, self)
328        '''
329         ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.
330
331        See `strongdm.svc.ApprovalWorkflowStepsHistory`.
332        '''
333        self.approval_workflows = svc.ApprovalWorkflows(channel, self)
334        '''
335         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
336         approvers and be approved or denied.
337
338        See `strongdm.svc.ApprovalWorkflows`.
339        '''
340        self.approval_workflows_history = svc.ApprovalWorkflowsHistory(
341            channel, self)
342        '''
343         ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.
344
345        See `strongdm.svc.ApprovalWorkflowsHistory`.
346        '''
347        self.control_panel = svc.ControlPanel(channel, self)
348        '''
349         ControlPanel contains all administrative controls.
350
351        See `strongdm.svc.ControlPanel`.
352        '''
353        self.discovery_connectors = svc.DiscoveryConnectors(channel, self)
354        '''
355         A Discovery Connector is a configuration object for performing Resource
356         Scans in remote systems such as AWS, GCP, Azure, and other systems.
357
358        See `strongdm.svc.DiscoveryConnectors`.
359        '''
360        self.granted_account_entitlements = svc.GrantedAccountEntitlements(
361            channel, self)
362        '''
363         GrantedAccountEntitlements enumerates the resources to which an account has been granted access.
364         The GrantedAccountEntitlements service is read-only.
365
366        See `strongdm.svc.GrantedAccountEntitlements`.
367        '''
368        self.granted_resource_entitlements = svc.GrantedResourceEntitlements(
369            channel, self)
370        '''
371         GrantedResourceEntitlements enumerates the accounts that have been granted access to a given resource.
372         The GrantedResourceEntitlements service is read-only.
373
374        See `strongdm.svc.GrantedResourceEntitlements`.
375        '''
376        self.granted_role_entitlements = svc.GrantedRoleEntitlements(
377            channel, self)
378        '''
379         GrantedRoleEntitlements enumerates the resources to which a role grants access.
380         The GrantedRoleEntitlements service is read-only.
381
382        See `strongdm.svc.GrantedRoleEntitlements`.
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.groups = svc.Groups(channel, self)
393        '''
394         A Group is a set of principals.
395
396        See `strongdm.svc.Groups`.
397        '''
398        self.groups_history = svc.GroupsHistory(channel, self)
399        '''
400         GroupsHistory records all changes to the state of a Group.
401
402        See `strongdm.svc.GroupsHistory`.
403        '''
404        self.groups_roles = svc.GroupsRoles(channel, self)
405        '''
406         A GroupRole is an assignment of a Group to a Role.
407
408        See `strongdm.svc.GroupsRoles`.
409        '''
410        self.groups_roles_history = svc.GroupsRolesHistory(channel, self)
411        '''
412         GroupsRolesHistory records all changes to the state of a GroupRole.
413
414        See `strongdm.svc.GroupsRolesHistory`.
415        '''
416        self.health_checks = svc.HealthChecks(channel, self)
417        '''
418         HealthChecks lists the last healthcheck between each node and resource.
419         Note the unconventional capitalization here is to prevent having a collision with GRPC
420
421        See `strongdm.svc.HealthChecks`.
422        '''
423        self.identity_aliases = svc.IdentityAliases(channel, self)
424        '''
425         IdentityAliases assign an alias to an account within an IdentitySet.
426         The alias is used as the username when connecting to a identity supported resource.
427
428        See `strongdm.svc.IdentityAliases`.
429        '''
430        self.identity_aliases_history = svc.IdentityAliasesHistory(
431            channel, self)
432        '''
433         IdentityAliasesHistory records all changes to the state of a IdentityAlias.
434
435        See `strongdm.svc.IdentityAliasesHistory`.
436        '''
437        self.identity_sets = svc.IdentitySets(channel, self)
438        '''
439         A IdentitySet is a named grouping of Identity Aliases for Accounts.
440         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
441
442        See `strongdm.svc.IdentitySets`.
443        '''
444        self.identity_sets_history = svc.IdentitySetsHistory(channel, self)
445        '''
446         IdentitySetsHistory records all changes to the state of a IdentitySet.
447
448        See `strongdm.svc.IdentitySetsHistory`.
449        '''
450        self.managed_secrets = svc.ManagedSecrets(channel, self)
451        '''
452         ManagedSecret is a private vertical for creating, reading, updating,
453         deleting, listing and rotating the managed secrets in the secrets engines as
454         an authenticated user.
455
456        See `strongdm.svc.ManagedSecrets`.
457        '''
458        self.nodes = svc.Nodes(channel, self)
459        '''
460         Nodes make up the StrongDM network, and allow your users to connect securely to your resources.
461         There are three types of nodes:
462         1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
463         2. **Gateway:** a relay that also listens for connections from StrongDM clients
464         3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources
465
466        See `strongdm.svc.Nodes`.
467        '''
468        self.nodes_history = svc.NodesHistory(channel, self)
469        '''
470         NodesHistory records all changes to the state of a Node.
471
472        See `strongdm.svc.NodesHistory`.
473        '''
474        self.organization_history = svc.OrganizationHistory(channel, self)
475        '''
476         OrganizationHistory records all changes to the state of an Organization.
477
478        See `strongdm.svc.OrganizationHistory`.
479        '''
480        self.peering_group_nodes = svc.PeeringGroupNodes(channel, self)
481        '''
482         PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.
483
484        See `strongdm.svc.PeeringGroupNodes`.
485        '''
486        self.peering_group_peers = svc.PeeringGroupPeers(channel, self)
487        '''
488         PeeringGroupPeers provides the building blocks necessary to link two peering groups.
489
490        See `strongdm.svc.PeeringGroupPeers`.
491        '''
492        self.peering_group_resources = svc.PeeringGroupResources(channel, self)
493        '''
494         PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.
495
496        See `strongdm.svc.PeeringGroupResources`.
497        '''
498        self.peering_groups = svc.PeeringGroups(channel, self)
499        '''
500         PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.
501
502        See `strongdm.svc.PeeringGroups`.
503        '''
504        self.policies = svc.Policies(channel, self)
505        '''
506         Policies are the collection of one or more statements that enforce fine-grained access
507         control for the users of an organization.
508
509        See `strongdm.svc.Policies`.
510        '''
511        self.policies_history = svc.PoliciesHistory(channel, self)
512        '''
513         PoliciesHistory records all changes to the state of a Policy.
514
515        See `strongdm.svc.PoliciesHistory`.
516        '''
517        self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self)
518        '''
519         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
520         The proxies within a cluster share the same key. One cluster can have
521         multiple keys in order to facilitate key rotation.
522
523        See `strongdm.svc.ProxyClusterKeys`.
524        '''
525        self.queries = svc.Queries(channel, self)
526        '''
527         A Query is a record of a single client request to a resource, such as a SQL query.
528         Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries.
529         The Queries service is read-only.
530
531        See `strongdm.svc.Queries`.
532        '''
533        self.remote_identities = svc.RemoteIdentities(channel, self)
534        '''
535         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
536
537        See `strongdm.svc.RemoteIdentities`.
538        '''
539        self.remote_identities_history = svc.RemoteIdentitiesHistory(
540            channel, self)
541        '''
542         RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
543
544        See `strongdm.svc.RemoteIdentitiesHistory`.
545        '''
546        self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self)
547        '''
548         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
549         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
550
551        See `strongdm.svc.RemoteIdentityGroups`.
552        '''
553        self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory(
554            channel, self)
555        '''
556         RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
557
558        See `strongdm.svc.RemoteIdentityGroupsHistory`.
559        '''
560        self.replays = svc.Replays(channel, self)
561        '''
562         A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session
563         (otherwise referred to as a query). The Replays service is read-only.
564
565        See `strongdm.svc.Replays`.
566        '''
567        self.resources = svc.Resources(channel, self)
568        '''
569         Resources are databases, servers, clusters, websites, or clouds that strongDM
570         delegates access to.
571
572        See `strongdm.svc.Resources`.
573        '''
574        self.resources_history = svc.ResourcesHistory(channel, self)
575        '''
576         ResourcesHistory records all changes to the state of a Resource.
577
578        See `strongdm.svc.ResourcesHistory`.
579        '''
580        self.role_resources = svc.RoleResources(channel, self)
581        '''
582         RoleResources enumerates the resources to which roles have access.
583         The RoleResources service is read-only.
584
585        See `strongdm.svc.RoleResources`.
586        '''
587        self.role_resources_history = svc.RoleResourcesHistory(channel, self)
588        '''
589         RoleResourcesHistory records all changes to the state of a RoleResource.
590
591        See `strongdm.svc.RoleResourcesHistory`.
592        '''
593        self.roles_history = svc.RolesHistory(channel, self)
594        '''
595         RolesHistory records all changes to the state of a Role.
596
597        See `strongdm.svc.RolesHistory`.
598        '''
599        self.secret_stores = svc.SecretStores(channel, self)
600        '''
601         SecretStores are servers where resource secrets (passwords, keys) are stored.
602
603        See `strongdm.svc.SecretStores`.
604        '''
605        self.secret_engines = svc.SecretEngines(channel, self)
606        '''
607
608
609        See `strongdm.svc.SecretEngines`.
610        '''
611        self.secret_store_healths = svc.SecretStoreHealths(channel, self)
612        '''
613         SecretStoreHealths exposes health states for secret stores.
614
615        See `strongdm.svc.SecretStoreHealths`.
616        '''
617        self.secret_stores_history = svc.SecretStoresHistory(channel, self)
618        '''
619         SecretStoresHistory records all changes to the state of a SecretStore.
620
621        See `strongdm.svc.SecretStoresHistory`.
622        '''
623        self.workflow_approvers = svc.WorkflowApprovers(channel, self)
624        '''
625         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
626
627        See `strongdm.svc.WorkflowApprovers`.
628        '''
629        self.workflow_approvers_history = svc.WorkflowApproversHistory(
630            channel, self)
631        '''
632         WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.
633
634        See `strongdm.svc.WorkflowApproversHistory`.
635        '''
636        self.workflow_roles = svc.WorkflowRoles(channel, self)
637        '''
638         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
639         to request access to a resource via the workflow.
640
641        See `strongdm.svc.WorkflowRoles`.
642        '''
643        self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self)
644        '''
645         WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole
646
647        See `strongdm.svc.WorkflowRolesHistory`.
648        '''
649        self.workflows = svc.Workflows(channel, self)
650        '''
651         Workflows are the collection of rules that define the resources to which access can be requested,
652         the users that can request that access, and the mechanism for approving those requests which can either
653         be automatic approval or a set of users authorized to approve the requests.
654
655        See `strongdm.svc.Workflows`.
656        '''
657        self.workflows_history = svc.WorkflowsHistory(channel, self)
658        '''
659         WorkflowsHistory provides records of all changes to the state of a Workflow.
660
661        See `strongdm.svc.WorkflowsHistory`.
662        '''

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_groups

An AccountGroup links an account and a group.

See strongdm.svc.AccountsGroups.

accounts_groups_history

AccountsGroupsHistory records all changes to the state of an AccountGroup.

See strongdm.svc.AccountsGroupsHistory.

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.

discovery_connectors

A Discovery Connector is a configuration object for performing Resource Scans in remote systems such as AWS, GCP, Azure, and other systems.

See strongdm.svc.DiscoveryConnectors.

granted_account_entitlements

GrantedAccountEntitlements enumerates the resources to which an account has been granted access. The GrantedAccountEntitlements service is read-only.

See strongdm.svc.GrantedAccountEntitlements.

granted_resource_entitlements

GrantedResourceEntitlements enumerates the accounts that have been granted access to a given resource. The GrantedResourceEntitlements service is read-only.

See strongdm.svc.GrantedResourceEntitlements.

granted_role_entitlements

GrantedRoleEntitlements enumerates the resources to which a role grants access. The GrantedRoleEntitlements service is read-only.

See strongdm.svc.GrantedRoleEntitlements.

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.

groups

A Group is a set of principals.

See strongdm.svc.Groups.

groups_history

GroupsHistory records all changes to the state of a Group.

See strongdm.svc.GroupsHistory.

groups_roles

A GroupRole is an assignment of a Group to a Role.

See strongdm.svc.GroupsRoles.

groups_roles_history

GroupsRolesHistory records all changes to the state of a GroupRole.

See strongdm.svc.GroupsRolesHistory.

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 three types of nodes:

  1. Relay: creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
  2. Gateway: a relay that also listens for connections from StrongDM clients
  3. Proxy Cluster: a cluster of workers that together mediate access from clients to resources

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_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)
664    def close(self):
665        '''Closes this Client and releases all resources held by it.
666
667        Closing the Client will immediately terminate all RPCs active with the
668        Client and it is not valid to invoke new RPCs with the Client.
669
670        This method is idempotent.
671        '''
672        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)
674    def get_metadata(self, method_name, req):
675        return [
676            ('x-sdm-authentication', self.api_access_key),
677            ('x-sdm-signature', self.sign(method_name,
678                                          req.SerializeToString())),
679            ('x-sdm-api-version', API_VERSION),
680            ('x-sdm-user-agent', USER_AGENT),
681        ]
def sign(self, method_name, request_bytes)
683    def sign(self, method_name, request_bytes):
684        def hmac_digest(key, msg_byte_string):
685            return hmac.new(key, msg=msg_byte_string,
686                            digestmod=hashlib.sha256).digest()
687
688        current_utc_date = datetime.datetime.now(
689            datetime.timezone.utc).strftime('%Y-%m-%d')
690        signing_key = hmac_digest(self.api_secret, current_utc_date.encode())
691        signing_key = hmac_digest(signing_key, b'sdm_api_v1')
692
693        hash = hashlib.sha256()
694
695        hash.update(method_name.encode())
696        hash.update(b'\n')
697        hash.update(request_bytes)
698
699        return base64.b64encode(hmac_digest(signing_key, hash.digest()))
def exponentialBackoff(self, retries, deadline=None)
701    def exponentialBackoff(self, retries, deadline=None):
702        def applyDeadline(delay, deadline):
703            if deadline is None:
704                return delay
705            remaining = deadline - time.time()
706            if remaining < 0:
707                return 0
708            return min(delay, remaining)
709
710        if retries == 0:
711            return applyDeadline(self.base_retry_delay, deadline)
712
713        backoff, max_delay = self.base_retry_delay, self.max_retry_delay
714        while backoff < max_delay and retries > 0:
715            backoff *= self.retry_factor
716            retries -= 1
717
718        if backoff > max_delay:
719            backoff = max_delay
720
721        # Randomize backoff delays so that if a cluster of requests start at
722        # the same time, they won't operate in lockstep.
723        backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1)
724        if backoff < 0:
725            return 0
726
727        return applyDeadline(backoff, deadline)
def shouldRetry(self, retries, err, deadline=None)
729    def shouldRetry(self, retries, err, deadline=None):
730        # Check if we've passed the deadline
731        if deadline is not None and time.time() >= deadline:
732            return False
733
734        if not isinstance(err, grpc.RpcError):
735            return False
736
737        if self.retry_rate_limit_errors and err.code(
738        ) == grpc.StatusCode.RESOURCE_EXHAUSTED:
739            return True
740
741        return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL
742                                 or err.code() == grpc.StatusCode.UNAVAILABLE)
def snapshot_at(self, snapshot_datetime)
744    def snapshot_at(self, snapshot_datetime):
745        '''
746        Constructs a read-only client that will provide historical data from the provided timestamp.
747
748        See `SnapshotClient`.
749        '''
750        client = copy.copy(self)
751        client.snapshot_datetime = snapshot_datetime
752        client.access_requests = svc.AccessRequests(client.channel, client)
753        client.account_attachments = svc.AccountAttachments(
754            client.channel, client)
755        client.account_grants = svc.AccountGrants(client.channel, client)
756        client.account_permissions = svc.AccountPermissions(
757            client.channel, client)
758        client.account_resources = svc.AccountResources(client.channel, client)
759        client.accounts = svc.Accounts(client.channel, client)
760        client.accounts_groups = svc.AccountsGroups(client.channel, client)
761        client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers(
762            client.channel, client)
763        client.approval_workflow_steps = svc.ApprovalWorkflowSteps(
764            client.channel, client)
765        client.approval_workflows = svc.ApprovalWorkflows(
766            client.channel, client)
767        client.discovery_connectors = svc.DiscoveryConnectors(
768            client.channel, client)
769        client.granted_account_entitlements = svc.GrantedAccountEntitlements(
770            client.channel, client)
771        client.granted_resource_entitlements = svc.GrantedResourceEntitlements(
772            client.channel, client)
773        client.granted_role_entitlements = svc.GrantedRoleEntitlements(
774            client.channel, client)
775        client.roles = svc.Roles(client.channel, client)
776        client.groups = svc.Groups(client.channel, client)
777        client.groups_roles = svc.GroupsRoles(client.channel, client)
778        client.identity_aliases = svc.IdentityAliases(client.channel, client)
779        client.identity_sets = svc.IdentitySets(client.channel, client)
780        client.nodes = svc.Nodes(client.channel, client)
781        client.policies = svc.Policies(client.channel, client)
782        client.proxy_cluster_keys = svc.ProxyClusterKeys(
783            client.channel, client)
784        client.remote_identities = svc.RemoteIdentities(client.channel, client)
785        client.remote_identity_groups = svc.RemoteIdentityGroups(
786            client.channel, client)
787        client.resources = svc.Resources(client.channel, client)
788        client.role_resources = svc.RoleResources(client.channel, client)
789        client.secret_stores = svc.SecretStores(client.channel, client)
790        client.workflow_approvers = svc.WorkflowApprovers(
791            client.channel, client)
792        client.workflow_roles = svc.WorkflowRoles(client.channel, client)
793        client.workflows = svc.Workflows(client.channel, client)
794        return SnapshotClient(client)

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

See SnapshotClient.

class SnapshotClient:
 797class SnapshotClient:
 798    '''SnapshotClient exposes methods to query historical records at a provided timestamp.'''
 799    def __init__(self, client):
 800        self.access_requests = svc.SnapshotAccessRequests(
 801            client.access_requests)
 802        '''
 803         AccessRequests are requests for access to a resource that may match a Workflow.
 804
 805        See `strongdm.svc.SnapshotAccessRequests`.
 806        '''
 807        self.account_attachments = svc.SnapshotAccountAttachments(
 808            client.account_attachments)
 809        '''
 810         AccountAttachments assign an account to a role.
 811
 812        See `strongdm.svc.SnapshotAccountAttachments`.
 813        '''
 814        self.account_grants = svc.SnapshotAccountGrants(client.account_grants)
 815        '''
 816         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
 817
 818        See `strongdm.svc.SnapshotAccountGrants`.
 819        '''
 820        self.account_permissions = svc.SnapshotAccountPermissions(
 821            client.account_permissions)
 822        '''
 823         AccountPermissions records the granular permissions accounts have, allowing them to execute
 824         relevant commands via StrongDM's APIs.
 825
 826        See `strongdm.svc.SnapshotAccountPermissions`.
 827        '''
 828        self.account_resources = svc.SnapshotAccountResources(
 829            client.account_resources)
 830        '''
 831         AccountResources enumerates the resources to which accounts have access.
 832         The AccountResources service is read-only.
 833
 834        See `strongdm.svc.SnapshotAccountResources`.
 835        '''
 836        self.accounts = svc.SnapshotAccounts(client.accounts)
 837        '''
 838         Accounts are users that have access to strongDM. There are two types of accounts:
 839         1. **Users:** humans who are authenticated through username and password or SSO.
 840         2. **Service Accounts:** machines that are authenticated using a service token.
 841         3. **Tokens** are access keys with permissions that can be used for authentication.
 842
 843        See `strongdm.svc.SnapshotAccounts`.
 844        '''
 845        self.accounts_groups = svc.SnapshotAccountsGroups(
 846            client.accounts_groups)
 847        '''
 848         An AccountGroup links an account and a group.
 849
 850        See `strongdm.svc.SnapshotAccountsGroups`.
 851        '''
 852        self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers(
 853            client.approval_workflow_approvers)
 854        '''
 855         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
 856
 857        See `strongdm.svc.SnapshotApprovalWorkflowApprovers`.
 858        '''
 859        self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps(
 860            client.approval_workflow_steps)
 861        '''
 862         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
 863
 864        See `strongdm.svc.SnapshotApprovalWorkflowSteps`.
 865        '''
 866        self.approval_workflows = svc.SnapshotApprovalWorkflows(
 867            client.approval_workflows)
 868        '''
 869         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
 870         approvers and be approved or denied.
 871
 872        See `strongdm.svc.SnapshotApprovalWorkflows`.
 873        '''
 874        self.discovery_connectors = svc.SnapshotDiscoveryConnectors(
 875            client.discovery_connectors)
 876        '''
 877         A Discovery Connector is a configuration object for performing Resource
 878         Scans in remote systems such as AWS, GCP, Azure, and other systems.
 879
 880        See `strongdm.svc.SnapshotDiscoveryConnectors`.
 881        '''
 882        self.granted_account_entitlements = svc.SnapshotGrantedAccountEntitlements(
 883            client.granted_account_entitlements)
 884        '''
 885         GrantedAccountEntitlements enumerates the resources to which an account has been granted access.
 886         The GrantedAccountEntitlements service is read-only.
 887
 888        See `strongdm.svc.SnapshotGrantedAccountEntitlements`.
 889        '''
 890        self.granted_resource_entitlements = svc.SnapshotGrantedResourceEntitlements(
 891            client.granted_resource_entitlements)
 892        '''
 893         GrantedResourceEntitlements enumerates the accounts that have been granted access to a given resource.
 894         The GrantedResourceEntitlements service is read-only.
 895
 896        See `strongdm.svc.SnapshotGrantedResourceEntitlements`.
 897        '''
 898        self.granted_role_entitlements = svc.SnapshotGrantedRoleEntitlements(
 899            client.granted_role_entitlements)
 900        '''
 901         GrantedRoleEntitlements enumerates the resources to which a role grants access.
 902         The GrantedRoleEntitlements service is read-only.
 903
 904        See `strongdm.svc.SnapshotGrantedRoleEntitlements`.
 905        '''
 906        self.roles = svc.SnapshotRoles(client.roles)
 907        '''
 908         A Role has a list of access rules which determine which Resources the members
 909         of the Role have access to. An Account can be a member of multiple Roles via
 910         AccountAttachments.
 911
 912        See `strongdm.svc.SnapshotRoles`.
 913        '''
 914        self.groups = svc.SnapshotGroups(client.groups)
 915        '''
 916         A Group is a set of principals.
 917
 918        See `strongdm.svc.SnapshotGroups`.
 919        '''
 920        self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles)
 921        '''
 922         A GroupRole is an assignment of a Group to a Role.
 923
 924        See `strongdm.svc.SnapshotGroupsRoles`.
 925        '''
 926        self.identity_aliases = svc.SnapshotIdentityAliases(
 927            client.identity_aliases)
 928        '''
 929         IdentityAliases assign an alias to an account within an IdentitySet.
 930         The alias is used as the username when connecting to a identity supported resource.
 931
 932        See `strongdm.svc.SnapshotIdentityAliases`.
 933        '''
 934        self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets)
 935        '''
 936         A IdentitySet is a named grouping of Identity Aliases for Accounts.
 937         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
 938
 939        See `strongdm.svc.SnapshotIdentitySets`.
 940        '''
 941        self.nodes = svc.SnapshotNodes(client.nodes)
 942        '''
 943         Nodes make up the StrongDM network, and allow your users to connect securely to your resources.
 944         There are three types of nodes:
 945         1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
 946         2. **Gateway:** a relay that also listens for connections from StrongDM clients
 947         3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources
 948
 949        See `strongdm.svc.SnapshotNodes`.
 950        '''
 951        self.policies = svc.SnapshotPolicies(client.policies)
 952        '''
 953         Policies are the collection of one or more statements that enforce fine-grained access
 954         control for the users of an organization.
 955
 956        See `strongdm.svc.SnapshotPolicies`.
 957        '''
 958        self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys(
 959            client.proxy_cluster_keys)
 960        '''
 961         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
 962         The proxies within a cluster share the same key. One cluster can have
 963         multiple keys in order to facilitate key rotation.
 964
 965        See `strongdm.svc.SnapshotProxyClusterKeys`.
 966        '''
 967        self.remote_identities = svc.SnapshotRemoteIdentities(
 968            client.remote_identities)
 969        '''
 970         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
 971
 972        See `strongdm.svc.SnapshotRemoteIdentities`.
 973        '''
 974        self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups(
 975            client.remote_identity_groups)
 976        '''
 977         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
 978         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
 979
 980        See `strongdm.svc.SnapshotRemoteIdentityGroups`.
 981        '''
 982        self.resources = svc.SnapshotResources(client.resources)
 983        '''
 984         Resources are databases, servers, clusters, websites, or clouds that strongDM
 985         delegates access to.
 986
 987        See `strongdm.svc.SnapshotResources`.
 988        '''
 989        self.role_resources = svc.SnapshotRoleResources(client.role_resources)
 990        '''
 991         RoleResources enumerates the resources to which roles have access.
 992         The RoleResources service is read-only.
 993
 994        See `strongdm.svc.SnapshotRoleResources`.
 995        '''
 996        self.secret_stores = svc.SnapshotSecretStores(client.secret_stores)
 997        '''
 998         SecretStores are servers where resource secrets (passwords, keys) are stored.
 999
1000        See `strongdm.svc.SnapshotSecretStores`.
1001        '''
1002        self.workflow_approvers = svc.SnapshotWorkflowApprovers(
1003            client.workflow_approvers)
1004        '''
1005         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
1006
1007        See `strongdm.svc.SnapshotWorkflowApprovers`.
1008        '''
1009        self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles)
1010        '''
1011         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
1012         to request access to a resource via the workflow.
1013
1014        See `strongdm.svc.SnapshotWorkflowRoles`.
1015        '''
1016        self.workflows = svc.SnapshotWorkflows(client.workflows)
1017        '''
1018         Workflows are the collection of rules that define the resources to which access can be requested,
1019         the users that can request that access, and the mechanism for approving those requests which can either
1020         be automatic approval or a set of users authorized to approve the requests.
1021
1022        See `strongdm.svc.SnapshotWorkflows`.
1023        '''

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

SnapshotClient(client)
 799    def __init__(self, client):
 800        self.access_requests = svc.SnapshotAccessRequests(
 801            client.access_requests)
 802        '''
 803         AccessRequests are requests for access to a resource that may match a Workflow.
 804
 805        See `strongdm.svc.SnapshotAccessRequests`.
 806        '''
 807        self.account_attachments = svc.SnapshotAccountAttachments(
 808            client.account_attachments)
 809        '''
 810         AccountAttachments assign an account to a role.
 811
 812        See `strongdm.svc.SnapshotAccountAttachments`.
 813        '''
 814        self.account_grants = svc.SnapshotAccountGrants(client.account_grants)
 815        '''
 816         AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
 817
 818        See `strongdm.svc.SnapshotAccountGrants`.
 819        '''
 820        self.account_permissions = svc.SnapshotAccountPermissions(
 821            client.account_permissions)
 822        '''
 823         AccountPermissions records the granular permissions accounts have, allowing them to execute
 824         relevant commands via StrongDM's APIs.
 825
 826        See `strongdm.svc.SnapshotAccountPermissions`.
 827        '''
 828        self.account_resources = svc.SnapshotAccountResources(
 829            client.account_resources)
 830        '''
 831         AccountResources enumerates the resources to which accounts have access.
 832         The AccountResources service is read-only.
 833
 834        See `strongdm.svc.SnapshotAccountResources`.
 835        '''
 836        self.accounts = svc.SnapshotAccounts(client.accounts)
 837        '''
 838         Accounts are users that have access to strongDM. There are two types of accounts:
 839         1. **Users:** humans who are authenticated through username and password or SSO.
 840         2. **Service Accounts:** machines that are authenticated using a service token.
 841         3. **Tokens** are access keys with permissions that can be used for authentication.
 842
 843        See `strongdm.svc.SnapshotAccounts`.
 844        '''
 845        self.accounts_groups = svc.SnapshotAccountsGroups(
 846            client.accounts_groups)
 847        '''
 848         An AccountGroup links an account and a group.
 849
 850        See `strongdm.svc.SnapshotAccountsGroups`.
 851        '''
 852        self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers(
 853            client.approval_workflow_approvers)
 854        '''
 855         ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
 856
 857        See `strongdm.svc.SnapshotApprovalWorkflowApprovers`.
 858        '''
 859        self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps(
 860            client.approval_workflow_steps)
 861        '''
 862         ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow
 863
 864        See `strongdm.svc.SnapshotApprovalWorkflowSteps`.
 865        '''
 866        self.approval_workflows = svc.SnapshotApprovalWorkflows(
 867            client.approval_workflows)
 868        '''
 869         ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized
 870         approvers and be approved or denied.
 871
 872        See `strongdm.svc.SnapshotApprovalWorkflows`.
 873        '''
 874        self.discovery_connectors = svc.SnapshotDiscoveryConnectors(
 875            client.discovery_connectors)
 876        '''
 877         A Discovery Connector is a configuration object for performing Resource
 878         Scans in remote systems such as AWS, GCP, Azure, and other systems.
 879
 880        See `strongdm.svc.SnapshotDiscoveryConnectors`.
 881        '''
 882        self.granted_account_entitlements = svc.SnapshotGrantedAccountEntitlements(
 883            client.granted_account_entitlements)
 884        '''
 885         GrantedAccountEntitlements enumerates the resources to which an account has been granted access.
 886         The GrantedAccountEntitlements service is read-only.
 887
 888        See `strongdm.svc.SnapshotGrantedAccountEntitlements`.
 889        '''
 890        self.granted_resource_entitlements = svc.SnapshotGrantedResourceEntitlements(
 891            client.granted_resource_entitlements)
 892        '''
 893         GrantedResourceEntitlements enumerates the accounts that have been granted access to a given resource.
 894         The GrantedResourceEntitlements service is read-only.
 895
 896        See `strongdm.svc.SnapshotGrantedResourceEntitlements`.
 897        '''
 898        self.granted_role_entitlements = svc.SnapshotGrantedRoleEntitlements(
 899            client.granted_role_entitlements)
 900        '''
 901         GrantedRoleEntitlements enumerates the resources to which a role grants access.
 902         The GrantedRoleEntitlements service is read-only.
 903
 904        See `strongdm.svc.SnapshotGrantedRoleEntitlements`.
 905        '''
 906        self.roles = svc.SnapshotRoles(client.roles)
 907        '''
 908         A Role has a list of access rules which determine which Resources the members
 909         of the Role have access to. An Account can be a member of multiple Roles via
 910         AccountAttachments.
 911
 912        See `strongdm.svc.SnapshotRoles`.
 913        '''
 914        self.groups = svc.SnapshotGroups(client.groups)
 915        '''
 916         A Group is a set of principals.
 917
 918        See `strongdm.svc.SnapshotGroups`.
 919        '''
 920        self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles)
 921        '''
 922         A GroupRole is an assignment of a Group to a Role.
 923
 924        See `strongdm.svc.SnapshotGroupsRoles`.
 925        '''
 926        self.identity_aliases = svc.SnapshotIdentityAliases(
 927            client.identity_aliases)
 928        '''
 929         IdentityAliases assign an alias to an account within an IdentitySet.
 930         The alias is used as the username when connecting to a identity supported resource.
 931
 932        See `strongdm.svc.SnapshotIdentityAliases`.
 933        '''
 934        self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets)
 935        '''
 936         A IdentitySet is a named grouping of Identity Aliases for Accounts.
 937         An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
 938
 939        See `strongdm.svc.SnapshotIdentitySets`.
 940        '''
 941        self.nodes = svc.SnapshotNodes(client.nodes)
 942        '''
 943         Nodes make up the StrongDM network, and allow your users to connect securely to your resources.
 944         There are three types of nodes:
 945         1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
 946         2. **Gateway:** a relay that also listens for connections from StrongDM clients
 947         3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources
 948
 949        See `strongdm.svc.SnapshotNodes`.
 950        '''
 951        self.policies = svc.SnapshotPolicies(client.policies)
 952        '''
 953         Policies are the collection of one or more statements that enforce fine-grained access
 954         control for the users of an organization.
 955
 956        See `strongdm.svc.SnapshotPolicies`.
 957        '''
 958        self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys(
 959            client.proxy_cluster_keys)
 960        '''
 961         Proxy Cluster Keys are authentication keys for all proxies within a cluster.
 962         The proxies within a cluster share the same key. One cluster can have
 963         multiple keys in order to facilitate key rotation.
 964
 965        See `strongdm.svc.SnapshotProxyClusterKeys`.
 966        '''
 967        self.remote_identities = svc.SnapshotRemoteIdentities(
 968            client.remote_identities)
 969        '''
 970         RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
 971
 972        See `strongdm.svc.SnapshotRemoteIdentities`.
 973        '''
 974        self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups(
 975            client.remote_identity_groups)
 976        '''
 977         A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
 978         An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
 979
 980        See `strongdm.svc.SnapshotRemoteIdentityGroups`.
 981        '''
 982        self.resources = svc.SnapshotResources(client.resources)
 983        '''
 984         Resources are databases, servers, clusters, websites, or clouds that strongDM
 985         delegates access to.
 986
 987        See `strongdm.svc.SnapshotResources`.
 988        '''
 989        self.role_resources = svc.SnapshotRoleResources(client.role_resources)
 990        '''
 991         RoleResources enumerates the resources to which roles have access.
 992         The RoleResources service is read-only.
 993
 994        See `strongdm.svc.SnapshotRoleResources`.
 995        '''
 996        self.secret_stores = svc.SnapshotSecretStores(client.secret_stores)
 997        '''
 998         SecretStores are servers where resource secrets (passwords, keys) are stored.
 999
1000        See `strongdm.svc.SnapshotSecretStores`.
1001        '''
1002        self.workflow_approvers = svc.SnapshotWorkflowApprovers(
1003            client.workflow_approvers)
1004        '''
1005         WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
1006
1007        See `strongdm.svc.SnapshotWorkflowApprovers`.
1008        '''
1009        self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles)
1010        '''
1011         WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of
1012         to request access to a resource via the workflow.
1013
1014        See `strongdm.svc.SnapshotWorkflowRoles`.
1015        '''
1016        self.workflows = svc.SnapshotWorkflows(client.workflows)
1017        '''
1018         Workflows are the collection of rules that define the resources to which access can be requested,
1019         the users that can request that access, and the mechanism for approving those requests which can either
1020         be automatic approval or a set of users authorized to approve the requests.
1021
1022        See `strongdm.svc.SnapshotWorkflows`.
1023        '''
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.

accounts_groups

An AccountGroup links an account and a group.

See strongdm.svc.SnapshotAccountsGroups.

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.

discovery_connectors

A Discovery Connector is a configuration object for performing Resource Scans in remote systems such as AWS, GCP, Azure, and other systems.

See strongdm.svc.SnapshotDiscoveryConnectors.

granted_account_entitlements

GrantedAccountEntitlements enumerates the resources to which an account has been granted access. The GrantedAccountEntitlements service is read-only.

See strongdm.svc.SnapshotGrantedAccountEntitlements.

granted_resource_entitlements

GrantedResourceEntitlements enumerates the accounts that have been granted access to a given resource. The GrantedResourceEntitlements service is read-only.

See strongdm.svc.SnapshotGrantedResourceEntitlements.

granted_role_entitlements

GrantedRoleEntitlements enumerates the resources to which a role grants access. The GrantedRoleEntitlements service is read-only.

See strongdm.svc.SnapshotGrantedRoleEntitlements.

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.

groups

A Group is a set of principals.

See strongdm.svc.SnapshotGroups.

groups_roles

A GroupRole is an assignment of a Group to a Role.

See strongdm.svc.SnapshotGroupsRoles.

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 three types of nodes:

  1. Relay: creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
  2. Gateway: a relay that also listens for connections from StrongDM clients
  3. Proxy Cluster: a cluster of workers that together mediate access from clients to resources

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.

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.