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/15.44.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.roles = svc.Roles(channel, self) 360 ''' 361 A Role has a list of access rules which determine which Resources the members 362 of the Role have access to. An Account can be a member of multiple Roles via 363 AccountAttachments. 364 365 See `strongdm.svc.Roles`. 366 ''' 367 self.groups = svc.Groups(channel, self) 368 ''' 369 A Group is a set of principals. 370 371 See `strongdm.svc.Groups`. 372 ''' 373 self.groups_history = svc.GroupsHistory(channel, self) 374 ''' 375 GroupsHistory records all changes to the state of a Group. 376 377 See `strongdm.svc.GroupsHistory`. 378 ''' 379 self.groups_roles = svc.GroupsRoles(channel, self) 380 ''' 381 A GroupRole is an assignment of a Group to a Role. 382 383 See `strongdm.svc.GroupsRoles`. 384 ''' 385 self.groups_roles_history = svc.GroupsRolesHistory(channel, self) 386 ''' 387 GroupsRolesHistory records all changes to the state of a GroupRole. 388 389 See `strongdm.svc.GroupsRolesHistory`. 390 ''' 391 self.health_checks = svc.HealthChecks(channel, self) 392 ''' 393 HealthChecks lists the last healthcheck between each node and resource. 394 Note the unconventional capitalization here is to prevent having a collision with GRPC 395 396 See `strongdm.svc.HealthChecks`. 397 ''' 398 self.identity_aliases = svc.IdentityAliases(channel, self) 399 ''' 400 IdentityAliases assign an alias to an account within an IdentitySet. 401 The alias is used as the username when connecting to a identity supported resource. 402 403 See `strongdm.svc.IdentityAliases`. 404 ''' 405 self.identity_aliases_history = svc.IdentityAliasesHistory( 406 channel, self) 407 ''' 408 IdentityAliasesHistory records all changes to the state of a IdentityAlias. 409 410 See `strongdm.svc.IdentityAliasesHistory`. 411 ''' 412 self.identity_sets = svc.IdentitySets(channel, self) 413 ''' 414 A IdentitySet is a named grouping of Identity Aliases for Accounts. 415 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 416 417 See `strongdm.svc.IdentitySets`. 418 ''' 419 self.identity_sets_history = svc.IdentitySetsHistory(channel, self) 420 ''' 421 IdentitySetsHistory records all changes to the state of a IdentitySet. 422 423 See `strongdm.svc.IdentitySetsHistory`. 424 ''' 425 self.managed_secrets = svc.ManagedSecrets(channel, self) 426 ''' 427 ManagedSecret is a private vertical for creating, reading, updating, 428 deleting, listing and rotating the managed secrets in the secrets engines as 429 an authenticated user. 430 431 See `strongdm.svc.ManagedSecrets`. 432 ''' 433 self.nodes = svc.Nodes(channel, self) 434 ''' 435 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 436 There are three types of nodes: 437 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 438 2. **Gateway:** a relay that also listens for connections from StrongDM clients 439 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 440 441 See `strongdm.svc.Nodes`. 442 ''' 443 self.nodes_history = svc.NodesHistory(channel, self) 444 ''' 445 NodesHistory records all changes to the state of a Node. 446 447 See `strongdm.svc.NodesHistory`. 448 ''' 449 self.organization_history = svc.OrganizationHistory(channel, self) 450 ''' 451 OrganizationHistory records all changes to the state of an Organization. 452 453 See `strongdm.svc.OrganizationHistory`. 454 ''' 455 self.peering_group_nodes = svc.PeeringGroupNodes(channel, self) 456 ''' 457 PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group. 458 459 See `strongdm.svc.PeeringGroupNodes`. 460 ''' 461 self.peering_group_peers = svc.PeeringGroupPeers(channel, self) 462 ''' 463 PeeringGroupPeers provides the building blocks necessary to link two peering groups. 464 465 See `strongdm.svc.PeeringGroupPeers`. 466 ''' 467 self.peering_group_resources = svc.PeeringGroupResources(channel, self) 468 ''' 469 PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group. 470 471 See `strongdm.svc.PeeringGroupResources`. 472 ''' 473 self.peering_groups = svc.PeeringGroups(channel, self) 474 ''' 475 PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing. 476 477 See `strongdm.svc.PeeringGroups`. 478 ''' 479 self.policies = svc.Policies(channel, self) 480 ''' 481 Policies are the collection of one or more statements that enforce fine-grained access 482 control for the users of an organization. 483 484 See `strongdm.svc.Policies`. 485 ''' 486 self.policies_history = svc.PoliciesHistory(channel, self) 487 ''' 488 PoliciesHistory records all changes to the state of a Policy. 489 490 See `strongdm.svc.PoliciesHistory`. 491 ''' 492 self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self) 493 ''' 494 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 495 The proxies within a cluster share the same key. One cluster can have 496 multiple keys in order to facilitate key rotation. 497 498 See `strongdm.svc.ProxyClusterKeys`. 499 ''' 500 self.queries = svc.Queries(channel, self) 501 ''' 502 A Query is a record of a single client request to a resource, such as a SQL query. 503 Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries. 504 The Queries service is read-only. 505 506 See `strongdm.svc.Queries`. 507 ''' 508 self.remote_identities = svc.RemoteIdentities(channel, self) 509 ''' 510 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 511 512 See `strongdm.svc.RemoteIdentities`. 513 ''' 514 self.remote_identities_history = svc.RemoteIdentitiesHistory( 515 channel, self) 516 ''' 517 RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity. 518 519 See `strongdm.svc.RemoteIdentitiesHistory`. 520 ''' 521 self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self) 522 ''' 523 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 524 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 525 526 See `strongdm.svc.RemoteIdentityGroups`. 527 ''' 528 self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory( 529 channel, self) 530 ''' 531 RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup. 532 533 See `strongdm.svc.RemoteIdentityGroupsHistory`. 534 ''' 535 self.replays = svc.Replays(channel, self) 536 ''' 537 A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session 538 (otherwise referred to as a query). The Replays service is read-only. 539 540 See `strongdm.svc.Replays`. 541 ''' 542 self.resources = svc.Resources(channel, self) 543 ''' 544 Resources are databases, servers, clusters, websites, or clouds that strongDM 545 delegates access to. 546 547 See `strongdm.svc.Resources`. 548 ''' 549 self.resources_history = svc.ResourcesHistory(channel, self) 550 ''' 551 ResourcesHistory records all changes to the state of a Resource. 552 553 See `strongdm.svc.ResourcesHistory`. 554 ''' 555 self.role_resources = svc.RoleResources(channel, self) 556 ''' 557 RoleResources enumerates the resources to which roles have access. 558 The RoleResources service is read-only. 559 560 See `strongdm.svc.RoleResources`. 561 ''' 562 self.role_resources_history = svc.RoleResourcesHistory(channel, self) 563 ''' 564 RoleResourcesHistory records all changes to the state of a RoleResource. 565 566 See `strongdm.svc.RoleResourcesHistory`. 567 ''' 568 self.roles_history = svc.RolesHistory(channel, self) 569 ''' 570 RolesHistory records all changes to the state of a Role. 571 572 See `strongdm.svc.RolesHistory`. 573 ''' 574 self.secret_stores = svc.SecretStores(channel, self) 575 ''' 576 SecretStores are servers where resource secrets (passwords, keys) are stored. 577 578 See `strongdm.svc.SecretStores`. 579 ''' 580 self.secret_engines = svc.SecretEngines(channel, self) 581 ''' 582 583 584 See `strongdm.svc.SecretEngines`. 585 ''' 586 self.secret_store_healths = svc.SecretStoreHealths(channel, self) 587 ''' 588 SecretStoreHealths exposes health states for secret stores. 589 590 See `strongdm.svc.SecretStoreHealths`. 591 ''' 592 self.secret_stores_history = svc.SecretStoresHistory(channel, self) 593 ''' 594 SecretStoresHistory records all changes to the state of a SecretStore. 595 596 See `strongdm.svc.SecretStoresHistory`. 597 ''' 598 self.workflow_approvers = svc.WorkflowApprovers(channel, self) 599 ''' 600 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 601 602 See `strongdm.svc.WorkflowApprovers`. 603 ''' 604 self.workflow_approvers_history = svc.WorkflowApproversHistory( 605 channel, self) 606 ''' 607 WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover. 608 609 See `strongdm.svc.WorkflowApproversHistory`. 610 ''' 611 self.workflow_roles = svc.WorkflowRoles(channel, self) 612 ''' 613 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 614 to request access to a resource via the workflow. 615 616 See `strongdm.svc.WorkflowRoles`. 617 ''' 618 self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self) 619 ''' 620 WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole 621 622 See `strongdm.svc.WorkflowRolesHistory`. 623 ''' 624 self.workflows = svc.Workflows(channel, self) 625 ''' 626 Workflows are the collection of rules that define the resources to which access can be requested, 627 the users that can request that access, and the mechanism for approving those requests which can either 628 be automatic approval or a set of users authorized to approve the requests. 629 630 See `strongdm.svc.Workflows`. 631 ''' 632 self.workflows_history = svc.WorkflowsHistory(channel, self) 633 ''' 634 WorkflowsHistory provides records of all changes to the state of a Workflow. 635 636 See `strongdm.svc.WorkflowsHistory`. 637 ''' 638 639 def close(self): 640 '''Closes this Client and releases all resources held by it. 641 642 Closing the Client will immediately terminate all RPCs active with the 643 Client and it is not valid to invoke new RPCs with the Client. 644 645 This method is idempotent. 646 ''' 647 self.channel.close() 648 649 def get_metadata(self, method_name, req): 650 return [ 651 ('x-sdm-authentication', self.api_access_key), 652 ('x-sdm-signature', self.sign(method_name, 653 req.SerializeToString())), 654 ('x-sdm-api-version', API_VERSION), 655 ('x-sdm-user-agent', USER_AGENT), 656 ] 657 658 def sign(self, method_name, request_bytes): 659 def hmac_digest(key, msg_byte_string): 660 return hmac.new(key, msg=msg_byte_string, 661 digestmod=hashlib.sha256).digest() 662 663 current_utc_date = datetime.datetime.now( 664 datetime.timezone.utc).strftime('%Y-%m-%d') 665 signing_key = hmac_digest(self.api_secret, current_utc_date.encode()) 666 signing_key = hmac_digest(signing_key, b'sdm_api_v1') 667 668 hash = hashlib.sha256() 669 670 hash.update(method_name.encode()) 671 hash.update(b'\n') 672 hash.update(request_bytes) 673 674 return base64.b64encode(hmac_digest(signing_key, hash.digest())) 675 676 def exponentialBackoff(self, retries, deadline=None): 677 def applyDeadline(delay, deadline): 678 if deadline is None: 679 return delay 680 remaining = deadline - time.time() 681 if remaining < 0: 682 return 0 683 return min(delay, remaining) 684 685 if retries == 0: 686 return applyDeadline(self.base_retry_delay, deadline) 687 688 backoff, max_delay = self.base_retry_delay, self.max_retry_delay 689 while backoff < max_delay and retries > 0: 690 backoff *= self.retry_factor 691 retries -= 1 692 693 if backoff > max_delay: 694 backoff = max_delay 695 696 # Randomize backoff delays so that if a cluster of requests start at 697 # the same time, they won't operate in lockstep. 698 backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1) 699 if backoff < 0: 700 return 0 701 702 return applyDeadline(backoff, deadline) 703 704 def shouldRetry(self, retries, err, deadline=None): 705 # Check if we've passed the deadline 706 if deadline is not None and time.time() >= deadline: 707 return False 708 709 if not isinstance(err, grpc.RpcError): 710 return False 711 712 if self.retry_rate_limit_errors and err.code( 713 ) == grpc.StatusCode.RESOURCE_EXHAUSTED: 714 return True 715 716 return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL 717 or err.code() == grpc.StatusCode.UNAVAILABLE) 718 719 def snapshot_at(self, snapshot_datetime): 720 ''' 721 Constructs a read-only client that will provide historical data from the provided timestamp. 722 723 See `SnapshotClient`. 724 ''' 725 client = copy.copy(self) 726 client.snapshot_datetime = snapshot_datetime 727 client.access_requests = svc.AccessRequests(client.channel, client) 728 client.account_attachments = svc.AccountAttachments( 729 client.channel, client) 730 client.account_grants = svc.AccountGrants(client.channel, client) 731 client.account_permissions = svc.AccountPermissions( 732 client.channel, client) 733 client.account_resources = svc.AccountResources(client.channel, client) 734 client.accounts = svc.Accounts(client.channel, client) 735 client.accounts_groups = svc.AccountsGroups(client.channel, client) 736 client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 737 client.channel, client) 738 client.approval_workflow_steps = svc.ApprovalWorkflowSteps( 739 client.channel, client) 740 client.approval_workflows = svc.ApprovalWorkflows( 741 client.channel, client) 742 client.discovery_connectors = svc.DiscoveryConnectors( 743 client.channel, client) 744 client.roles = svc.Roles(client.channel, client) 745 client.groups = svc.Groups(client.channel, client) 746 client.groups_roles = svc.GroupsRoles(client.channel, client) 747 client.identity_aliases = svc.IdentityAliases(client.channel, client) 748 client.identity_sets = svc.IdentitySets(client.channel, client) 749 client.nodes = svc.Nodes(client.channel, client) 750 client.policies = svc.Policies(client.channel, client) 751 client.proxy_cluster_keys = svc.ProxyClusterKeys( 752 client.channel, client) 753 client.remote_identities = svc.RemoteIdentities(client.channel, client) 754 client.remote_identity_groups = svc.RemoteIdentityGroups( 755 client.channel, client) 756 client.resources = svc.Resources(client.channel, client) 757 client.role_resources = svc.RoleResources(client.channel, client) 758 client.secret_stores = svc.SecretStores(client.channel, client) 759 client.workflow_approvers = svc.WorkflowApprovers( 760 client.channel, client) 761 client.workflow_roles = svc.WorkflowRoles(client.channel, client) 762 client.workflows = svc.Workflows(client.channel, client) 763 return SnapshotClient(client) 764 765 766class SnapshotClient: 767 '''SnapshotClient exposes methods to query historical records at a provided timestamp.''' 768 def __init__(self, client): 769 self.access_requests = svc.SnapshotAccessRequests( 770 client.access_requests) 771 ''' 772 AccessRequests are requests for access to a resource that may match a Workflow. 773 774 See `strongdm.svc.SnapshotAccessRequests`. 775 ''' 776 self.account_attachments = svc.SnapshotAccountAttachments( 777 client.account_attachments) 778 ''' 779 AccountAttachments assign an account to a role. 780 781 See `strongdm.svc.SnapshotAccountAttachments`. 782 ''' 783 self.account_grants = svc.SnapshotAccountGrants(client.account_grants) 784 ''' 785 AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource. 786 787 See `strongdm.svc.SnapshotAccountGrants`. 788 ''' 789 self.account_permissions = svc.SnapshotAccountPermissions( 790 client.account_permissions) 791 ''' 792 AccountPermissions records the granular permissions accounts have, allowing them to execute 793 relevant commands via StrongDM's APIs. 794 795 See `strongdm.svc.SnapshotAccountPermissions`. 796 ''' 797 self.account_resources = svc.SnapshotAccountResources( 798 client.account_resources) 799 ''' 800 AccountResources enumerates the resources to which accounts have access. 801 The AccountResources service is read-only. 802 803 See `strongdm.svc.SnapshotAccountResources`. 804 ''' 805 self.accounts = svc.SnapshotAccounts(client.accounts) 806 ''' 807 Accounts are users that have access to strongDM. There are two types of accounts: 808 1. **Users:** humans who are authenticated through username and password or SSO. 809 2. **Service Accounts:** machines that are authenticated using a service token. 810 3. **Tokens** are access keys with permissions that can be used for authentication. 811 812 See `strongdm.svc.SnapshotAccounts`. 813 ''' 814 self.accounts_groups = svc.SnapshotAccountsGroups( 815 client.accounts_groups) 816 ''' 817 An AccountGroup links an account and a group. 818 819 See `strongdm.svc.SnapshotAccountsGroups`. 820 ''' 821 self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers( 822 client.approval_workflow_approvers) 823 ''' 824 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 825 826 See `strongdm.svc.SnapshotApprovalWorkflowApprovers`. 827 ''' 828 self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps( 829 client.approval_workflow_steps) 830 ''' 831 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 832 833 See `strongdm.svc.SnapshotApprovalWorkflowSteps`. 834 ''' 835 self.approval_workflows = svc.SnapshotApprovalWorkflows( 836 client.approval_workflows) 837 ''' 838 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 839 approvers and be approved or denied. 840 841 See `strongdm.svc.SnapshotApprovalWorkflows`. 842 ''' 843 self.discovery_connectors = svc.SnapshotDiscoveryConnectors( 844 client.discovery_connectors) 845 ''' 846 A Discovery Connector is a configuration object for performing Resource 847 Scans in remote systems such as AWS, GCP, Azure, and other systems. 848 849 See `strongdm.svc.SnapshotDiscoveryConnectors`. 850 ''' 851 self.roles = svc.SnapshotRoles(client.roles) 852 ''' 853 A Role has a list of access rules which determine which Resources the members 854 of the Role have access to. An Account can be a member of multiple Roles via 855 AccountAttachments. 856 857 See `strongdm.svc.SnapshotRoles`. 858 ''' 859 self.groups = svc.SnapshotGroups(client.groups) 860 ''' 861 A Group is a set of principals. 862 863 See `strongdm.svc.SnapshotGroups`. 864 ''' 865 self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles) 866 ''' 867 A GroupRole is an assignment of a Group to a Role. 868 869 See `strongdm.svc.SnapshotGroupsRoles`. 870 ''' 871 self.identity_aliases = svc.SnapshotIdentityAliases( 872 client.identity_aliases) 873 ''' 874 IdentityAliases assign an alias to an account within an IdentitySet. 875 The alias is used as the username when connecting to a identity supported resource. 876 877 See `strongdm.svc.SnapshotIdentityAliases`. 878 ''' 879 self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets) 880 ''' 881 A IdentitySet is a named grouping of Identity Aliases for Accounts. 882 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 883 884 See `strongdm.svc.SnapshotIdentitySets`. 885 ''' 886 self.nodes = svc.SnapshotNodes(client.nodes) 887 ''' 888 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 889 There are three types of nodes: 890 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 891 2. **Gateway:** a relay that also listens for connections from StrongDM clients 892 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 893 894 See `strongdm.svc.SnapshotNodes`. 895 ''' 896 self.policies = svc.SnapshotPolicies(client.policies) 897 ''' 898 Policies are the collection of one or more statements that enforce fine-grained access 899 control for the users of an organization. 900 901 See `strongdm.svc.SnapshotPolicies`. 902 ''' 903 self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys( 904 client.proxy_cluster_keys) 905 ''' 906 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 907 The proxies within a cluster share the same key. One cluster can have 908 multiple keys in order to facilitate key rotation. 909 910 See `strongdm.svc.SnapshotProxyClusterKeys`. 911 ''' 912 self.remote_identities = svc.SnapshotRemoteIdentities( 913 client.remote_identities) 914 ''' 915 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 916 917 See `strongdm.svc.SnapshotRemoteIdentities`. 918 ''' 919 self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups( 920 client.remote_identity_groups) 921 ''' 922 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 923 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 924 925 See `strongdm.svc.SnapshotRemoteIdentityGroups`. 926 ''' 927 self.resources = svc.SnapshotResources(client.resources) 928 ''' 929 Resources are databases, servers, clusters, websites, or clouds that strongDM 930 delegates access to. 931 932 See `strongdm.svc.SnapshotResources`. 933 ''' 934 self.role_resources = svc.SnapshotRoleResources(client.role_resources) 935 ''' 936 RoleResources enumerates the resources to which roles have access. 937 The RoleResources service is read-only. 938 939 See `strongdm.svc.SnapshotRoleResources`. 940 ''' 941 self.secret_stores = svc.SnapshotSecretStores(client.secret_stores) 942 ''' 943 SecretStores are servers where resource secrets (passwords, keys) are stored. 944 945 See `strongdm.svc.SnapshotSecretStores`. 946 ''' 947 self.workflow_approvers = svc.SnapshotWorkflowApprovers( 948 client.workflow_approvers) 949 ''' 950 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 951 952 See `strongdm.svc.SnapshotWorkflowApprovers`. 953 ''' 954 self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles) 955 ''' 956 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 957 to request access to a resource via the workflow. 958 959 See `strongdm.svc.SnapshotWorkflowRoles`. 960 ''' 961 self.workflows = svc.SnapshotWorkflows(client.workflows) 962 ''' 963 Workflows are the collection of rules that define the resources to which access can be requested, 964 the users that can request that access, and the mechanism for approving those requests which can either 965 be automatic approval or a set of users authorized to approve the requests. 966 967 See `strongdm.svc.SnapshotWorkflows`. 968 '''
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.roles = svc.Roles(channel, self) 361 ''' 362 A Role has a list of access rules which determine which Resources the members 363 of the Role have access to. An Account can be a member of multiple Roles via 364 AccountAttachments. 365 366 See `strongdm.svc.Roles`. 367 ''' 368 self.groups = svc.Groups(channel, self) 369 ''' 370 A Group is a set of principals. 371 372 See `strongdm.svc.Groups`. 373 ''' 374 self.groups_history = svc.GroupsHistory(channel, self) 375 ''' 376 GroupsHistory records all changes to the state of a Group. 377 378 See `strongdm.svc.GroupsHistory`. 379 ''' 380 self.groups_roles = svc.GroupsRoles(channel, self) 381 ''' 382 A GroupRole is an assignment of a Group to a Role. 383 384 See `strongdm.svc.GroupsRoles`. 385 ''' 386 self.groups_roles_history = svc.GroupsRolesHistory(channel, self) 387 ''' 388 GroupsRolesHistory records all changes to the state of a GroupRole. 389 390 See `strongdm.svc.GroupsRolesHistory`. 391 ''' 392 self.health_checks = svc.HealthChecks(channel, self) 393 ''' 394 HealthChecks lists the last healthcheck between each node and resource. 395 Note the unconventional capitalization here is to prevent having a collision with GRPC 396 397 See `strongdm.svc.HealthChecks`. 398 ''' 399 self.identity_aliases = svc.IdentityAliases(channel, self) 400 ''' 401 IdentityAliases assign an alias to an account within an IdentitySet. 402 The alias is used as the username when connecting to a identity supported resource. 403 404 See `strongdm.svc.IdentityAliases`. 405 ''' 406 self.identity_aliases_history = svc.IdentityAliasesHistory( 407 channel, self) 408 ''' 409 IdentityAliasesHistory records all changes to the state of a IdentityAlias. 410 411 See `strongdm.svc.IdentityAliasesHistory`. 412 ''' 413 self.identity_sets = svc.IdentitySets(channel, self) 414 ''' 415 A IdentitySet is a named grouping of Identity Aliases for Accounts. 416 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 417 418 See `strongdm.svc.IdentitySets`. 419 ''' 420 self.identity_sets_history = svc.IdentitySetsHistory(channel, self) 421 ''' 422 IdentitySetsHistory records all changes to the state of a IdentitySet. 423 424 See `strongdm.svc.IdentitySetsHistory`. 425 ''' 426 self.managed_secrets = svc.ManagedSecrets(channel, self) 427 ''' 428 ManagedSecret is a private vertical for creating, reading, updating, 429 deleting, listing and rotating the managed secrets in the secrets engines as 430 an authenticated user. 431 432 See `strongdm.svc.ManagedSecrets`. 433 ''' 434 self.nodes = svc.Nodes(channel, self) 435 ''' 436 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 437 There are three types of nodes: 438 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 439 2. **Gateway:** a relay that also listens for connections from StrongDM clients 440 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 441 442 See `strongdm.svc.Nodes`. 443 ''' 444 self.nodes_history = svc.NodesHistory(channel, self) 445 ''' 446 NodesHistory records all changes to the state of a Node. 447 448 See `strongdm.svc.NodesHistory`. 449 ''' 450 self.organization_history = svc.OrganizationHistory(channel, self) 451 ''' 452 OrganizationHistory records all changes to the state of an Organization. 453 454 See `strongdm.svc.OrganizationHistory`. 455 ''' 456 self.peering_group_nodes = svc.PeeringGroupNodes(channel, self) 457 ''' 458 PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group. 459 460 See `strongdm.svc.PeeringGroupNodes`. 461 ''' 462 self.peering_group_peers = svc.PeeringGroupPeers(channel, self) 463 ''' 464 PeeringGroupPeers provides the building blocks necessary to link two peering groups. 465 466 See `strongdm.svc.PeeringGroupPeers`. 467 ''' 468 self.peering_group_resources = svc.PeeringGroupResources(channel, self) 469 ''' 470 PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group. 471 472 See `strongdm.svc.PeeringGroupResources`. 473 ''' 474 self.peering_groups = svc.PeeringGroups(channel, self) 475 ''' 476 PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing. 477 478 See `strongdm.svc.PeeringGroups`. 479 ''' 480 self.policies = svc.Policies(channel, self) 481 ''' 482 Policies are the collection of one or more statements that enforce fine-grained access 483 control for the users of an organization. 484 485 See `strongdm.svc.Policies`. 486 ''' 487 self.policies_history = svc.PoliciesHistory(channel, self) 488 ''' 489 PoliciesHistory records all changes to the state of a Policy. 490 491 See `strongdm.svc.PoliciesHistory`. 492 ''' 493 self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self) 494 ''' 495 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 496 The proxies within a cluster share the same key. One cluster can have 497 multiple keys in order to facilitate key rotation. 498 499 See `strongdm.svc.ProxyClusterKeys`. 500 ''' 501 self.queries = svc.Queries(channel, self) 502 ''' 503 A Query is a record of a single client request to a resource, such as a SQL query. 504 Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries. 505 The Queries service is read-only. 506 507 See `strongdm.svc.Queries`. 508 ''' 509 self.remote_identities = svc.RemoteIdentities(channel, self) 510 ''' 511 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 512 513 See `strongdm.svc.RemoteIdentities`. 514 ''' 515 self.remote_identities_history = svc.RemoteIdentitiesHistory( 516 channel, self) 517 ''' 518 RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity. 519 520 See `strongdm.svc.RemoteIdentitiesHistory`. 521 ''' 522 self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self) 523 ''' 524 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 525 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 526 527 See `strongdm.svc.RemoteIdentityGroups`. 528 ''' 529 self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory( 530 channel, self) 531 ''' 532 RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup. 533 534 See `strongdm.svc.RemoteIdentityGroupsHistory`. 535 ''' 536 self.replays = svc.Replays(channel, self) 537 ''' 538 A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session 539 (otherwise referred to as a query). The Replays service is read-only. 540 541 See `strongdm.svc.Replays`. 542 ''' 543 self.resources = svc.Resources(channel, self) 544 ''' 545 Resources are databases, servers, clusters, websites, or clouds that strongDM 546 delegates access to. 547 548 See `strongdm.svc.Resources`. 549 ''' 550 self.resources_history = svc.ResourcesHistory(channel, self) 551 ''' 552 ResourcesHistory records all changes to the state of a Resource. 553 554 See `strongdm.svc.ResourcesHistory`. 555 ''' 556 self.role_resources = svc.RoleResources(channel, self) 557 ''' 558 RoleResources enumerates the resources to which roles have access. 559 The RoleResources service is read-only. 560 561 See `strongdm.svc.RoleResources`. 562 ''' 563 self.role_resources_history = svc.RoleResourcesHistory(channel, self) 564 ''' 565 RoleResourcesHistory records all changes to the state of a RoleResource. 566 567 See `strongdm.svc.RoleResourcesHistory`. 568 ''' 569 self.roles_history = svc.RolesHistory(channel, self) 570 ''' 571 RolesHistory records all changes to the state of a Role. 572 573 See `strongdm.svc.RolesHistory`. 574 ''' 575 self.secret_stores = svc.SecretStores(channel, self) 576 ''' 577 SecretStores are servers where resource secrets (passwords, keys) are stored. 578 579 See `strongdm.svc.SecretStores`. 580 ''' 581 self.secret_engines = svc.SecretEngines(channel, self) 582 ''' 583 584 585 See `strongdm.svc.SecretEngines`. 586 ''' 587 self.secret_store_healths = svc.SecretStoreHealths(channel, self) 588 ''' 589 SecretStoreHealths exposes health states for secret stores. 590 591 See `strongdm.svc.SecretStoreHealths`. 592 ''' 593 self.secret_stores_history = svc.SecretStoresHistory(channel, self) 594 ''' 595 SecretStoresHistory records all changes to the state of a SecretStore. 596 597 See `strongdm.svc.SecretStoresHistory`. 598 ''' 599 self.workflow_approvers = svc.WorkflowApprovers(channel, self) 600 ''' 601 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 602 603 See `strongdm.svc.WorkflowApprovers`. 604 ''' 605 self.workflow_approvers_history = svc.WorkflowApproversHistory( 606 channel, self) 607 ''' 608 WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover. 609 610 See `strongdm.svc.WorkflowApproversHistory`. 611 ''' 612 self.workflow_roles = svc.WorkflowRoles(channel, self) 613 ''' 614 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 615 to request access to a resource via the workflow. 616 617 See `strongdm.svc.WorkflowRoles`. 618 ''' 619 self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self) 620 ''' 621 WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole 622 623 See `strongdm.svc.WorkflowRolesHistory`. 624 ''' 625 self.workflows = svc.Workflows(channel, self) 626 ''' 627 Workflows are the collection of rules that define the resources to which access can be requested, 628 the users that can request that access, and the mechanism for approving those requests which can either 629 be automatic approval or a set of users authorized to approve the requests. 630 631 See `strongdm.svc.Workflows`. 632 ''' 633 self.workflows_history = svc.WorkflowsHistory(channel, self) 634 ''' 635 WorkflowsHistory provides records of all changes to the state of a Workflow. 636 637 See `strongdm.svc.WorkflowsHistory`. 638 ''' 639 640 def close(self): 641 '''Closes this Client and releases all resources held by it. 642 643 Closing the Client will immediately terminate all RPCs active with the 644 Client and it is not valid to invoke new RPCs with the Client. 645 646 This method is idempotent. 647 ''' 648 self.channel.close() 649 650 def get_metadata(self, method_name, req): 651 return [ 652 ('x-sdm-authentication', self.api_access_key), 653 ('x-sdm-signature', self.sign(method_name, 654 req.SerializeToString())), 655 ('x-sdm-api-version', API_VERSION), 656 ('x-sdm-user-agent', USER_AGENT), 657 ] 658 659 def sign(self, method_name, request_bytes): 660 def hmac_digest(key, msg_byte_string): 661 return hmac.new(key, msg=msg_byte_string, 662 digestmod=hashlib.sha256).digest() 663 664 current_utc_date = datetime.datetime.now( 665 datetime.timezone.utc).strftime('%Y-%m-%d') 666 signing_key = hmac_digest(self.api_secret, current_utc_date.encode()) 667 signing_key = hmac_digest(signing_key, b'sdm_api_v1') 668 669 hash = hashlib.sha256() 670 671 hash.update(method_name.encode()) 672 hash.update(b'\n') 673 hash.update(request_bytes) 674 675 return base64.b64encode(hmac_digest(signing_key, hash.digest())) 676 677 def exponentialBackoff(self, retries, deadline=None): 678 def applyDeadline(delay, deadline): 679 if deadline is None: 680 return delay 681 remaining = deadline - time.time() 682 if remaining < 0: 683 return 0 684 return min(delay, remaining) 685 686 if retries == 0: 687 return applyDeadline(self.base_retry_delay, deadline) 688 689 backoff, max_delay = self.base_retry_delay, self.max_retry_delay 690 while backoff < max_delay and retries > 0: 691 backoff *= self.retry_factor 692 retries -= 1 693 694 if backoff > max_delay: 695 backoff = max_delay 696 697 # Randomize backoff delays so that if a cluster of requests start at 698 # the same time, they won't operate in lockstep. 699 backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1) 700 if backoff < 0: 701 return 0 702 703 return applyDeadline(backoff, deadline) 704 705 def shouldRetry(self, retries, err, deadline=None): 706 # Check if we've passed the deadline 707 if deadline is not None and time.time() >= deadline: 708 return False 709 710 if not isinstance(err, grpc.RpcError): 711 return False 712 713 if self.retry_rate_limit_errors and err.code( 714 ) == grpc.StatusCode.RESOURCE_EXHAUSTED: 715 return True 716 717 return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL 718 or err.code() == grpc.StatusCode.UNAVAILABLE) 719 720 def snapshot_at(self, snapshot_datetime): 721 ''' 722 Constructs a read-only client that will provide historical data from the provided timestamp. 723 724 See `SnapshotClient`. 725 ''' 726 client = copy.copy(self) 727 client.snapshot_datetime = snapshot_datetime 728 client.access_requests = svc.AccessRequests(client.channel, client) 729 client.account_attachments = svc.AccountAttachments( 730 client.channel, client) 731 client.account_grants = svc.AccountGrants(client.channel, client) 732 client.account_permissions = svc.AccountPermissions( 733 client.channel, client) 734 client.account_resources = svc.AccountResources(client.channel, client) 735 client.accounts = svc.Accounts(client.channel, client) 736 client.accounts_groups = svc.AccountsGroups(client.channel, client) 737 client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 738 client.channel, client) 739 client.approval_workflow_steps = svc.ApprovalWorkflowSteps( 740 client.channel, client) 741 client.approval_workflows = svc.ApprovalWorkflows( 742 client.channel, client) 743 client.discovery_connectors = svc.DiscoveryConnectors( 744 client.channel, client) 745 client.roles = svc.Roles(client.channel, client) 746 client.groups = svc.Groups(client.channel, client) 747 client.groups_roles = svc.GroupsRoles(client.channel, client) 748 client.identity_aliases = svc.IdentityAliases(client.channel, client) 749 client.identity_sets = svc.IdentitySets(client.channel, client) 750 client.nodes = svc.Nodes(client.channel, client) 751 client.policies = svc.Policies(client.channel, client) 752 client.proxy_cluster_keys = svc.ProxyClusterKeys( 753 client.channel, client) 754 client.remote_identities = svc.RemoteIdentities(client.channel, client) 755 client.remote_identity_groups = svc.RemoteIdentityGroups( 756 client.channel, client) 757 client.resources = svc.Resources(client.channel, client) 758 client.role_resources = svc.RoleResources(client.channel, client) 759 client.secret_stores = svc.SecretStores(client.channel, client) 760 client.workflow_approvers = svc.WorkflowApprovers( 761 client.channel, client) 762 client.workflow_roles = svc.WorkflowRoles(client.channel, client) 763 client.workflows = svc.Workflows(client.channel, client) 764 return SnapshotClient(client)
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.roles = svc.Roles(channel, self) 361 ''' 362 A Role has a list of access rules which determine which Resources the members 363 of the Role have access to. An Account can be a member of multiple Roles via 364 AccountAttachments. 365 366 See `strongdm.svc.Roles`. 367 ''' 368 self.groups = svc.Groups(channel, self) 369 ''' 370 A Group is a set of principals. 371 372 See `strongdm.svc.Groups`. 373 ''' 374 self.groups_history = svc.GroupsHistory(channel, self) 375 ''' 376 GroupsHistory records all changes to the state of a Group. 377 378 See `strongdm.svc.GroupsHistory`. 379 ''' 380 self.groups_roles = svc.GroupsRoles(channel, self) 381 ''' 382 A GroupRole is an assignment of a Group to a Role. 383 384 See `strongdm.svc.GroupsRoles`. 385 ''' 386 self.groups_roles_history = svc.GroupsRolesHistory(channel, self) 387 ''' 388 GroupsRolesHistory records all changes to the state of a GroupRole. 389 390 See `strongdm.svc.GroupsRolesHistory`. 391 ''' 392 self.health_checks = svc.HealthChecks(channel, self) 393 ''' 394 HealthChecks lists the last healthcheck between each node and resource. 395 Note the unconventional capitalization here is to prevent having a collision with GRPC 396 397 See `strongdm.svc.HealthChecks`. 398 ''' 399 self.identity_aliases = svc.IdentityAliases(channel, self) 400 ''' 401 IdentityAliases assign an alias to an account within an IdentitySet. 402 The alias is used as the username when connecting to a identity supported resource. 403 404 See `strongdm.svc.IdentityAliases`. 405 ''' 406 self.identity_aliases_history = svc.IdentityAliasesHistory( 407 channel, self) 408 ''' 409 IdentityAliasesHistory records all changes to the state of a IdentityAlias. 410 411 See `strongdm.svc.IdentityAliasesHistory`. 412 ''' 413 self.identity_sets = svc.IdentitySets(channel, self) 414 ''' 415 A IdentitySet is a named grouping of Identity Aliases for Accounts. 416 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 417 418 See `strongdm.svc.IdentitySets`. 419 ''' 420 self.identity_sets_history = svc.IdentitySetsHistory(channel, self) 421 ''' 422 IdentitySetsHistory records all changes to the state of a IdentitySet. 423 424 See `strongdm.svc.IdentitySetsHistory`. 425 ''' 426 self.managed_secrets = svc.ManagedSecrets(channel, self) 427 ''' 428 ManagedSecret is a private vertical for creating, reading, updating, 429 deleting, listing and rotating the managed secrets in the secrets engines as 430 an authenticated user. 431 432 See `strongdm.svc.ManagedSecrets`. 433 ''' 434 self.nodes = svc.Nodes(channel, self) 435 ''' 436 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 437 There are three types of nodes: 438 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 439 2. **Gateway:** a relay that also listens for connections from StrongDM clients 440 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 441 442 See `strongdm.svc.Nodes`. 443 ''' 444 self.nodes_history = svc.NodesHistory(channel, self) 445 ''' 446 NodesHistory records all changes to the state of a Node. 447 448 See `strongdm.svc.NodesHistory`. 449 ''' 450 self.organization_history = svc.OrganizationHistory(channel, self) 451 ''' 452 OrganizationHistory records all changes to the state of an Organization. 453 454 See `strongdm.svc.OrganizationHistory`. 455 ''' 456 self.peering_group_nodes = svc.PeeringGroupNodes(channel, self) 457 ''' 458 PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group. 459 460 See `strongdm.svc.PeeringGroupNodes`. 461 ''' 462 self.peering_group_peers = svc.PeeringGroupPeers(channel, self) 463 ''' 464 PeeringGroupPeers provides the building blocks necessary to link two peering groups. 465 466 See `strongdm.svc.PeeringGroupPeers`. 467 ''' 468 self.peering_group_resources = svc.PeeringGroupResources(channel, self) 469 ''' 470 PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group. 471 472 See `strongdm.svc.PeeringGroupResources`. 473 ''' 474 self.peering_groups = svc.PeeringGroups(channel, self) 475 ''' 476 PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing. 477 478 See `strongdm.svc.PeeringGroups`. 479 ''' 480 self.policies = svc.Policies(channel, self) 481 ''' 482 Policies are the collection of one or more statements that enforce fine-grained access 483 control for the users of an organization. 484 485 See `strongdm.svc.Policies`. 486 ''' 487 self.policies_history = svc.PoliciesHistory(channel, self) 488 ''' 489 PoliciesHistory records all changes to the state of a Policy. 490 491 See `strongdm.svc.PoliciesHistory`. 492 ''' 493 self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self) 494 ''' 495 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 496 The proxies within a cluster share the same key. One cluster can have 497 multiple keys in order to facilitate key rotation. 498 499 See `strongdm.svc.ProxyClusterKeys`. 500 ''' 501 self.queries = svc.Queries(channel, self) 502 ''' 503 A Query is a record of a single client request to a resource, such as a SQL query. 504 Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries. 505 The Queries service is read-only. 506 507 See `strongdm.svc.Queries`. 508 ''' 509 self.remote_identities = svc.RemoteIdentities(channel, self) 510 ''' 511 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 512 513 See `strongdm.svc.RemoteIdentities`. 514 ''' 515 self.remote_identities_history = svc.RemoteIdentitiesHistory( 516 channel, self) 517 ''' 518 RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity. 519 520 See `strongdm.svc.RemoteIdentitiesHistory`. 521 ''' 522 self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self) 523 ''' 524 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 525 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 526 527 See `strongdm.svc.RemoteIdentityGroups`. 528 ''' 529 self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory( 530 channel, self) 531 ''' 532 RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup. 533 534 See `strongdm.svc.RemoteIdentityGroupsHistory`. 535 ''' 536 self.replays = svc.Replays(channel, self) 537 ''' 538 A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session 539 (otherwise referred to as a query). The Replays service is read-only. 540 541 See `strongdm.svc.Replays`. 542 ''' 543 self.resources = svc.Resources(channel, self) 544 ''' 545 Resources are databases, servers, clusters, websites, or clouds that strongDM 546 delegates access to. 547 548 See `strongdm.svc.Resources`. 549 ''' 550 self.resources_history = svc.ResourcesHistory(channel, self) 551 ''' 552 ResourcesHistory records all changes to the state of a Resource. 553 554 See `strongdm.svc.ResourcesHistory`. 555 ''' 556 self.role_resources = svc.RoleResources(channel, self) 557 ''' 558 RoleResources enumerates the resources to which roles have access. 559 The RoleResources service is read-only. 560 561 See `strongdm.svc.RoleResources`. 562 ''' 563 self.role_resources_history = svc.RoleResourcesHistory(channel, self) 564 ''' 565 RoleResourcesHistory records all changes to the state of a RoleResource. 566 567 See `strongdm.svc.RoleResourcesHistory`. 568 ''' 569 self.roles_history = svc.RolesHistory(channel, self) 570 ''' 571 RolesHistory records all changes to the state of a Role. 572 573 See `strongdm.svc.RolesHistory`. 574 ''' 575 self.secret_stores = svc.SecretStores(channel, self) 576 ''' 577 SecretStores are servers where resource secrets (passwords, keys) are stored. 578 579 See `strongdm.svc.SecretStores`. 580 ''' 581 self.secret_engines = svc.SecretEngines(channel, self) 582 ''' 583 584 585 See `strongdm.svc.SecretEngines`. 586 ''' 587 self.secret_store_healths = svc.SecretStoreHealths(channel, self) 588 ''' 589 SecretStoreHealths exposes health states for secret stores. 590 591 See `strongdm.svc.SecretStoreHealths`. 592 ''' 593 self.secret_stores_history = svc.SecretStoresHistory(channel, self) 594 ''' 595 SecretStoresHistory records all changes to the state of a SecretStore. 596 597 See `strongdm.svc.SecretStoresHistory`. 598 ''' 599 self.workflow_approvers = svc.WorkflowApprovers(channel, self) 600 ''' 601 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 602 603 See `strongdm.svc.WorkflowApprovers`. 604 ''' 605 self.workflow_approvers_history = svc.WorkflowApproversHistory( 606 channel, self) 607 ''' 608 WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover. 609 610 See `strongdm.svc.WorkflowApproversHistory`. 611 ''' 612 self.workflow_roles = svc.WorkflowRoles(channel, self) 613 ''' 614 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 615 to request access to a resource via the workflow. 616 617 See `strongdm.svc.WorkflowRoles`. 618 ''' 619 self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self) 620 ''' 621 WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole 622 623 See `strongdm.svc.WorkflowRolesHistory`. 624 ''' 625 self.workflows = svc.Workflows(channel, self) 626 ''' 627 Workflows are the collection of rules that define the resources to which access can be requested, 628 the users that can request that access, and the mechanism for approving those requests which can either 629 be automatic approval or a set of users authorized to approve the requests. 630 631 See `strongdm.svc.Workflows`. 632 ''' 633 self.workflows_history = svc.WorkflowsHistory(channel, self) 634 ''' 635 WorkflowsHistory provides records of all changes to the state of a Workflow. 636 637 See `strongdm.svc.WorkflowsHistory`. 638 '''
Create a new Client.
- api_access_key: the access key to authenticate with strongDM
- api_secret: the secret key to authenticate with strongDM
AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.
AccessRequestsHistory provides records of all changes to the state of an AccessRequest.
AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
AccountPermissions records the granular permissions accounts have, allowing them to execute relevant commands via StrongDM's APIs.
AccountResources enumerates the resources to which accounts have access. The AccountResources service is read-only.
AccountResourcesHistory records all changes to the state of a AccountResource.
Accounts are users that have access to strongDM. There are two types of accounts:
- Users: humans who are authenticated through username and password or SSO.
- Service Accounts: machines that are authenticated using a service token.
- Tokens are access keys with permissions that can be used for authentication.
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.
ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.
ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.
ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized approvers and be approved or denied.
ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.
A Discovery Connector is a configuration object for performing Resource Scans in remote systems such as AWS, GCP, Azure, and other systems.
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.
HealthChecks lists the last healthcheck between each node and resource. Note the unconventional capitalization here is to prevent having a collision with GRPC
IdentityAliases assign an alias to an account within an IdentitySet. The alias is used as the username when connecting to a identity supported resource.
IdentityAliasesHistory records all changes to the state of a IdentityAlias.
A IdentitySet is a named grouping of Identity Aliases for Accounts. An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
ManagedSecret is a private vertical for creating, reading, updating, deleting, listing and rotating the managed secrets in the secrets engines as an authenticated user.
Nodes make up the StrongDM network, and allow your users to connect securely to your resources. There are three types of nodes:
- Relay: creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
- Gateway: a relay that also listens for connections from StrongDM clients
- Proxy Cluster: a cluster of workers that together mediate access from clients to resources
See strongdm.svc.Nodes.
PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.
PeeringGroupPeers provides the building blocks necessary to link two peering groups.
PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.
PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.
Policies are the collection of one or more statements that enforce fine-grained access control for the users of an organization.
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.
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.
RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
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 are databases, servers, clusters, websites, or clouds that strongDM delegates access to.
RoleResources enumerates the resources to which roles have access. The RoleResources service is read-only.
WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.
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.
WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole
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.
640 def close(self): 641 '''Closes this Client and releases all resources held by it. 642 643 Closing the Client will immediately terminate all RPCs active with the 644 Client and it is not valid to invoke new RPCs with the Client. 645 646 This method is idempotent. 647 ''' 648 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.
659 def sign(self, method_name, request_bytes): 660 def hmac_digest(key, msg_byte_string): 661 return hmac.new(key, msg=msg_byte_string, 662 digestmod=hashlib.sha256).digest() 663 664 current_utc_date = datetime.datetime.now( 665 datetime.timezone.utc).strftime('%Y-%m-%d') 666 signing_key = hmac_digest(self.api_secret, current_utc_date.encode()) 667 signing_key = hmac_digest(signing_key, b'sdm_api_v1') 668 669 hash = hashlib.sha256() 670 671 hash.update(method_name.encode()) 672 hash.update(b'\n') 673 hash.update(request_bytes) 674 675 return base64.b64encode(hmac_digest(signing_key, hash.digest()))
677 def exponentialBackoff(self, retries, deadline=None): 678 def applyDeadline(delay, deadline): 679 if deadline is None: 680 return delay 681 remaining = deadline - time.time() 682 if remaining < 0: 683 return 0 684 return min(delay, remaining) 685 686 if retries == 0: 687 return applyDeadline(self.base_retry_delay, deadline) 688 689 backoff, max_delay = self.base_retry_delay, self.max_retry_delay 690 while backoff < max_delay and retries > 0: 691 backoff *= self.retry_factor 692 retries -= 1 693 694 if backoff > max_delay: 695 backoff = max_delay 696 697 # Randomize backoff delays so that if a cluster of requests start at 698 # the same time, they won't operate in lockstep. 699 backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1) 700 if backoff < 0: 701 return 0 702 703 return applyDeadline(backoff, deadline)
705 def shouldRetry(self, retries, err, deadline=None): 706 # Check if we've passed the deadline 707 if deadline is not None and time.time() >= deadline: 708 return False 709 710 if not isinstance(err, grpc.RpcError): 711 return False 712 713 if self.retry_rate_limit_errors and err.code( 714 ) == grpc.StatusCode.RESOURCE_EXHAUSTED: 715 return True 716 717 return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL 718 or err.code() == grpc.StatusCode.UNAVAILABLE)
720 def snapshot_at(self, snapshot_datetime): 721 ''' 722 Constructs a read-only client that will provide historical data from the provided timestamp. 723 724 See `SnapshotClient`. 725 ''' 726 client = copy.copy(self) 727 client.snapshot_datetime = snapshot_datetime 728 client.access_requests = svc.AccessRequests(client.channel, client) 729 client.account_attachments = svc.AccountAttachments( 730 client.channel, client) 731 client.account_grants = svc.AccountGrants(client.channel, client) 732 client.account_permissions = svc.AccountPermissions( 733 client.channel, client) 734 client.account_resources = svc.AccountResources(client.channel, client) 735 client.accounts = svc.Accounts(client.channel, client) 736 client.accounts_groups = svc.AccountsGroups(client.channel, client) 737 client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 738 client.channel, client) 739 client.approval_workflow_steps = svc.ApprovalWorkflowSteps( 740 client.channel, client) 741 client.approval_workflows = svc.ApprovalWorkflows( 742 client.channel, client) 743 client.discovery_connectors = svc.DiscoveryConnectors( 744 client.channel, client) 745 client.roles = svc.Roles(client.channel, client) 746 client.groups = svc.Groups(client.channel, client) 747 client.groups_roles = svc.GroupsRoles(client.channel, client) 748 client.identity_aliases = svc.IdentityAliases(client.channel, client) 749 client.identity_sets = svc.IdentitySets(client.channel, client) 750 client.nodes = svc.Nodes(client.channel, client) 751 client.policies = svc.Policies(client.channel, client) 752 client.proxy_cluster_keys = svc.ProxyClusterKeys( 753 client.channel, client) 754 client.remote_identities = svc.RemoteIdentities(client.channel, client) 755 client.remote_identity_groups = svc.RemoteIdentityGroups( 756 client.channel, client) 757 client.resources = svc.Resources(client.channel, client) 758 client.role_resources = svc.RoleResources(client.channel, client) 759 client.secret_stores = svc.SecretStores(client.channel, client) 760 client.workflow_approvers = svc.WorkflowApprovers( 761 client.channel, client) 762 client.workflow_roles = svc.WorkflowRoles(client.channel, client) 763 client.workflows = svc.Workflows(client.channel, client) 764 return SnapshotClient(client)
Constructs a read-only client that will provide historical data from the provided timestamp.
See SnapshotClient.
767class SnapshotClient: 768 '''SnapshotClient exposes methods to query historical records at a provided timestamp.''' 769 def __init__(self, client): 770 self.access_requests = svc.SnapshotAccessRequests( 771 client.access_requests) 772 ''' 773 AccessRequests are requests for access to a resource that may match a Workflow. 774 775 See `strongdm.svc.SnapshotAccessRequests`. 776 ''' 777 self.account_attachments = svc.SnapshotAccountAttachments( 778 client.account_attachments) 779 ''' 780 AccountAttachments assign an account to a role. 781 782 See `strongdm.svc.SnapshotAccountAttachments`. 783 ''' 784 self.account_grants = svc.SnapshotAccountGrants(client.account_grants) 785 ''' 786 AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource. 787 788 See `strongdm.svc.SnapshotAccountGrants`. 789 ''' 790 self.account_permissions = svc.SnapshotAccountPermissions( 791 client.account_permissions) 792 ''' 793 AccountPermissions records the granular permissions accounts have, allowing them to execute 794 relevant commands via StrongDM's APIs. 795 796 See `strongdm.svc.SnapshotAccountPermissions`. 797 ''' 798 self.account_resources = svc.SnapshotAccountResources( 799 client.account_resources) 800 ''' 801 AccountResources enumerates the resources to which accounts have access. 802 The AccountResources service is read-only. 803 804 See `strongdm.svc.SnapshotAccountResources`. 805 ''' 806 self.accounts = svc.SnapshotAccounts(client.accounts) 807 ''' 808 Accounts are users that have access to strongDM. There are two types of accounts: 809 1. **Users:** humans who are authenticated through username and password or SSO. 810 2. **Service Accounts:** machines that are authenticated using a service token. 811 3. **Tokens** are access keys with permissions that can be used for authentication. 812 813 See `strongdm.svc.SnapshotAccounts`. 814 ''' 815 self.accounts_groups = svc.SnapshotAccountsGroups( 816 client.accounts_groups) 817 ''' 818 An AccountGroup links an account and a group. 819 820 See `strongdm.svc.SnapshotAccountsGroups`. 821 ''' 822 self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers( 823 client.approval_workflow_approvers) 824 ''' 825 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 826 827 See `strongdm.svc.SnapshotApprovalWorkflowApprovers`. 828 ''' 829 self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps( 830 client.approval_workflow_steps) 831 ''' 832 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 833 834 See `strongdm.svc.SnapshotApprovalWorkflowSteps`. 835 ''' 836 self.approval_workflows = svc.SnapshotApprovalWorkflows( 837 client.approval_workflows) 838 ''' 839 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 840 approvers and be approved or denied. 841 842 See `strongdm.svc.SnapshotApprovalWorkflows`. 843 ''' 844 self.discovery_connectors = svc.SnapshotDiscoveryConnectors( 845 client.discovery_connectors) 846 ''' 847 A Discovery Connector is a configuration object for performing Resource 848 Scans in remote systems such as AWS, GCP, Azure, and other systems. 849 850 See `strongdm.svc.SnapshotDiscoveryConnectors`. 851 ''' 852 self.roles = svc.SnapshotRoles(client.roles) 853 ''' 854 A Role has a list of access rules which determine which Resources the members 855 of the Role have access to. An Account can be a member of multiple Roles via 856 AccountAttachments. 857 858 See `strongdm.svc.SnapshotRoles`. 859 ''' 860 self.groups = svc.SnapshotGroups(client.groups) 861 ''' 862 A Group is a set of principals. 863 864 See `strongdm.svc.SnapshotGroups`. 865 ''' 866 self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles) 867 ''' 868 A GroupRole is an assignment of a Group to a Role. 869 870 See `strongdm.svc.SnapshotGroupsRoles`. 871 ''' 872 self.identity_aliases = svc.SnapshotIdentityAliases( 873 client.identity_aliases) 874 ''' 875 IdentityAliases assign an alias to an account within an IdentitySet. 876 The alias is used as the username when connecting to a identity supported resource. 877 878 See `strongdm.svc.SnapshotIdentityAliases`. 879 ''' 880 self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets) 881 ''' 882 A IdentitySet is a named grouping of Identity Aliases for Accounts. 883 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 884 885 See `strongdm.svc.SnapshotIdentitySets`. 886 ''' 887 self.nodes = svc.SnapshotNodes(client.nodes) 888 ''' 889 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 890 There are three types of nodes: 891 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 892 2. **Gateway:** a relay that also listens for connections from StrongDM clients 893 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 894 895 See `strongdm.svc.SnapshotNodes`. 896 ''' 897 self.policies = svc.SnapshotPolicies(client.policies) 898 ''' 899 Policies are the collection of one or more statements that enforce fine-grained access 900 control for the users of an organization. 901 902 See `strongdm.svc.SnapshotPolicies`. 903 ''' 904 self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys( 905 client.proxy_cluster_keys) 906 ''' 907 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 908 The proxies within a cluster share the same key. One cluster can have 909 multiple keys in order to facilitate key rotation. 910 911 See `strongdm.svc.SnapshotProxyClusterKeys`. 912 ''' 913 self.remote_identities = svc.SnapshotRemoteIdentities( 914 client.remote_identities) 915 ''' 916 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 917 918 See `strongdm.svc.SnapshotRemoteIdentities`. 919 ''' 920 self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups( 921 client.remote_identity_groups) 922 ''' 923 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 924 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 925 926 See `strongdm.svc.SnapshotRemoteIdentityGroups`. 927 ''' 928 self.resources = svc.SnapshotResources(client.resources) 929 ''' 930 Resources are databases, servers, clusters, websites, or clouds that strongDM 931 delegates access to. 932 933 See `strongdm.svc.SnapshotResources`. 934 ''' 935 self.role_resources = svc.SnapshotRoleResources(client.role_resources) 936 ''' 937 RoleResources enumerates the resources to which roles have access. 938 The RoleResources service is read-only. 939 940 See `strongdm.svc.SnapshotRoleResources`. 941 ''' 942 self.secret_stores = svc.SnapshotSecretStores(client.secret_stores) 943 ''' 944 SecretStores are servers where resource secrets (passwords, keys) are stored. 945 946 See `strongdm.svc.SnapshotSecretStores`. 947 ''' 948 self.workflow_approvers = svc.SnapshotWorkflowApprovers( 949 client.workflow_approvers) 950 ''' 951 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 952 953 See `strongdm.svc.SnapshotWorkflowApprovers`. 954 ''' 955 self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles) 956 ''' 957 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 958 to request access to a resource via the workflow. 959 960 See `strongdm.svc.SnapshotWorkflowRoles`. 961 ''' 962 self.workflows = svc.SnapshotWorkflows(client.workflows) 963 ''' 964 Workflows are the collection of rules that define the resources to which access can be requested, 965 the users that can request that access, and the mechanism for approving those requests which can either 966 be automatic approval or a set of users authorized to approve the requests. 967 968 See `strongdm.svc.SnapshotWorkflows`. 969 '''
SnapshotClient exposes methods to query historical records at a provided timestamp.
769 def __init__(self, client): 770 self.access_requests = svc.SnapshotAccessRequests( 771 client.access_requests) 772 ''' 773 AccessRequests are requests for access to a resource that may match a Workflow. 774 775 See `strongdm.svc.SnapshotAccessRequests`. 776 ''' 777 self.account_attachments = svc.SnapshotAccountAttachments( 778 client.account_attachments) 779 ''' 780 AccountAttachments assign an account to a role. 781 782 See `strongdm.svc.SnapshotAccountAttachments`. 783 ''' 784 self.account_grants = svc.SnapshotAccountGrants(client.account_grants) 785 ''' 786 AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource. 787 788 See `strongdm.svc.SnapshotAccountGrants`. 789 ''' 790 self.account_permissions = svc.SnapshotAccountPermissions( 791 client.account_permissions) 792 ''' 793 AccountPermissions records the granular permissions accounts have, allowing them to execute 794 relevant commands via StrongDM's APIs. 795 796 See `strongdm.svc.SnapshotAccountPermissions`. 797 ''' 798 self.account_resources = svc.SnapshotAccountResources( 799 client.account_resources) 800 ''' 801 AccountResources enumerates the resources to which accounts have access. 802 The AccountResources service is read-only. 803 804 See `strongdm.svc.SnapshotAccountResources`. 805 ''' 806 self.accounts = svc.SnapshotAccounts(client.accounts) 807 ''' 808 Accounts are users that have access to strongDM. There are two types of accounts: 809 1. **Users:** humans who are authenticated through username and password or SSO. 810 2. **Service Accounts:** machines that are authenticated using a service token. 811 3. **Tokens** are access keys with permissions that can be used for authentication. 812 813 See `strongdm.svc.SnapshotAccounts`. 814 ''' 815 self.accounts_groups = svc.SnapshotAccountsGroups( 816 client.accounts_groups) 817 ''' 818 An AccountGroup links an account and a group. 819 820 See `strongdm.svc.SnapshotAccountsGroups`. 821 ''' 822 self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers( 823 client.approval_workflow_approvers) 824 ''' 825 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 826 827 See `strongdm.svc.SnapshotApprovalWorkflowApprovers`. 828 ''' 829 self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps( 830 client.approval_workflow_steps) 831 ''' 832 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 833 834 See `strongdm.svc.SnapshotApprovalWorkflowSteps`. 835 ''' 836 self.approval_workflows = svc.SnapshotApprovalWorkflows( 837 client.approval_workflows) 838 ''' 839 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 840 approvers and be approved or denied. 841 842 See `strongdm.svc.SnapshotApprovalWorkflows`. 843 ''' 844 self.discovery_connectors = svc.SnapshotDiscoveryConnectors( 845 client.discovery_connectors) 846 ''' 847 A Discovery Connector is a configuration object for performing Resource 848 Scans in remote systems such as AWS, GCP, Azure, and other systems. 849 850 See `strongdm.svc.SnapshotDiscoveryConnectors`. 851 ''' 852 self.roles = svc.SnapshotRoles(client.roles) 853 ''' 854 A Role has a list of access rules which determine which Resources the members 855 of the Role have access to. An Account can be a member of multiple Roles via 856 AccountAttachments. 857 858 See `strongdm.svc.SnapshotRoles`. 859 ''' 860 self.groups = svc.SnapshotGroups(client.groups) 861 ''' 862 A Group is a set of principals. 863 864 See `strongdm.svc.SnapshotGroups`. 865 ''' 866 self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles) 867 ''' 868 A GroupRole is an assignment of a Group to a Role. 869 870 See `strongdm.svc.SnapshotGroupsRoles`. 871 ''' 872 self.identity_aliases = svc.SnapshotIdentityAliases( 873 client.identity_aliases) 874 ''' 875 IdentityAliases assign an alias to an account within an IdentitySet. 876 The alias is used as the username when connecting to a identity supported resource. 877 878 See `strongdm.svc.SnapshotIdentityAliases`. 879 ''' 880 self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets) 881 ''' 882 A IdentitySet is a named grouping of Identity Aliases for Accounts. 883 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 884 885 See `strongdm.svc.SnapshotIdentitySets`. 886 ''' 887 self.nodes = svc.SnapshotNodes(client.nodes) 888 ''' 889 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 890 There are three types of nodes: 891 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 892 2. **Gateway:** a relay that also listens for connections from StrongDM clients 893 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 894 895 See `strongdm.svc.SnapshotNodes`. 896 ''' 897 self.policies = svc.SnapshotPolicies(client.policies) 898 ''' 899 Policies are the collection of one or more statements that enforce fine-grained access 900 control for the users of an organization. 901 902 See `strongdm.svc.SnapshotPolicies`. 903 ''' 904 self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys( 905 client.proxy_cluster_keys) 906 ''' 907 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 908 The proxies within a cluster share the same key. One cluster can have 909 multiple keys in order to facilitate key rotation. 910 911 See `strongdm.svc.SnapshotProxyClusterKeys`. 912 ''' 913 self.remote_identities = svc.SnapshotRemoteIdentities( 914 client.remote_identities) 915 ''' 916 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 917 918 See `strongdm.svc.SnapshotRemoteIdentities`. 919 ''' 920 self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups( 921 client.remote_identity_groups) 922 ''' 923 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 924 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 925 926 See `strongdm.svc.SnapshotRemoteIdentityGroups`. 927 ''' 928 self.resources = svc.SnapshotResources(client.resources) 929 ''' 930 Resources are databases, servers, clusters, websites, or clouds that strongDM 931 delegates access to. 932 933 See `strongdm.svc.SnapshotResources`. 934 ''' 935 self.role_resources = svc.SnapshotRoleResources(client.role_resources) 936 ''' 937 RoleResources enumerates the resources to which roles have access. 938 The RoleResources service is read-only. 939 940 See `strongdm.svc.SnapshotRoleResources`. 941 ''' 942 self.secret_stores = svc.SnapshotSecretStores(client.secret_stores) 943 ''' 944 SecretStores are servers where resource secrets (passwords, keys) are stored. 945 946 See `strongdm.svc.SnapshotSecretStores`. 947 ''' 948 self.workflow_approvers = svc.SnapshotWorkflowApprovers( 949 client.workflow_approvers) 950 ''' 951 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 952 953 See `strongdm.svc.SnapshotWorkflowApprovers`. 954 ''' 955 self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles) 956 ''' 957 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 958 to request access to a resource via the workflow. 959 960 See `strongdm.svc.SnapshotWorkflowRoles`. 961 ''' 962 self.workflows = svc.SnapshotWorkflows(client.workflows) 963 ''' 964 Workflows are the collection of rules that define the resources to which access can be requested, 965 the users that can request that access, and the mechanism for approving those requests which can either 966 be automatic approval or a set of users authorized to approve the requests. 967 968 See `strongdm.svc.SnapshotWorkflows`. 969 '''
AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
AccountPermissions records the granular permissions accounts have, allowing them to execute relevant commands via StrongDM's APIs.
AccountResources enumerates the resources to which accounts have access. The AccountResources service is read-only.
Accounts are users that have access to strongDM. There are two types of accounts:
- Users: humans who are authenticated through username and password or SSO.
- Service Accounts: machines that are authenticated using a service token.
- Tokens are access keys with permissions that can be used for authentication.
ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized approvers and be approved or denied.
A Discovery Connector is a configuration object for performing Resource Scans in remote systems such as AWS, GCP, Azure, and other systems.
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.
IdentityAliases assign an alias to an account within an IdentitySet. The alias is used as the username when connecting to a identity supported resource.
A IdentitySet is a named grouping of Identity Aliases for Accounts. An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
Nodes make up the StrongDM network, and allow your users to connect securely to your resources. There are three types of nodes:
- Relay: creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
- Gateway: a relay that also listens for connections from StrongDM clients
- Proxy Cluster: a cluster of workers that together mediate access from clients to resources
Policies are the collection of one or more statements that enforce fine-grained access control for the users of an organization.
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.
RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
Resources are databases, servers, clusters, websites, or clouds that strongDM delegates access to.
RoleResources enumerates the resources to which roles have access. The RoleResources service is read-only.
WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
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.