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.37.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_groups = svc.AccountsGroups(channel, self) 149 ''' 150 An AccountGroup links an account and a group. 151 152 See `strongdm.svc.AccountsGroups`. 153 ''' 154 self.accounts_groups_history = svc.AccountsGroupsHistory(channel, self) 155 ''' 156 AccountsGroupsHistory records all changes to the state of an AccountGroup. 157 158 See `strongdm.svc.AccountsGroupsHistory`. 159 ''' 160 self.accounts_history = svc.AccountsHistory(channel, self) 161 ''' 162 AccountsHistory records all changes to the state of an Account. 163 164 See `strongdm.svc.AccountsHistory`. 165 ''' 166 self.activities = svc.Activities(channel, self) 167 ''' 168 An Activity is a record of an action taken against a strongDM deployment, e.g. 169 a user creation, resource deletion, sso configuration change, etc. The Activities 170 service is read-only. 171 172 See `strongdm.svc.Activities`. 173 ''' 174 self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 175 channel, self) 176 ''' 177 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 178 179 See `strongdm.svc.ApprovalWorkflowApprovers`. 180 ''' 181 self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory( 182 channel, self) 183 ''' 184 ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover. 185 186 See `strongdm.svc.ApprovalWorkflowApproversHistory`. 187 ''' 188 self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self) 189 ''' 190 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 191 192 See `strongdm.svc.ApprovalWorkflowSteps`. 193 ''' 194 self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory( 195 channel, self) 196 ''' 197 ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep. 198 199 See `strongdm.svc.ApprovalWorkflowStepsHistory`. 200 ''' 201 self.approval_workflows = svc.ApprovalWorkflows(channel, self) 202 ''' 203 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 204 approvers and be approved or denied. 205 206 See `strongdm.svc.ApprovalWorkflows`. 207 ''' 208 self.approval_workflows_history = svc.ApprovalWorkflowsHistory( 209 channel, self) 210 ''' 211 ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow. 212 213 See `strongdm.svc.ApprovalWorkflowsHistory`. 214 ''' 215 self.control_panel = svc.ControlPanel(channel, self) 216 ''' 217 ControlPanel contains all administrative controls. 218 219 See `strongdm.svc.ControlPanel`. 220 ''' 221 self.roles = svc.Roles(channel, self) 222 ''' 223 A Role has a list of access rules which determine which Resources the members 224 of the Role have access to. An Account can be a member of multiple Roles via 225 AccountAttachments. 226 227 See `strongdm.svc.Roles`. 228 ''' 229 self.groups = svc.Groups(channel, self) 230 ''' 231 A Group is a set of principals. 232 233 See `strongdm.svc.Groups`. 234 ''' 235 self.groups_history = svc.GroupsHistory(channel, self) 236 ''' 237 GroupsHistory records all changes to the state of a Group. 238 239 See `strongdm.svc.GroupsHistory`. 240 ''' 241 self.groups_roles = svc.GroupsRoles(channel, self) 242 ''' 243 A GroupRole is an assignment of a Group to a Role. 244 245 See `strongdm.svc.GroupsRoles`. 246 ''' 247 self.groups_roles_history = svc.GroupsRolesHistory(channel, self) 248 ''' 249 GroupsRolesHistory records all changes to the state of a GroupRole. 250 251 See `strongdm.svc.GroupsRolesHistory`. 252 ''' 253 self.health_checks = svc.HealthChecks(channel, self) 254 ''' 255 HealthChecks lists the last healthcheck between each node and resource. 256 Note the unconventional capitalization here is to prevent having a collision with GRPC 257 258 See `strongdm.svc.HealthChecks`. 259 ''' 260 self.identity_aliases = svc.IdentityAliases(channel, self) 261 ''' 262 IdentityAliases assign an alias to an account within an IdentitySet. 263 The alias is used as the username when connecting to a identity supported resource. 264 265 See `strongdm.svc.IdentityAliases`. 266 ''' 267 self.identity_aliases_history = svc.IdentityAliasesHistory( 268 channel, self) 269 ''' 270 IdentityAliasesHistory records all changes to the state of a IdentityAlias. 271 272 See `strongdm.svc.IdentityAliasesHistory`. 273 ''' 274 self.identity_sets = svc.IdentitySets(channel, self) 275 ''' 276 A IdentitySet is a named grouping of Identity Aliases for Accounts. 277 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 278 279 See `strongdm.svc.IdentitySets`. 280 ''' 281 self.identity_sets_history = svc.IdentitySetsHistory(channel, self) 282 ''' 283 IdentitySetsHistory records all changes to the state of a IdentitySet. 284 285 See `strongdm.svc.IdentitySetsHistory`. 286 ''' 287 self.managed_secrets = svc.ManagedSecrets(channel, self) 288 ''' 289 ManagedSecret is a private vertical for creating, reading, updating, 290 deleting, listing and rotating the managed secrets in the secrets engines as 291 an authenticated user. 292 293 See `strongdm.svc.ManagedSecrets`. 294 ''' 295 self.nodes = svc.Nodes(channel, self) 296 ''' 297 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 298 There are three types of nodes: 299 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 300 2. **Gateway:** a relay that also listens for connections from StrongDM clients 301 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 302 303 See `strongdm.svc.Nodes`. 304 ''' 305 self.nodes_history = svc.NodesHistory(channel, self) 306 ''' 307 NodesHistory records all changes to the state of a Node. 308 309 See `strongdm.svc.NodesHistory`. 310 ''' 311 self.organization_history = svc.OrganizationHistory(channel, self) 312 ''' 313 OrganizationHistory records all changes to the state of an Organization. 314 315 See `strongdm.svc.OrganizationHistory`. 316 ''' 317 self.peering_group_nodes = svc.PeeringGroupNodes(channel, self) 318 ''' 319 PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group. 320 321 See `strongdm.svc.PeeringGroupNodes`. 322 ''' 323 self.peering_group_peers = svc.PeeringGroupPeers(channel, self) 324 ''' 325 PeeringGroupPeers provides the building blocks necessary to link two peering groups. 326 327 See `strongdm.svc.PeeringGroupPeers`. 328 ''' 329 self.peering_group_resources = svc.PeeringGroupResources(channel, self) 330 ''' 331 PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group. 332 333 See `strongdm.svc.PeeringGroupResources`. 334 ''' 335 self.peering_groups = svc.PeeringGroups(channel, self) 336 ''' 337 PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing. 338 339 See `strongdm.svc.PeeringGroups`. 340 ''' 341 self.policies = svc.Policies(channel, self) 342 ''' 343 Policies are the collection of one or more statements that enforce fine-grained access 344 control for the users of an organization. 345 346 See `strongdm.svc.Policies`. 347 ''' 348 self.policies_history = svc.PoliciesHistory(channel, self) 349 ''' 350 PoliciesHistory records all changes to the state of a Policy. 351 352 See `strongdm.svc.PoliciesHistory`. 353 ''' 354 self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self) 355 ''' 356 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 357 The proxies within a cluster share the same key. One cluster can have 358 multiple keys in order to facilitate key rotation. 359 360 See `strongdm.svc.ProxyClusterKeys`. 361 ''' 362 self.queries = svc.Queries(channel, self) 363 ''' 364 A Query is a record of a single client request to a resource, such as a SQL query. 365 Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries. 366 The Queries service is read-only. 367 368 See `strongdm.svc.Queries`. 369 ''' 370 self.remote_identities = svc.RemoteIdentities(channel, self) 371 ''' 372 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 373 374 See `strongdm.svc.RemoteIdentities`. 375 ''' 376 self.remote_identities_history = svc.RemoteIdentitiesHistory( 377 channel, self) 378 ''' 379 RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity. 380 381 See `strongdm.svc.RemoteIdentitiesHistory`. 382 ''' 383 self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self) 384 ''' 385 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 386 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 387 388 See `strongdm.svc.RemoteIdentityGroups`. 389 ''' 390 self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory( 391 channel, self) 392 ''' 393 RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup. 394 395 See `strongdm.svc.RemoteIdentityGroupsHistory`. 396 ''' 397 self.replays = svc.Replays(channel, self) 398 ''' 399 A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session 400 (otherwise referred to as a query). The Replays service is read-only. 401 402 See `strongdm.svc.Replays`. 403 ''' 404 self.resources = svc.Resources(channel, self) 405 ''' 406 Resources are databases, servers, clusters, websites, or clouds that strongDM 407 delegates access to. 408 409 See `strongdm.svc.Resources`. 410 ''' 411 self.resources_history = svc.ResourcesHistory(channel, self) 412 ''' 413 ResourcesHistory records all changes to the state of a Resource. 414 415 See `strongdm.svc.ResourcesHistory`. 416 ''' 417 self.role_resources = svc.RoleResources(channel, self) 418 ''' 419 RoleResources enumerates the resources to which roles have access. 420 The RoleResources service is read-only. 421 422 See `strongdm.svc.RoleResources`. 423 ''' 424 self.role_resources_history = svc.RoleResourcesHistory(channel, self) 425 ''' 426 RoleResourcesHistory records all changes to the state of a RoleResource. 427 428 See `strongdm.svc.RoleResourcesHistory`. 429 ''' 430 self.roles_history = svc.RolesHistory(channel, self) 431 ''' 432 RolesHistory records all changes to the state of a Role. 433 434 See `strongdm.svc.RolesHistory`. 435 ''' 436 self.secret_stores = svc.SecretStores(channel, self) 437 ''' 438 SecretStores are servers where resource secrets (passwords, keys) are stored. 439 440 See `strongdm.svc.SecretStores`. 441 ''' 442 self.secret_engines = svc.SecretEngines(channel, self) 443 ''' 444 445 446 See `strongdm.svc.SecretEngines`. 447 ''' 448 self.secret_store_healths = svc.SecretStoreHealths(channel, self) 449 ''' 450 SecretStoreHealths exposes health states for secret stores. 451 452 See `strongdm.svc.SecretStoreHealths`. 453 ''' 454 self.secret_stores_history = svc.SecretStoresHistory(channel, self) 455 ''' 456 SecretStoresHistory records all changes to the state of a SecretStore. 457 458 See `strongdm.svc.SecretStoresHistory`. 459 ''' 460 self.workflow_approvers = svc.WorkflowApprovers(channel, self) 461 ''' 462 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 463 464 See `strongdm.svc.WorkflowApprovers`. 465 ''' 466 self.workflow_approvers_history = svc.WorkflowApproversHistory( 467 channel, self) 468 ''' 469 WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover. 470 471 See `strongdm.svc.WorkflowApproversHistory`. 472 ''' 473 self.workflow_roles = svc.WorkflowRoles(channel, self) 474 ''' 475 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 476 to request access to a resource via the workflow. 477 478 See `strongdm.svc.WorkflowRoles`. 479 ''' 480 self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self) 481 ''' 482 WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole 483 484 See `strongdm.svc.WorkflowRolesHistory`. 485 ''' 486 self.workflows = svc.Workflows(channel, self) 487 ''' 488 Workflows are the collection of rules that define the resources to which access can be requested, 489 the users that can request that access, and the mechanism for approving those requests which can either 490 be automatic approval or a set of users authorized to approve the requests. 491 492 See `strongdm.svc.Workflows`. 493 ''' 494 self.workflows_history = svc.WorkflowsHistory(channel, self) 495 ''' 496 WorkflowsHistory provides records of all changes to the state of a Workflow. 497 498 See `strongdm.svc.WorkflowsHistory`. 499 ''' 500 501 def close(self): 502 '''Closes this Client and releases all resources held by it. 503 504 Closing the Client will immediately terminate all RPCs active with the 505 Client and it is not valid to invoke new RPCs with the Client. 506 507 This method is idempotent. 508 ''' 509 self.channel.close() 510 511 def get_metadata(self, method_name, req): 512 return [ 513 ('x-sdm-authentication', self.api_access_key), 514 ('x-sdm-signature', self.sign(method_name, 515 req.SerializeToString())), 516 ('x-sdm-api-version', API_VERSION), 517 ('x-sdm-user-agent', USER_AGENT), 518 ] 519 520 def sign(self, method_name, request_bytes): 521 def hmac_digest(key, msg_byte_string): 522 return hmac.new(key, msg=msg_byte_string, 523 digestmod=hashlib.sha256).digest() 524 525 current_utc_date = datetime.datetime.now( 526 datetime.timezone.utc).strftime('%Y-%m-%d') 527 signing_key = hmac_digest(self.api_secret, current_utc_date.encode()) 528 signing_key = hmac_digest(signing_key, b'sdm_api_v1') 529 530 hash = hashlib.sha256() 531 532 hash.update(method_name.encode()) 533 hash.update(b'\n') 534 hash.update(request_bytes) 535 536 return base64.b64encode(hmac_digest(signing_key, hash.digest())) 537 538 def exponentialBackoff(self, retries, deadline=None): 539 def applyDeadline(delay, deadline): 540 if deadline is None: 541 return delay 542 remaining = deadline - time.time() 543 if remaining < 0: 544 return 0 545 return min(delay, remaining) 546 547 if retries == 0: 548 return applyDeadline(self.base_retry_delay, deadline) 549 550 backoff, max_delay = self.base_retry_delay, self.max_retry_delay 551 while backoff < max_delay and retries > 0: 552 backoff *= self.retry_factor 553 retries -= 1 554 555 if backoff > max_delay: 556 backoff = max_delay 557 558 # Randomize backoff delays so that if a cluster of requests start at 559 # the same time, they won't operate in lockstep. 560 backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1) 561 if backoff < 0: 562 return 0 563 564 return applyDeadline(backoff, deadline) 565 566 def shouldRetry(self, retries, err, deadline=None): 567 # Check if we've passed the deadline 568 if deadline is not None and time.time() >= deadline: 569 return False 570 571 if not isinstance(err, grpc.RpcError): 572 return False 573 574 if self.retry_rate_limit_errors and err.code( 575 ) == grpc.StatusCode.RESOURCE_EXHAUSTED: 576 return True 577 578 return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL 579 or err.code() == grpc.StatusCode.UNAVAILABLE) 580 581 def snapshot_at(self, snapshot_datetime): 582 ''' 583 Constructs a read-only client that will provide historical data from the provided timestamp. 584 585 See `SnapshotClient`. 586 ''' 587 client = copy.copy(self) 588 client.snapshot_datetime = snapshot_datetime 589 client.access_requests = svc.AccessRequests(client.channel, client) 590 client.account_attachments = svc.AccountAttachments( 591 client.channel, client) 592 client.account_grants = svc.AccountGrants(client.channel, client) 593 client.account_permissions = svc.AccountPermissions( 594 client.channel, client) 595 client.account_resources = svc.AccountResources(client.channel, client) 596 client.accounts = svc.Accounts(client.channel, client) 597 client.accounts_groups = svc.AccountsGroups(client.channel, client) 598 client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 599 client.channel, client) 600 client.approval_workflow_steps = svc.ApprovalWorkflowSteps( 601 client.channel, client) 602 client.approval_workflows = svc.ApprovalWorkflows( 603 client.channel, client) 604 client.roles = svc.Roles(client.channel, client) 605 client.groups = svc.Groups(client.channel, client) 606 client.groups_roles = svc.GroupsRoles(client.channel, client) 607 client.identity_aliases = svc.IdentityAliases(client.channel, client) 608 client.identity_sets = svc.IdentitySets(client.channel, client) 609 client.nodes = svc.Nodes(client.channel, client) 610 client.policies = svc.Policies(client.channel, client) 611 client.proxy_cluster_keys = svc.ProxyClusterKeys( 612 client.channel, client) 613 client.remote_identities = svc.RemoteIdentities(client.channel, client) 614 client.remote_identity_groups = svc.RemoteIdentityGroups( 615 client.channel, client) 616 client.resources = svc.Resources(client.channel, client) 617 client.role_resources = svc.RoleResources(client.channel, client) 618 client.secret_stores = svc.SecretStores(client.channel, client) 619 client.workflow_approvers = svc.WorkflowApprovers( 620 client.channel, client) 621 client.workflow_roles = svc.WorkflowRoles(client.channel, client) 622 client.workflows = svc.Workflows(client.channel, client) 623 return SnapshotClient(client) 624 625 626class SnapshotClient: 627 '''SnapshotClient exposes methods to query historical records at a provided timestamp.''' 628 def __init__(self, client): 629 self.access_requests = svc.SnapshotAccessRequests( 630 client.access_requests) 631 ''' 632 AccessRequests are requests for access to a resource that may match a Workflow. 633 634 See `strongdm.svc.SnapshotAccessRequests`. 635 ''' 636 self.account_attachments = svc.SnapshotAccountAttachments( 637 client.account_attachments) 638 ''' 639 AccountAttachments assign an account to a role. 640 641 See `strongdm.svc.SnapshotAccountAttachments`. 642 ''' 643 self.account_grants = svc.SnapshotAccountGrants(client.account_grants) 644 ''' 645 AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource. 646 647 See `strongdm.svc.SnapshotAccountGrants`. 648 ''' 649 self.account_permissions = svc.SnapshotAccountPermissions( 650 client.account_permissions) 651 ''' 652 AccountPermissions records the granular permissions accounts have, allowing them to execute 653 relevant commands via StrongDM's APIs. 654 655 See `strongdm.svc.SnapshotAccountPermissions`. 656 ''' 657 self.account_resources = svc.SnapshotAccountResources( 658 client.account_resources) 659 ''' 660 AccountResources enumerates the resources to which accounts have access. 661 The AccountResources service is read-only. 662 663 See `strongdm.svc.SnapshotAccountResources`. 664 ''' 665 self.accounts = svc.SnapshotAccounts(client.accounts) 666 ''' 667 Accounts are users that have access to strongDM. There are two types of accounts: 668 1. **Users:** humans who are authenticated through username and password or SSO. 669 2. **Service Accounts:** machines that are authenticated using a service token. 670 3. **Tokens** are access keys with permissions that can be used for authentication. 671 672 See `strongdm.svc.SnapshotAccounts`. 673 ''' 674 self.accounts_groups = svc.SnapshotAccountsGroups( 675 client.accounts_groups) 676 ''' 677 An AccountGroup links an account and a group. 678 679 See `strongdm.svc.SnapshotAccountsGroups`. 680 ''' 681 self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers( 682 client.approval_workflow_approvers) 683 ''' 684 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 685 686 See `strongdm.svc.SnapshotApprovalWorkflowApprovers`. 687 ''' 688 self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps( 689 client.approval_workflow_steps) 690 ''' 691 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 692 693 See `strongdm.svc.SnapshotApprovalWorkflowSteps`. 694 ''' 695 self.approval_workflows = svc.SnapshotApprovalWorkflows( 696 client.approval_workflows) 697 ''' 698 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 699 approvers and be approved or denied. 700 701 See `strongdm.svc.SnapshotApprovalWorkflows`. 702 ''' 703 self.roles = svc.SnapshotRoles(client.roles) 704 ''' 705 A Role has a list of access rules which determine which Resources the members 706 of the Role have access to. An Account can be a member of multiple Roles via 707 AccountAttachments. 708 709 See `strongdm.svc.SnapshotRoles`. 710 ''' 711 self.groups = svc.SnapshotGroups(client.groups) 712 ''' 713 A Group is a set of principals. 714 715 See `strongdm.svc.SnapshotGroups`. 716 ''' 717 self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles) 718 ''' 719 A GroupRole is an assignment of a Group to a Role. 720 721 See `strongdm.svc.SnapshotGroupsRoles`. 722 ''' 723 self.identity_aliases = svc.SnapshotIdentityAliases( 724 client.identity_aliases) 725 ''' 726 IdentityAliases assign an alias to an account within an IdentitySet. 727 The alias is used as the username when connecting to a identity supported resource. 728 729 See `strongdm.svc.SnapshotIdentityAliases`. 730 ''' 731 self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets) 732 ''' 733 A IdentitySet is a named grouping of Identity Aliases for Accounts. 734 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 735 736 See `strongdm.svc.SnapshotIdentitySets`. 737 ''' 738 self.nodes = svc.SnapshotNodes(client.nodes) 739 ''' 740 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 741 There are three types of nodes: 742 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 743 2. **Gateway:** a relay that also listens for connections from StrongDM clients 744 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 745 746 See `strongdm.svc.SnapshotNodes`. 747 ''' 748 self.policies = svc.SnapshotPolicies(client.policies) 749 ''' 750 Policies are the collection of one or more statements that enforce fine-grained access 751 control for the users of an organization. 752 753 See `strongdm.svc.SnapshotPolicies`. 754 ''' 755 self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys( 756 client.proxy_cluster_keys) 757 ''' 758 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 759 The proxies within a cluster share the same key. One cluster can have 760 multiple keys in order to facilitate key rotation. 761 762 See `strongdm.svc.SnapshotProxyClusterKeys`. 763 ''' 764 self.remote_identities = svc.SnapshotRemoteIdentities( 765 client.remote_identities) 766 ''' 767 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 768 769 See `strongdm.svc.SnapshotRemoteIdentities`. 770 ''' 771 self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups( 772 client.remote_identity_groups) 773 ''' 774 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 775 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 776 777 See `strongdm.svc.SnapshotRemoteIdentityGroups`. 778 ''' 779 self.resources = svc.SnapshotResources(client.resources) 780 ''' 781 Resources are databases, servers, clusters, websites, or clouds that strongDM 782 delegates access to. 783 784 See `strongdm.svc.SnapshotResources`. 785 ''' 786 self.role_resources = svc.SnapshotRoleResources(client.role_resources) 787 ''' 788 RoleResources enumerates the resources to which roles have access. 789 The RoleResources service is read-only. 790 791 See `strongdm.svc.SnapshotRoleResources`. 792 ''' 793 self.secret_stores = svc.SnapshotSecretStores(client.secret_stores) 794 ''' 795 SecretStores are servers where resource secrets (passwords, keys) are stored. 796 797 See `strongdm.svc.SnapshotSecretStores`. 798 ''' 799 self.workflow_approvers = svc.SnapshotWorkflowApprovers( 800 client.workflow_approvers) 801 ''' 802 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 803 804 See `strongdm.svc.SnapshotWorkflowApprovers`. 805 ''' 806 self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles) 807 ''' 808 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 809 to request access to a resource via the workflow. 810 811 See `strongdm.svc.SnapshotWorkflowRoles`. 812 ''' 813 self.workflows = svc.SnapshotWorkflows(client.workflows) 814 ''' 815 Workflows are the collection of rules that define the resources to which access can be requested, 816 the users that can request that access, and the mechanism for approving those requests which can either 817 be automatic approval or a set of users authorized to approve the requests. 818 819 See `strongdm.svc.SnapshotWorkflows`. 820 '''
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_groups = svc.AccountsGroups(channel, self) 150 ''' 151 An AccountGroup links an account and a group. 152 153 See `strongdm.svc.AccountsGroups`. 154 ''' 155 self.accounts_groups_history = svc.AccountsGroupsHistory(channel, self) 156 ''' 157 AccountsGroupsHistory records all changes to the state of an AccountGroup. 158 159 See `strongdm.svc.AccountsGroupsHistory`. 160 ''' 161 self.accounts_history = svc.AccountsHistory(channel, self) 162 ''' 163 AccountsHistory records all changes to the state of an Account. 164 165 See `strongdm.svc.AccountsHistory`. 166 ''' 167 self.activities = svc.Activities(channel, self) 168 ''' 169 An Activity is a record of an action taken against a strongDM deployment, e.g. 170 a user creation, resource deletion, sso configuration change, etc. The Activities 171 service is read-only. 172 173 See `strongdm.svc.Activities`. 174 ''' 175 self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 176 channel, self) 177 ''' 178 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 179 180 See `strongdm.svc.ApprovalWorkflowApprovers`. 181 ''' 182 self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory( 183 channel, self) 184 ''' 185 ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover. 186 187 See `strongdm.svc.ApprovalWorkflowApproversHistory`. 188 ''' 189 self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self) 190 ''' 191 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 192 193 See `strongdm.svc.ApprovalWorkflowSteps`. 194 ''' 195 self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory( 196 channel, self) 197 ''' 198 ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep. 199 200 See `strongdm.svc.ApprovalWorkflowStepsHistory`. 201 ''' 202 self.approval_workflows = svc.ApprovalWorkflows(channel, self) 203 ''' 204 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 205 approvers and be approved or denied. 206 207 See `strongdm.svc.ApprovalWorkflows`. 208 ''' 209 self.approval_workflows_history = svc.ApprovalWorkflowsHistory( 210 channel, self) 211 ''' 212 ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow. 213 214 See `strongdm.svc.ApprovalWorkflowsHistory`. 215 ''' 216 self.control_panel = svc.ControlPanel(channel, self) 217 ''' 218 ControlPanel contains all administrative controls. 219 220 See `strongdm.svc.ControlPanel`. 221 ''' 222 self.roles = svc.Roles(channel, self) 223 ''' 224 A Role has a list of access rules which determine which Resources the members 225 of the Role have access to. An Account can be a member of multiple Roles via 226 AccountAttachments. 227 228 See `strongdm.svc.Roles`. 229 ''' 230 self.groups = svc.Groups(channel, self) 231 ''' 232 A Group is a set of principals. 233 234 See `strongdm.svc.Groups`. 235 ''' 236 self.groups_history = svc.GroupsHistory(channel, self) 237 ''' 238 GroupsHistory records all changes to the state of a Group. 239 240 See `strongdm.svc.GroupsHistory`. 241 ''' 242 self.groups_roles = svc.GroupsRoles(channel, self) 243 ''' 244 A GroupRole is an assignment of a Group to a Role. 245 246 See `strongdm.svc.GroupsRoles`. 247 ''' 248 self.groups_roles_history = svc.GroupsRolesHistory(channel, self) 249 ''' 250 GroupsRolesHistory records all changes to the state of a GroupRole. 251 252 See `strongdm.svc.GroupsRolesHistory`. 253 ''' 254 self.health_checks = svc.HealthChecks(channel, self) 255 ''' 256 HealthChecks lists the last healthcheck between each node and resource. 257 Note the unconventional capitalization here is to prevent having a collision with GRPC 258 259 See `strongdm.svc.HealthChecks`. 260 ''' 261 self.identity_aliases = svc.IdentityAliases(channel, self) 262 ''' 263 IdentityAliases assign an alias to an account within an IdentitySet. 264 The alias is used as the username when connecting to a identity supported resource. 265 266 See `strongdm.svc.IdentityAliases`. 267 ''' 268 self.identity_aliases_history = svc.IdentityAliasesHistory( 269 channel, self) 270 ''' 271 IdentityAliasesHistory records all changes to the state of a IdentityAlias. 272 273 See `strongdm.svc.IdentityAliasesHistory`. 274 ''' 275 self.identity_sets = svc.IdentitySets(channel, self) 276 ''' 277 A IdentitySet is a named grouping of Identity Aliases for Accounts. 278 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 279 280 See `strongdm.svc.IdentitySets`. 281 ''' 282 self.identity_sets_history = svc.IdentitySetsHistory(channel, self) 283 ''' 284 IdentitySetsHistory records all changes to the state of a IdentitySet. 285 286 See `strongdm.svc.IdentitySetsHistory`. 287 ''' 288 self.managed_secrets = svc.ManagedSecrets(channel, self) 289 ''' 290 ManagedSecret is a private vertical for creating, reading, updating, 291 deleting, listing and rotating the managed secrets in the secrets engines as 292 an authenticated user. 293 294 See `strongdm.svc.ManagedSecrets`. 295 ''' 296 self.nodes = svc.Nodes(channel, self) 297 ''' 298 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 299 There are three types of nodes: 300 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 301 2. **Gateway:** a relay that also listens for connections from StrongDM clients 302 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 303 304 See `strongdm.svc.Nodes`. 305 ''' 306 self.nodes_history = svc.NodesHistory(channel, self) 307 ''' 308 NodesHistory records all changes to the state of a Node. 309 310 See `strongdm.svc.NodesHistory`. 311 ''' 312 self.organization_history = svc.OrganizationHistory(channel, self) 313 ''' 314 OrganizationHistory records all changes to the state of an Organization. 315 316 See `strongdm.svc.OrganizationHistory`. 317 ''' 318 self.peering_group_nodes = svc.PeeringGroupNodes(channel, self) 319 ''' 320 PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group. 321 322 See `strongdm.svc.PeeringGroupNodes`. 323 ''' 324 self.peering_group_peers = svc.PeeringGroupPeers(channel, self) 325 ''' 326 PeeringGroupPeers provides the building blocks necessary to link two peering groups. 327 328 See `strongdm.svc.PeeringGroupPeers`. 329 ''' 330 self.peering_group_resources = svc.PeeringGroupResources(channel, self) 331 ''' 332 PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group. 333 334 See `strongdm.svc.PeeringGroupResources`. 335 ''' 336 self.peering_groups = svc.PeeringGroups(channel, self) 337 ''' 338 PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing. 339 340 See `strongdm.svc.PeeringGroups`. 341 ''' 342 self.policies = svc.Policies(channel, self) 343 ''' 344 Policies are the collection of one or more statements that enforce fine-grained access 345 control for the users of an organization. 346 347 See `strongdm.svc.Policies`. 348 ''' 349 self.policies_history = svc.PoliciesHistory(channel, self) 350 ''' 351 PoliciesHistory records all changes to the state of a Policy. 352 353 See `strongdm.svc.PoliciesHistory`. 354 ''' 355 self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self) 356 ''' 357 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 358 The proxies within a cluster share the same key. One cluster can have 359 multiple keys in order to facilitate key rotation. 360 361 See `strongdm.svc.ProxyClusterKeys`. 362 ''' 363 self.queries = svc.Queries(channel, self) 364 ''' 365 A Query is a record of a single client request to a resource, such as a SQL query. 366 Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries. 367 The Queries service is read-only. 368 369 See `strongdm.svc.Queries`. 370 ''' 371 self.remote_identities = svc.RemoteIdentities(channel, self) 372 ''' 373 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 374 375 See `strongdm.svc.RemoteIdentities`. 376 ''' 377 self.remote_identities_history = svc.RemoteIdentitiesHistory( 378 channel, self) 379 ''' 380 RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity. 381 382 See `strongdm.svc.RemoteIdentitiesHistory`. 383 ''' 384 self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self) 385 ''' 386 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 387 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 388 389 See `strongdm.svc.RemoteIdentityGroups`. 390 ''' 391 self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory( 392 channel, self) 393 ''' 394 RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup. 395 396 See `strongdm.svc.RemoteIdentityGroupsHistory`. 397 ''' 398 self.replays = svc.Replays(channel, self) 399 ''' 400 A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session 401 (otherwise referred to as a query). The Replays service is read-only. 402 403 See `strongdm.svc.Replays`. 404 ''' 405 self.resources = svc.Resources(channel, self) 406 ''' 407 Resources are databases, servers, clusters, websites, or clouds that strongDM 408 delegates access to. 409 410 See `strongdm.svc.Resources`. 411 ''' 412 self.resources_history = svc.ResourcesHistory(channel, self) 413 ''' 414 ResourcesHistory records all changes to the state of a Resource. 415 416 See `strongdm.svc.ResourcesHistory`. 417 ''' 418 self.role_resources = svc.RoleResources(channel, self) 419 ''' 420 RoleResources enumerates the resources to which roles have access. 421 The RoleResources service is read-only. 422 423 See `strongdm.svc.RoleResources`. 424 ''' 425 self.role_resources_history = svc.RoleResourcesHistory(channel, self) 426 ''' 427 RoleResourcesHistory records all changes to the state of a RoleResource. 428 429 See `strongdm.svc.RoleResourcesHistory`. 430 ''' 431 self.roles_history = svc.RolesHistory(channel, self) 432 ''' 433 RolesHistory records all changes to the state of a Role. 434 435 See `strongdm.svc.RolesHistory`. 436 ''' 437 self.secret_stores = svc.SecretStores(channel, self) 438 ''' 439 SecretStores are servers where resource secrets (passwords, keys) are stored. 440 441 See `strongdm.svc.SecretStores`. 442 ''' 443 self.secret_engines = svc.SecretEngines(channel, self) 444 ''' 445 446 447 See `strongdm.svc.SecretEngines`. 448 ''' 449 self.secret_store_healths = svc.SecretStoreHealths(channel, self) 450 ''' 451 SecretStoreHealths exposes health states for secret stores. 452 453 See `strongdm.svc.SecretStoreHealths`. 454 ''' 455 self.secret_stores_history = svc.SecretStoresHistory(channel, self) 456 ''' 457 SecretStoresHistory records all changes to the state of a SecretStore. 458 459 See `strongdm.svc.SecretStoresHistory`. 460 ''' 461 self.workflow_approvers = svc.WorkflowApprovers(channel, self) 462 ''' 463 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 464 465 See `strongdm.svc.WorkflowApprovers`. 466 ''' 467 self.workflow_approvers_history = svc.WorkflowApproversHistory( 468 channel, self) 469 ''' 470 WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover. 471 472 See `strongdm.svc.WorkflowApproversHistory`. 473 ''' 474 self.workflow_roles = svc.WorkflowRoles(channel, self) 475 ''' 476 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 477 to request access to a resource via the workflow. 478 479 See `strongdm.svc.WorkflowRoles`. 480 ''' 481 self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self) 482 ''' 483 WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole 484 485 See `strongdm.svc.WorkflowRolesHistory`. 486 ''' 487 self.workflows = svc.Workflows(channel, self) 488 ''' 489 Workflows are the collection of rules that define the resources to which access can be requested, 490 the users that can request that access, and the mechanism for approving those requests which can either 491 be automatic approval or a set of users authorized to approve the requests. 492 493 See `strongdm.svc.Workflows`. 494 ''' 495 self.workflows_history = svc.WorkflowsHistory(channel, self) 496 ''' 497 WorkflowsHistory provides records of all changes to the state of a Workflow. 498 499 See `strongdm.svc.WorkflowsHistory`. 500 ''' 501 502 def close(self): 503 '''Closes this Client and releases all resources held by it. 504 505 Closing the Client will immediately terminate all RPCs active with the 506 Client and it is not valid to invoke new RPCs with the Client. 507 508 This method is idempotent. 509 ''' 510 self.channel.close() 511 512 def get_metadata(self, method_name, req): 513 return [ 514 ('x-sdm-authentication', self.api_access_key), 515 ('x-sdm-signature', self.sign(method_name, 516 req.SerializeToString())), 517 ('x-sdm-api-version', API_VERSION), 518 ('x-sdm-user-agent', USER_AGENT), 519 ] 520 521 def sign(self, method_name, request_bytes): 522 def hmac_digest(key, msg_byte_string): 523 return hmac.new(key, msg=msg_byte_string, 524 digestmod=hashlib.sha256).digest() 525 526 current_utc_date = datetime.datetime.now( 527 datetime.timezone.utc).strftime('%Y-%m-%d') 528 signing_key = hmac_digest(self.api_secret, current_utc_date.encode()) 529 signing_key = hmac_digest(signing_key, b'sdm_api_v1') 530 531 hash = hashlib.sha256() 532 533 hash.update(method_name.encode()) 534 hash.update(b'\n') 535 hash.update(request_bytes) 536 537 return base64.b64encode(hmac_digest(signing_key, hash.digest())) 538 539 def exponentialBackoff(self, retries, deadline=None): 540 def applyDeadline(delay, deadline): 541 if deadline is None: 542 return delay 543 remaining = deadline - time.time() 544 if remaining < 0: 545 return 0 546 return min(delay, remaining) 547 548 if retries == 0: 549 return applyDeadline(self.base_retry_delay, deadline) 550 551 backoff, max_delay = self.base_retry_delay, self.max_retry_delay 552 while backoff < max_delay and retries > 0: 553 backoff *= self.retry_factor 554 retries -= 1 555 556 if backoff > max_delay: 557 backoff = max_delay 558 559 # Randomize backoff delays so that if a cluster of requests start at 560 # the same time, they won't operate in lockstep. 561 backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1) 562 if backoff < 0: 563 return 0 564 565 return applyDeadline(backoff, deadline) 566 567 def shouldRetry(self, retries, err, deadline=None): 568 # Check if we've passed the deadline 569 if deadline is not None and time.time() >= deadline: 570 return False 571 572 if not isinstance(err, grpc.RpcError): 573 return False 574 575 if self.retry_rate_limit_errors and err.code( 576 ) == grpc.StatusCode.RESOURCE_EXHAUSTED: 577 return True 578 579 return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL 580 or err.code() == grpc.StatusCode.UNAVAILABLE) 581 582 def snapshot_at(self, snapshot_datetime): 583 ''' 584 Constructs a read-only client that will provide historical data from the provided timestamp. 585 586 See `SnapshotClient`. 587 ''' 588 client = copy.copy(self) 589 client.snapshot_datetime = snapshot_datetime 590 client.access_requests = svc.AccessRequests(client.channel, client) 591 client.account_attachments = svc.AccountAttachments( 592 client.channel, client) 593 client.account_grants = svc.AccountGrants(client.channel, client) 594 client.account_permissions = svc.AccountPermissions( 595 client.channel, client) 596 client.account_resources = svc.AccountResources(client.channel, client) 597 client.accounts = svc.Accounts(client.channel, client) 598 client.accounts_groups = svc.AccountsGroups(client.channel, client) 599 client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 600 client.channel, client) 601 client.approval_workflow_steps = svc.ApprovalWorkflowSteps( 602 client.channel, client) 603 client.approval_workflows = svc.ApprovalWorkflows( 604 client.channel, client) 605 client.roles = svc.Roles(client.channel, client) 606 client.groups = svc.Groups(client.channel, client) 607 client.groups_roles = svc.GroupsRoles(client.channel, client) 608 client.identity_aliases = svc.IdentityAliases(client.channel, client) 609 client.identity_sets = svc.IdentitySets(client.channel, client) 610 client.nodes = svc.Nodes(client.channel, client) 611 client.policies = svc.Policies(client.channel, client) 612 client.proxy_cluster_keys = svc.ProxyClusterKeys( 613 client.channel, client) 614 client.remote_identities = svc.RemoteIdentities(client.channel, client) 615 client.remote_identity_groups = svc.RemoteIdentityGroups( 616 client.channel, client) 617 client.resources = svc.Resources(client.channel, client) 618 client.role_resources = svc.RoleResources(client.channel, client) 619 client.secret_stores = svc.SecretStores(client.channel, client) 620 client.workflow_approvers = svc.WorkflowApprovers( 621 client.channel, client) 622 client.workflow_roles = svc.WorkflowRoles(client.channel, client) 623 client.workflows = svc.Workflows(client.channel, client) 624 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_groups = svc.AccountsGroups(channel, self) 150 ''' 151 An AccountGroup links an account and a group. 152 153 See `strongdm.svc.AccountsGroups`. 154 ''' 155 self.accounts_groups_history = svc.AccountsGroupsHistory(channel, self) 156 ''' 157 AccountsGroupsHistory records all changes to the state of an AccountGroup. 158 159 See `strongdm.svc.AccountsGroupsHistory`. 160 ''' 161 self.accounts_history = svc.AccountsHistory(channel, self) 162 ''' 163 AccountsHistory records all changes to the state of an Account. 164 165 See `strongdm.svc.AccountsHistory`. 166 ''' 167 self.activities = svc.Activities(channel, self) 168 ''' 169 An Activity is a record of an action taken against a strongDM deployment, e.g. 170 a user creation, resource deletion, sso configuration change, etc. The Activities 171 service is read-only. 172 173 See `strongdm.svc.Activities`. 174 ''' 175 self.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 176 channel, self) 177 ''' 178 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 179 180 See `strongdm.svc.ApprovalWorkflowApprovers`. 181 ''' 182 self.approval_workflow_approvers_history = svc.ApprovalWorkflowApproversHistory( 183 channel, self) 184 ''' 185 ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover. 186 187 See `strongdm.svc.ApprovalWorkflowApproversHistory`. 188 ''' 189 self.approval_workflow_steps = svc.ApprovalWorkflowSteps(channel, self) 190 ''' 191 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 192 193 See `strongdm.svc.ApprovalWorkflowSteps`. 194 ''' 195 self.approval_workflow_steps_history = svc.ApprovalWorkflowStepsHistory( 196 channel, self) 197 ''' 198 ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep. 199 200 See `strongdm.svc.ApprovalWorkflowStepsHistory`. 201 ''' 202 self.approval_workflows = svc.ApprovalWorkflows(channel, self) 203 ''' 204 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 205 approvers and be approved or denied. 206 207 See `strongdm.svc.ApprovalWorkflows`. 208 ''' 209 self.approval_workflows_history = svc.ApprovalWorkflowsHistory( 210 channel, self) 211 ''' 212 ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow. 213 214 See `strongdm.svc.ApprovalWorkflowsHistory`. 215 ''' 216 self.control_panel = svc.ControlPanel(channel, self) 217 ''' 218 ControlPanel contains all administrative controls. 219 220 See `strongdm.svc.ControlPanel`. 221 ''' 222 self.roles = svc.Roles(channel, self) 223 ''' 224 A Role has a list of access rules which determine which Resources the members 225 of the Role have access to. An Account can be a member of multiple Roles via 226 AccountAttachments. 227 228 See `strongdm.svc.Roles`. 229 ''' 230 self.groups = svc.Groups(channel, self) 231 ''' 232 A Group is a set of principals. 233 234 See `strongdm.svc.Groups`. 235 ''' 236 self.groups_history = svc.GroupsHistory(channel, self) 237 ''' 238 GroupsHistory records all changes to the state of a Group. 239 240 See `strongdm.svc.GroupsHistory`. 241 ''' 242 self.groups_roles = svc.GroupsRoles(channel, self) 243 ''' 244 A GroupRole is an assignment of a Group to a Role. 245 246 See `strongdm.svc.GroupsRoles`. 247 ''' 248 self.groups_roles_history = svc.GroupsRolesHistory(channel, self) 249 ''' 250 GroupsRolesHistory records all changes to the state of a GroupRole. 251 252 See `strongdm.svc.GroupsRolesHistory`. 253 ''' 254 self.health_checks = svc.HealthChecks(channel, self) 255 ''' 256 HealthChecks lists the last healthcheck between each node and resource. 257 Note the unconventional capitalization here is to prevent having a collision with GRPC 258 259 See `strongdm.svc.HealthChecks`. 260 ''' 261 self.identity_aliases = svc.IdentityAliases(channel, self) 262 ''' 263 IdentityAliases assign an alias to an account within an IdentitySet. 264 The alias is used as the username when connecting to a identity supported resource. 265 266 See `strongdm.svc.IdentityAliases`. 267 ''' 268 self.identity_aliases_history = svc.IdentityAliasesHistory( 269 channel, self) 270 ''' 271 IdentityAliasesHistory records all changes to the state of a IdentityAlias. 272 273 See `strongdm.svc.IdentityAliasesHistory`. 274 ''' 275 self.identity_sets = svc.IdentitySets(channel, self) 276 ''' 277 A IdentitySet is a named grouping of Identity Aliases for Accounts. 278 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 279 280 See `strongdm.svc.IdentitySets`. 281 ''' 282 self.identity_sets_history = svc.IdentitySetsHistory(channel, self) 283 ''' 284 IdentitySetsHistory records all changes to the state of a IdentitySet. 285 286 See `strongdm.svc.IdentitySetsHistory`. 287 ''' 288 self.managed_secrets = svc.ManagedSecrets(channel, self) 289 ''' 290 ManagedSecret is a private vertical for creating, reading, updating, 291 deleting, listing and rotating the managed secrets in the secrets engines as 292 an authenticated user. 293 294 See `strongdm.svc.ManagedSecrets`. 295 ''' 296 self.nodes = svc.Nodes(channel, self) 297 ''' 298 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 299 There are three types of nodes: 300 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 301 2. **Gateway:** a relay that also listens for connections from StrongDM clients 302 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 303 304 See `strongdm.svc.Nodes`. 305 ''' 306 self.nodes_history = svc.NodesHistory(channel, self) 307 ''' 308 NodesHistory records all changes to the state of a Node. 309 310 See `strongdm.svc.NodesHistory`. 311 ''' 312 self.organization_history = svc.OrganizationHistory(channel, self) 313 ''' 314 OrganizationHistory records all changes to the state of an Organization. 315 316 See `strongdm.svc.OrganizationHistory`. 317 ''' 318 self.peering_group_nodes = svc.PeeringGroupNodes(channel, self) 319 ''' 320 PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group. 321 322 See `strongdm.svc.PeeringGroupNodes`. 323 ''' 324 self.peering_group_peers = svc.PeeringGroupPeers(channel, self) 325 ''' 326 PeeringGroupPeers provides the building blocks necessary to link two peering groups. 327 328 See `strongdm.svc.PeeringGroupPeers`. 329 ''' 330 self.peering_group_resources = svc.PeeringGroupResources(channel, self) 331 ''' 332 PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group. 333 334 See `strongdm.svc.PeeringGroupResources`. 335 ''' 336 self.peering_groups = svc.PeeringGroups(channel, self) 337 ''' 338 PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing. 339 340 See `strongdm.svc.PeeringGroups`. 341 ''' 342 self.policies = svc.Policies(channel, self) 343 ''' 344 Policies are the collection of one or more statements that enforce fine-grained access 345 control for the users of an organization. 346 347 See `strongdm.svc.Policies`. 348 ''' 349 self.policies_history = svc.PoliciesHistory(channel, self) 350 ''' 351 PoliciesHistory records all changes to the state of a Policy. 352 353 See `strongdm.svc.PoliciesHistory`. 354 ''' 355 self.proxy_cluster_keys = svc.ProxyClusterKeys(channel, self) 356 ''' 357 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 358 The proxies within a cluster share the same key. One cluster can have 359 multiple keys in order to facilitate key rotation. 360 361 See `strongdm.svc.ProxyClusterKeys`. 362 ''' 363 self.queries = svc.Queries(channel, self) 364 ''' 365 A Query is a record of a single client request to a resource, such as a SQL query. 366 Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries. 367 The Queries service is read-only. 368 369 See `strongdm.svc.Queries`. 370 ''' 371 self.remote_identities = svc.RemoteIdentities(channel, self) 372 ''' 373 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 374 375 See `strongdm.svc.RemoteIdentities`. 376 ''' 377 self.remote_identities_history = svc.RemoteIdentitiesHistory( 378 channel, self) 379 ''' 380 RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity. 381 382 See `strongdm.svc.RemoteIdentitiesHistory`. 383 ''' 384 self.remote_identity_groups = svc.RemoteIdentityGroups(channel, self) 385 ''' 386 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 387 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 388 389 See `strongdm.svc.RemoteIdentityGroups`. 390 ''' 391 self.remote_identity_groups_history = svc.RemoteIdentityGroupsHistory( 392 channel, self) 393 ''' 394 RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup. 395 396 See `strongdm.svc.RemoteIdentityGroupsHistory`. 397 ''' 398 self.replays = svc.Replays(channel, self) 399 ''' 400 A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session 401 (otherwise referred to as a query). The Replays service is read-only. 402 403 See `strongdm.svc.Replays`. 404 ''' 405 self.resources = svc.Resources(channel, self) 406 ''' 407 Resources are databases, servers, clusters, websites, or clouds that strongDM 408 delegates access to. 409 410 See `strongdm.svc.Resources`. 411 ''' 412 self.resources_history = svc.ResourcesHistory(channel, self) 413 ''' 414 ResourcesHistory records all changes to the state of a Resource. 415 416 See `strongdm.svc.ResourcesHistory`. 417 ''' 418 self.role_resources = svc.RoleResources(channel, self) 419 ''' 420 RoleResources enumerates the resources to which roles have access. 421 The RoleResources service is read-only. 422 423 See `strongdm.svc.RoleResources`. 424 ''' 425 self.role_resources_history = svc.RoleResourcesHistory(channel, self) 426 ''' 427 RoleResourcesHistory records all changes to the state of a RoleResource. 428 429 See `strongdm.svc.RoleResourcesHistory`. 430 ''' 431 self.roles_history = svc.RolesHistory(channel, self) 432 ''' 433 RolesHistory records all changes to the state of a Role. 434 435 See `strongdm.svc.RolesHistory`. 436 ''' 437 self.secret_stores = svc.SecretStores(channel, self) 438 ''' 439 SecretStores are servers where resource secrets (passwords, keys) are stored. 440 441 See `strongdm.svc.SecretStores`. 442 ''' 443 self.secret_engines = svc.SecretEngines(channel, self) 444 ''' 445 446 447 See `strongdm.svc.SecretEngines`. 448 ''' 449 self.secret_store_healths = svc.SecretStoreHealths(channel, self) 450 ''' 451 SecretStoreHealths exposes health states for secret stores. 452 453 See `strongdm.svc.SecretStoreHealths`. 454 ''' 455 self.secret_stores_history = svc.SecretStoresHistory(channel, self) 456 ''' 457 SecretStoresHistory records all changes to the state of a SecretStore. 458 459 See `strongdm.svc.SecretStoresHistory`. 460 ''' 461 self.workflow_approvers = svc.WorkflowApprovers(channel, self) 462 ''' 463 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 464 465 See `strongdm.svc.WorkflowApprovers`. 466 ''' 467 self.workflow_approvers_history = svc.WorkflowApproversHistory( 468 channel, self) 469 ''' 470 WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover. 471 472 See `strongdm.svc.WorkflowApproversHistory`. 473 ''' 474 self.workflow_roles = svc.WorkflowRoles(channel, self) 475 ''' 476 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 477 to request access to a resource via the workflow. 478 479 See `strongdm.svc.WorkflowRoles`. 480 ''' 481 self.workflow_roles_history = svc.WorkflowRolesHistory(channel, self) 482 ''' 483 WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole 484 485 See `strongdm.svc.WorkflowRolesHistory`. 486 ''' 487 self.workflows = svc.Workflows(channel, self) 488 ''' 489 Workflows are the collection of rules that define the resources to which access can be requested, 490 the users that can request that access, and the mechanism for approving those requests which can either 491 be automatic approval or a set of users authorized to approve the requests. 492 493 See `strongdm.svc.Workflows`. 494 ''' 495 self.workflows_history = svc.WorkflowsHistory(channel, self) 496 ''' 497 WorkflowsHistory provides records of all changes to the state of a Workflow. 498 499 See `strongdm.svc.WorkflowsHistory`. 500 '''
Create a new Client.
- api_access_key: the access key to authenticate with strongDM
- api_secret: the secret key to authenticate with strongDM
AccessRequestEventsHistory provides records of all changes to the state of an AccessRequest.
AccessRequestsHistory provides records of all changes to the state of an AccessRequest.
AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
AccountPermissions records the granular permissions accounts have, allowing them to execute relevant commands via StrongDM's APIs.
AccountResources enumerates the resources to which accounts have access. The AccountResources service is read-only.
AccountResourcesHistory records all changes to the state of a AccountResource.
Accounts are users that have access to strongDM. There are two types of accounts:
- Users: humans who are authenticated through username and password or SSO.
- Service Accounts: machines that are authenticated using a service token.
- Tokens are access keys with permissions that can be used for authentication.
An Activity is a record of an action taken against a strongDM deployment, e.g. a user creation, resource deletion, sso configuration change, etc. The Activities service is read-only.
ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
ApprovalWorkflowApproversHistory records all changes to the state of an ApprovalWorkflowApprover.
ApprovalWorkflowStepsHistory records all changes to the state of an ApprovalWorkflowStep.
ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized approvers and be approved or denied.
ApprovalWorkflowsHistory records all changes to the state of an ApprovalWorkflow.
A Role has a list of access rules which determine which Resources the members of the Role have access to. An Account can be a member of multiple Roles via AccountAttachments.
See strongdm.svc.Roles.
HealthChecks lists the last healthcheck between each node and resource. Note the unconventional capitalization here is to prevent having a collision with GRPC
IdentityAliases assign an alias to an account within an IdentitySet. The alias is used as the username when connecting to a identity supported resource.
IdentityAliasesHistory records all changes to the state of a IdentityAlias.
A IdentitySet is a named grouping of Identity Aliases for Accounts. An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
ManagedSecret is a private vertical for creating, reading, updating, deleting, listing and rotating the managed secrets in the secrets engines as an authenticated user.
Nodes make up the StrongDM network, and allow your users to connect securely to your resources. There are three types of nodes:
- Relay: creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
- Gateway: a relay that also listens for connections from StrongDM clients
- Proxy Cluster: a cluster of workers that together mediate access from clients to resources
See strongdm.svc.Nodes.
PeeringGroupNodes provides the building blocks necessary to obtain attach a node to a peering group.
PeeringGroupPeers provides the building blocks necessary to link two peering groups.
PeeringGroupResources provides the building blocks necessary to obtain attach a resource to a peering group.
PeeringGroups provides the building blocks necessary to obtain explicit network topology and routing.
Policies are the collection of one or more statements that enforce fine-grained access control for the users of an organization.
Proxy Cluster Keys are authentication keys for all proxies within a cluster. The proxies within a cluster share the same key. One cluster can have multiple keys in order to facilitate key rotation.
A Query is a record of a single client request to a resource, such as a SQL query. Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries. The Queries service is read-only.
See strongdm.svc.Queries.
RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session (otherwise referred to as a query). The Replays service is read-only.
See strongdm.svc.Replays.
Resources are databases, servers, clusters, websites, or clouds that strongDM delegates access to.
RoleResources enumerates the resources to which roles have access. The RoleResources service is read-only.
WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
WorkflowApproversHistory provides records of all changes to the state of a WorkflowApprover.
WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of to request access to a resource via the workflow.
WorkflowRolesHistory provides records of all changes to the state of a WorkflowRole
Workflows are the collection of rules that define the resources to which access can be requested, the users that can request that access, and the mechanism for approving those requests which can either be automatic approval or a set of users authorized to approve the requests.
502 def close(self): 503 '''Closes this Client and releases all resources held by it. 504 505 Closing the Client will immediately terminate all RPCs active with the 506 Client and it is not valid to invoke new RPCs with the Client. 507 508 This method is idempotent. 509 ''' 510 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.
521 def sign(self, method_name, request_bytes): 522 def hmac_digest(key, msg_byte_string): 523 return hmac.new(key, msg=msg_byte_string, 524 digestmod=hashlib.sha256).digest() 525 526 current_utc_date = datetime.datetime.now( 527 datetime.timezone.utc).strftime('%Y-%m-%d') 528 signing_key = hmac_digest(self.api_secret, current_utc_date.encode()) 529 signing_key = hmac_digest(signing_key, b'sdm_api_v1') 530 531 hash = hashlib.sha256() 532 533 hash.update(method_name.encode()) 534 hash.update(b'\n') 535 hash.update(request_bytes) 536 537 return base64.b64encode(hmac_digest(signing_key, hash.digest()))
539 def exponentialBackoff(self, retries, deadline=None): 540 def applyDeadline(delay, deadline): 541 if deadline is None: 542 return delay 543 remaining = deadline - time.time() 544 if remaining < 0: 545 return 0 546 return min(delay, remaining) 547 548 if retries == 0: 549 return applyDeadline(self.base_retry_delay, deadline) 550 551 backoff, max_delay = self.base_retry_delay, self.max_retry_delay 552 while backoff < max_delay and retries > 0: 553 backoff *= self.retry_factor 554 retries -= 1 555 556 if backoff > max_delay: 557 backoff = max_delay 558 559 # Randomize backoff delays so that if a cluster of requests start at 560 # the same time, they won't operate in lockstep. 561 backoff *= 1 + self.retry_jitter * (random.random() * 2 - 1) 562 if backoff < 0: 563 return 0 564 565 return applyDeadline(backoff, deadline)
567 def shouldRetry(self, retries, err, deadline=None): 568 # Check if we've passed the deadline 569 if deadline is not None and time.time() >= deadline: 570 return False 571 572 if not isinstance(err, grpc.RpcError): 573 return False 574 575 if self.retry_rate_limit_errors and err.code( 576 ) == grpc.StatusCode.RESOURCE_EXHAUSTED: 577 return True 578 579 return retries <= 3 and (err.code() == grpc.StatusCode.INTERNAL 580 or err.code() == grpc.StatusCode.UNAVAILABLE)
582 def snapshot_at(self, snapshot_datetime): 583 ''' 584 Constructs a read-only client that will provide historical data from the provided timestamp. 585 586 See `SnapshotClient`. 587 ''' 588 client = copy.copy(self) 589 client.snapshot_datetime = snapshot_datetime 590 client.access_requests = svc.AccessRequests(client.channel, client) 591 client.account_attachments = svc.AccountAttachments( 592 client.channel, client) 593 client.account_grants = svc.AccountGrants(client.channel, client) 594 client.account_permissions = svc.AccountPermissions( 595 client.channel, client) 596 client.account_resources = svc.AccountResources(client.channel, client) 597 client.accounts = svc.Accounts(client.channel, client) 598 client.accounts_groups = svc.AccountsGroups(client.channel, client) 599 client.approval_workflow_approvers = svc.ApprovalWorkflowApprovers( 600 client.channel, client) 601 client.approval_workflow_steps = svc.ApprovalWorkflowSteps( 602 client.channel, client) 603 client.approval_workflows = svc.ApprovalWorkflows( 604 client.channel, client) 605 client.roles = svc.Roles(client.channel, client) 606 client.groups = svc.Groups(client.channel, client) 607 client.groups_roles = svc.GroupsRoles(client.channel, client) 608 client.identity_aliases = svc.IdentityAliases(client.channel, client) 609 client.identity_sets = svc.IdentitySets(client.channel, client) 610 client.nodes = svc.Nodes(client.channel, client) 611 client.policies = svc.Policies(client.channel, client) 612 client.proxy_cluster_keys = svc.ProxyClusterKeys( 613 client.channel, client) 614 client.remote_identities = svc.RemoteIdentities(client.channel, client) 615 client.remote_identity_groups = svc.RemoteIdentityGroups( 616 client.channel, client) 617 client.resources = svc.Resources(client.channel, client) 618 client.role_resources = svc.RoleResources(client.channel, client) 619 client.secret_stores = svc.SecretStores(client.channel, client) 620 client.workflow_approvers = svc.WorkflowApprovers( 621 client.channel, client) 622 client.workflow_roles = svc.WorkflowRoles(client.channel, client) 623 client.workflows = svc.Workflows(client.channel, client) 624 return SnapshotClient(client)
Constructs a read-only client that will provide historical data from the provided timestamp.
See SnapshotClient.
627class SnapshotClient: 628 '''SnapshotClient exposes methods to query historical records at a provided timestamp.''' 629 def __init__(self, client): 630 self.access_requests = svc.SnapshotAccessRequests( 631 client.access_requests) 632 ''' 633 AccessRequests are requests for access to a resource that may match a Workflow. 634 635 See `strongdm.svc.SnapshotAccessRequests`. 636 ''' 637 self.account_attachments = svc.SnapshotAccountAttachments( 638 client.account_attachments) 639 ''' 640 AccountAttachments assign an account to a role. 641 642 See `strongdm.svc.SnapshotAccountAttachments`. 643 ''' 644 self.account_grants = svc.SnapshotAccountGrants(client.account_grants) 645 ''' 646 AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource. 647 648 See `strongdm.svc.SnapshotAccountGrants`. 649 ''' 650 self.account_permissions = svc.SnapshotAccountPermissions( 651 client.account_permissions) 652 ''' 653 AccountPermissions records the granular permissions accounts have, allowing them to execute 654 relevant commands via StrongDM's APIs. 655 656 See `strongdm.svc.SnapshotAccountPermissions`. 657 ''' 658 self.account_resources = svc.SnapshotAccountResources( 659 client.account_resources) 660 ''' 661 AccountResources enumerates the resources to which accounts have access. 662 The AccountResources service is read-only. 663 664 See `strongdm.svc.SnapshotAccountResources`. 665 ''' 666 self.accounts = svc.SnapshotAccounts(client.accounts) 667 ''' 668 Accounts are users that have access to strongDM. There are two types of accounts: 669 1. **Users:** humans who are authenticated through username and password or SSO. 670 2. **Service Accounts:** machines that are authenticated using a service token. 671 3. **Tokens** are access keys with permissions that can be used for authentication. 672 673 See `strongdm.svc.SnapshotAccounts`. 674 ''' 675 self.accounts_groups = svc.SnapshotAccountsGroups( 676 client.accounts_groups) 677 ''' 678 An AccountGroup links an account and a group. 679 680 See `strongdm.svc.SnapshotAccountsGroups`. 681 ''' 682 self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers( 683 client.approval_workflow_approvers) 684 ''' 685 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 686 687 See `strongdm.svc.SnapshotApprovalWorkflowApprovers`. 688 ''' 689 self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps( 690 client.approval_workflow_steps) 691 ''' 692 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 693 694 See `strongdm.svc.SnapshotApprovalWorkflowSteps`. 695 ''' 696 self.approval_workflows = svc.SnapshotApprovalWorkflows( 697 client.approval_workflows) 698 ''' 699 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 700 approvers and be approved or denied. 701 702 See `strongdm.svc.SnapshotApprovalWorkflows`. 703 ''' 704 self.roles = svc.SnapshotRoles(client.roles) 705 ''' 706 A Role has a list of access rules which determine which Resources the members 707 of the Role have access to. An Account can be a member of multiple Roles via 708 AccountAttachments. 709 710 See `strongdm.svc.SnapshotRoles`. 711 ''' 712 self.groups = svc.SnapshotGroups(client.groups) 713 ''' 714 A Group is a set of principals. 715 716 See `strongdm.svc.SnapshotGroups`. 717 ''' 718 self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles) 719 ''' 720 A GroupRole is an assignment of a Group to a Role. 721 722 See `strongdm.svc.SnapshotGroupsRoles`. 723 ''' 724 self.identity_aliases = svc.SnapshotIdentityAliases( 725 client.identity_aliases) 726 ''' 727 IdentityAliases assign an alias to an account within an IdentitySet. 728 The alias is used as the username when connecting to a identity supported resource. 729 730 See `strongdm.svc.SnapshotIdentityAliases`. 731 ''' 732 self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets) 733 ''' 734 A IdentitySet is a named grouping of Identity Aliases for Accounts. 735 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 736 737 See `strongdm.svc.SnapshotIdentitySets`. 738 ''' 739 self.nodes = svc.SnapshotNodes(client.nodes) 740 ''' 741 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 742 There are three types of nodes: 743 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 744 2. **Gateway:** a relay that also listens for connections from StrongDM clients 745 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 746 747 See `strongdm.svc.SnapshotNodes`. 748 ''' 749 self.policies = svc.SnapshotPolicies(client.policies) 750 ''' 751 Policies are the collection of one or more statements that enforce fine-grained access 752 control for the users of an organization. 753 754 See `strongdm.svc.SnapshotPolicies`. 755 ''' 756 self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys( 757 client.proxy_cluster_keys) 758 ''' 759 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 760 The proxies within a cluster share the same key. One cluster can have 761 multiple keys in order to facilitate key rotation. 762 763 See `strongdm.svc.SnapshotProxyClusterKeys`. 764 ''' 765 self.remote_identities = svc.SnapshotRemoteIdentities( 766 client.remote_identities) 767 ''' 768 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 769 770 See `strongdm.svc.SnapshotRemoteIdentities`. 771 ''' 772 self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups( 773 client.remote_identity_groups) 774 ''' 775 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 776 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 777 778 See `strongdm.svc.SnapshotRemoteIdentityGroups`. 779 ''' 780 self.resources = svc.SnapshotResources(client.resources) 781 ''' 782 Resources are databases, servers, clusters, websites, or clouds that strongDM 783 delegates access to. 784 785 See `strongdm.svc.SnapshotResources`. 786 ''' 787 self.role_resources = svc.SnapshotRoleResources(client.role_resources) 788 ''' 789 RoleResources enumerates the resources to which roles have access. 790 The RoleResources service is read-only. 791 792 See `strongdm.svc.SnapshotRoleResources`. 793 ''' 794 self.secret_stores = svc.SnapshotSecretStores(client.secret_stores) 795 ''' 796 SecretStores are servers where resource secrets (passwords, keys) are stored. 797 798 See `strongdm.svc.SnapshotSecretStores`. 799 ''' 800 self.workflow_approvers = svc.SnapshotWorkflowApprovers( 801 client.workflow_approvers) 802 ''' 803 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 804 805 See `strongdm.svc.SnapshotWorkflowApprovers`. 806 ''' 807 self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles) 808 ''' 809 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 810 to request access to a resource via the workflow. 811 812 See `strongdm.svc.SnapshotWorkflowRoles`. 813 ''' 814 self.workflows = svc.SnapshotWorkflows(client.workflows) 815 ''' 816 Workflows are the collection of rules that define the resources to which access can be requested, 817 the users that can request that access, and the mechanism for approving those requests which can either 818 be automatic approval or a set of users authorized to approve the requests. 819 820 See `strongdm.svc.SnapshotWorkflows`. 821 '''
SnapshotClient exposes methods to query historical records at a provided timestamp.
629 def __init__(self, client): 630 self.access_requests = svc.SnapshotAccessRequests( 631 client.access_requests) 632 ''' 633 AccessRequests are requests for access to a resource that may match a Workflow. 634 635 See `strongdm.svc.SnapshotAccessRequests`. 636 ''' 637 self.account_attachments = svc.SnapshotAccountAttachments( 638 client.account_attachments) 639 ''' 640 AccountAttachments assign an account to a role. 641 642 See `strongdm.svc.SnapshotAccountAttachments`. 643 ''' 644 self.account_grants = svc.SnapshotAccountGrants(client.account_grants) 645 ''' 646 AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource. 647 648 See `strongdm.svc.SnapshotAccountGrants`. 649 ''' 650 self.account_permissions = svc.SnapshotAccountPermissions( 651 client.account_permissions) 652 ''' 653 AccountPermissions records the granular permissions accounts have, allowing them to execute 654 relevant commands via StrongDM's APIs. 655 656 See `strongdm.svc.SnapshotAccountPermissions`. 657 ''' 658 self.account_resources = svc.SnapshotAccountResources( 659 client.account_resources) 660 ''' 661 AccountResources enumerates the resources to which accounts have access. 662 The AccountResources service is read-only. 663 664 See `strongdm.svc.SnapshotAccountResources`. 665 ''' 666 self.accounts = svc.SnapshotAccounts(client.accounts) 667 ''' 668 Accounts are users that have access to strongDM. There are two types of accounts: 669 1. **Users:** humans who are authenticated through username and password or SSO. 670 2. **Service Accounts:** machines that are authenticated using a service token. 671 3. **Tokens** are access keys with permissions that can be used for authentication. 672 673 See `strongdm.svc.SnapshotAccounts`. 674 ''' 675 self.accounts_groups = svc.SnapshotAccountsGroups( 676 client.accounts_groups) 677 ''' 678 An AccountGroup links an account and a group. 679 680 See `strongdm.svc.SnapshotAccountsGroups`. 681 ''' 682 self.approval_workflow_approvers = svc.SnapshotApprovalWorkflowApprovers( 683 client.approval_workflow_approvers) 684 ''' 685 ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep 686 687 See `strongdm.svc.SnapshotApprovalWorkflowApprovers`. 688 ''' 689 self.approval_workflow_steps = svc.SnapshotApprovalWorkflowSteps( 690 client.approval_workflow_steps) 691 ''' 692 ApprovalWorkflowSteps link approval workflow steps to an ApprovalWorkflow 693 694 See `strongdm.svc.SnapshotApprovalWorkflowSteps`. 695 ''' 696 self.approval_workflows = svc.SnapshotApprovalWorkflows( 697 client.approval_workflows) 698 ''' 699 ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized 700 approvers and be approved or denied. 701 702 See `strongdm.svc.SnapshotApprovalWorkflows`. 703 ''' 704 self.roles = svc.SnapshotRoles(client.roles) 705 ''' 706 A Role has a list of access rules which determine which Resources the members 707 of the Role have access to. An Account can be a member of multiple Roles via 708 AccountAttachments. 709 710 See `strongdm.svc.SnapshotRoles`. 711 ''' 712 self.groups = svc.SnapshotGroups(client.groups) 713 ''' 714 A Group is a set of principals. 715 716 See `strongdm.svc.SnapshotGroups`. 717 ''' 718 self.groups_roles = svc.SnapshotGroupsRoles(client.groups_roles) 719 ''' 720 A GroupRole is an assignment of a Group to a Role. 721 722 See `strongdm.svc.SnapshotGroupsRoles`. 723 ''' 724 self.identity_aliases = svc.SnapshotIdentityAliases( 725 client.identity_aliases) 726 ''' 727 IdentityAliases assign an alias to an account within an IdentitySet. 728 The alias is used as the username when connecting to a identity supported resource. 729 730 See `strongdm.svc.SnapshotIdentityAliases`. 731 ''' 732 self.identity_sets = svc.SnapshotIdentitySets(client.identity_sets) 733 ''' 734 A IdentitySet is a named grouping of Identity Aliases for Accounts. 735 An Account's relationship to a IdentitySet is defined via IdentityAlias objects. 736 737 See `strongdm.svc.SnapshotIdentitySets`. 738 ''' 739 self.nodes = svc.SnapshotNodes(client.nodes) 740 ''' 741 Nodes make up the StrongDM network, and allow your users to connect securely to your resources. 742 There are three types of nodes: 743 1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall 744 2. **Gateway:** a relay that also listens for connections from StrongDM clients 745 3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources 746 747 See `strongdm.svc.SnapshotNodes`. 748 ''' 749 self.policies = svc.SnapshotPolicies(client.policies) 750 ''' 751 Policies are the collection of one or more statements that enforce fine-grained access 752 control for the users of an organization. 753 754 See `strongdm.svc.SnapshotPolicies`. 755 ''' 756 self.proxy_cluster_keys = svc.SnapshotProxyClusterKeys( 757 client.proxy_cluster_keys) 758 ''' 759 Proxy Cluster Keys are authentication keys for all proxies within a cluster. 760 The proxies within a cluster share the same key. One cluster can have 761 multiple keys in order to facilitate key rotation. 762 763 See `strongdm.svc.SnapshotProxyClusterKeys`. 764 ''' 765 self.remote_identities = svc.SnapshotRemoteIdentities( 766 client.remote_identities) 767 ''' 768 RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource. 769 770 See `strongdm.svc.SnapshotRemoteIdentities`. 771 ''' 772 self.remote_identity_groups = svc.SnapshotRemoteIdentityGroups( 773 client.remote_identity_groups) 774 ''' 775 A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. 776 An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects. 777 778 See `strongdm.svc.SnapshotRemoteIdentityGroups`. 779 ''' 780 self.resources = svc.SnapshotResources(client.resources) 781 ''' 782 Resources are databases, servers, clusters, websites, or clouds that strongDM 783 delegates access to. 784 785 See `strongdm.svc.SnapshotResources`. 786 ''' 787 self.role_resources = svc.SnapshotRoleResources(client.role_resources) 788 ''' 789 RoleResources enumerates the resources to which roles have access. 790 The RoleResources service is read-only. 791 792 See `strongdm.svc.SnapshotRoleResources`. 793 ''' 794 self.secret_stores = svc.SnapshotSecretStores(client.secret_stores) 795 ''' 796 SecretStores are servers where resource secrets (passwords, keys) are stored. 797 798 See `strongdm.svc.SnapshotSecretStores`. 799 ''' 800 self.workflow_approvers = svc.SnapshotWorkflowApprovers( 801 client.workflow_approvers) 802 ''' 803 WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow. 804 805 See `strongdm.svc.SnapshotWorkflowApprovers`. 806 ''' 807 self.workflow_roles = svc.SnapshotWorkflowRoles(client.workflow_roles) 808 ''' 809 WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of 810 to request access to a resource via the workflow. 811 812 See `strongdm.svc.SnapshotWorkflowRoles`. 813 ''' 814 self.workflows = svc.SnapshotWorkflows(client.workflows) 815 ''' 816 Workflows are the collection of rules that define the resources to which access can be requested, 817 the users that can request that access, and the mechanism for approving those requests which can either 818 be automatic approval or a set of users authorized to approve the requests. 819 820 See `strongdm.svc.SnapshotWorkflows`. 821 '''
AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
AccountPermissions records the granular permissions accounts have, allowing them to execute relevant commands via StrongDM's APIs.
AccountResources enumerates the resources to which accounts have access. The AccountResources service is read-only.
Accounts are users that have access to strongDM. There are two types of accounts:
- Users: humans who are authenticated through username and password or SSO.
- Service Accounts: machines that are authenticated using a service token.
- Tokens are access keys with permissions that can be used for authentication.
ApprovalWorkflowApprovers link approval workflow approvers to an ApprovalWorkflowStep
ApprovalWorkflows are the mechanism by which requests for access can be viewed by authorized approvers and be approved or denied.
A Role has a list of access rules which determine which Resources the members of the Role have access to. An Account can be a member of multiple Roles via AccountAttachments.
IdentityAliases assign an alias to an account within an IdentitySet. The alias is used as the username when connecting to a identity supported resource.
A IdentitySet is a named grouping of Identity Aliases for Accounts. An Account's relationship to a IdentitySet is defined via IdentityAlias objects.
Nodes make up the StrongDM network, and allow your users to connect securely to your resources. There are three types of nodes:
- Relay: creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
- Gateway: a relay that also listens for connections from StrongDM clients
- Proxy Cluster: a cluster of workers that together mediate access from clients to resources
Policies are the collection of one or more statements that enforce fine-grained access control for the users of an organization.
Proxy Cluster Keys are authentication keys for all proxies within a cluster. The proxies within a cluster share the same key. One cluster can have multiple keys in order to facilitate key rotation.
RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts. An Account's relationship to a RemoteIdentityGroup is defined via RemoteIdentity objects.
Resources are databases, servers, clusters, websites, or clouds that strongDM delegates access to.
RoleResources enumerates the resources to which roles have access. The RoleResources service is read-only.
WorkflowApprovers is an account or a role with the ability to approve requests bound to a workflow.
WorkflowRole links a role to a workflow. The linked roles indicate which roles a user must be a part of to request access to a resource via the workflow.