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