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