def grant_access(access_list):

  client = strongdm.Client(access_key, secret_key)

  # Get Datasource(s)
  resources = list(client.resources.list('name:{}'.format(DATASOURCE)) )
  resourceID = resources[0].id

  # Cycle through the output from PagerDuty
  for item in access_list:
    # Use the PD email address to get the user from SDM
    print('Current PD user is: ' + item["email"])
    users = list(client.accounts.list('email:{}'.format(item["email"])))
    if len(users) > 0:
      print('SDM user found!')
      myUserID = users[0].id
      # Convert the date strings from PD into a datetime object
      s = datetime.datetime.strptime(item["from"], '%Y-%m-%dT%H:%M:%SZ')
      e = datetime.datetime.strptime(item["to"], '%Y-%m-%dT%H:%M:%SZ')
      # Make both objects 'aware' (with TZ) as required by the strongDM SDK
      start = s.replace(tzinfo=timezone.utc)
      end = e.replace(tzinfo=timezone.utc)
      # Create the grant object
      myGrant = strongdm.AccountGrant(resource_id='{}'.format(resourceID),account_id='{}'.format(myUserID), 
        start_from=start, valid_until=end)
      # Perform the grant
      try:
        respGrant = client.account_grants.create(myGrant)
      except Exception as ex:
        print("\nSkipping user " + item["email"] + " on account of error: " + str(ex))
      else:
        print("\nGrant succeeded for user " + item["email"] + " to resource " + DATASOURCE + " from {} to {}".format(start,end))
    print('---\n')
Пример #2
0
def main():
    client = strongdm.Client(os.getenv("SDM_API_ACCESS_KEY"),
                             os.getenv("SDM_API_SECRET_KEY"))

    users = client.accounts.list('')
    for user in users:
        print(user)
Пример #3
0
def main():
  client = strongdm.Client(os.getenv("SDM_API_ACCESS_KEY"), os.getenv("SDM_API_SECRET_KEY"))

 	# The RoleGrants API has been deprecated in favor of Access Rules.
 	# When using Access Rules, the best practice is to grant Resources access based on type and tags.
	# If it is _necessary_ to grant access to specific Resources in the same way as Role Grants did,
	# you can use Resource IDs directly in Access Rules as shown in the following examples.

  create_role_grant_via_access_rules(client)
  delete_role_grant_via_access_rules(client)
  list_role_grants_via_access_rules(client)
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import strongdm

# Load the SDM API keys from the environment.
# If these values are not set in your environment,
# please follow the documentation here:
# https://www.strongdm.com/docs/admin-guide/api-credentials/
api_access_key = os.getenv("SDM_API_ACCESS_KEY")
api_secret_key = os.getenv("SDM_API_SECRET_KEY")
client = strongdm.Client(api_access_key, api_secret_key)

service = strongdm.Service(name="example service account")

response = client.accounts.create(service, timeout=30)

print("Successfully created service.")
print("\tName:", response.account.name)
print("\tID:", response.account.id)
print("\tToken:", response.token)
Пример #5
0
def main():
    access_key = os.getenv("SDM_API_ACCESS_KEY")
    secret_key = os.getenv("SDM_API_SECRET_KEY")
    if access_key is None or secret_key is None:
        print("SDM_API_ACCESS_KEY and SDM_API_SECRET_KEY must be provided")
        return 1

    client = strongdm.Client(access_key, secret_key)

    if len(sys.argv) == 2 and sys.argv[1] == "revert":
        with open('state.json', 'r') as infile:
            state = json.load(infile)

            reinstated_count = 0

            users = client.accounts.list('')
            for user in users:
                if not user.suspended:
                    continue
                reinstated_count += 1
                user.suspended = False
                client.accounts.update(user)
            for attachment in state['attachments']:
                try:
                    client.account_attachments.create(
                        strongdm.AccountAttachment(
                            account_id=attachment["account_id"],
                            role_id=attachment["role_id"]))
                except strongdm.errors.AlreadyExistsError:
                    pass
                except Exception as ex:
                    print("skipping creation of attachment due to error: ",
                          str(ex))
            for grant in state['grants']:
                try:
                    client.account_grants.create(
                        strongdm.AccountGrant(
                            account_id=grant["account_id"],
                            resource_id=grant["resource_id"]))
                except strongdm.errors.AlreadyExistsError:
                    pass
                except Exception as ex:
                    print("skipping creation of grant due to error: ", str(ex))
            print("reinstated " + str(reinstated_count) + " users")
            print("recreated " + str(len(state['attachments'])) +
                  " account attachments")
            print("recreated " + str(len(state['grants'])) + " account grants")
        return

    admin_email = ""
    if len(sys.argv) == 2:
        admin_email = sys.argv[1]
    else:
        print("please provide an admin email to preserve")
        return 1

    admin_user_id = ""
    users = client.accounts.list('email:?', admin_email)
    for user in users:
        admin_user_id = user.id

    account_attachments = client.account_attachments.list('')
    account_grants = client.account_grants.list('')

    state = {
        'attachments': [{
            "account_id": x.account_id,
            "role_id": x.role_id
        } for x in account_attachments if x.account_id != admin_user_id],
        'grants': [{
            "account_id": x.account_id,
            "resource_id": x.resource_id
        } for x in account_grants
                   if x.account_id != admin_user_id and x.valid_until is None],
    }

    print("storing " + str(len(state['attachments'])) +
          " account attachments in state")
    print("storing " + str(len(state['grants'])) + " account grants in state")

    with open('state.json', 'w') as outfile:
        json.dump(state, outfile)

    suspended_count = 0
    users = client.accounts.list('')
    for user in users:
        if isinstance(user, strongdm.User) and user.email == admin_email:
            continue
        user.suspended = True
        try:
            client.accounts.update(user)
            suspended_count += 1
        except Exception as ex:
            print("skipping user " + user.id + " on account of error: " +
                  str(ex))

    print("suspended " + str(suspended_count) + " users ")
Пример #6
0
def create_sdm_service(api_access_key, api_secret_key, log):
    client = strongdm.Client(api_access_key, api_secret_key)
    return SdmService(client, log)
Пример #7
0
import logging
import os
import strongdm

import model

client = strongdm.Client(os.getenv("SDM_API_ACCESS_KEY"),
                         os.getenv("SDM_API_SECRET_KEY"))


def save_user_resources(users: [model.User]):
    for user in users:
        sdm_user = get_or_create_user(user)
        logging.info("User details %s", sdm_user)

        for resource in user.resources_to_grant:
            sdm_resource = grant_resource(sdm_user, resource)
            if sdm_resource:
                logging.info("Resource = %s granted to user = %s",
                             sdm_resource, sdm_user)

        for resource in user.resources_to_revoke:
            sdm_resource = revoke_resource(sdm_user, resource)
            if sdm_resource:
                logging.info("Resource = %s revoked from user = %s",
                             sdm_resource, sdm_user)


def get_or_create_user(user: model.User):
    sdm_user = next(client.accounts.list(f'email:{user.email}'), None)
    if not sdm_user:
Пример #8
0
def okta_sync(plan, verbose):
    SDM_API_ACCESS_KEY = os.getenv('SDM_API_ACCESS_KEY')
    SDM_API_SECRET_KEY = os.getenv('SDM_API_SECRET_KEY')
    OKTA_CLIENT_TOKEN = os.getenv('OKTA_CLIENT_TOKEN')
    OKTA_CLIENT_ORGURL = os.getenv('OKTA_CLIENT_ORGURL')

    if SDM_API_ACCESS_KEY is None or SDM_API_SECRET_KEY is None \
        or OKTA_CLIENT_TOKEN is None or OKTA_CLIENT_ORGURL is None:
        print(
            "SDM_API_ACCESS_KEY, SDM_API_SECRET_KEY, OKTA_CLIENT_TOKEN, and OKTA_CLIENT_ORGURL must be set"
        )
        return

    report = {
        'start': str(datetime.datetime.now()),
        'oktaUsersCount': 0,
        'oktaUsers': [],
        'sdmUsersCount': 0,
        'sdmUsers': [],
        'bothUsersCount': 0,
        'sdmResourcesCount': 0,
        'sdmResources': {},
        'permissionsGranted': 0,
        'permissionsRevoked': 0,
        'grants': [],
        'revocations': [],
        'matchers': {},
    }

    matchers = load_matchers()
    okta_users = load_okta_users()

    report['matchers'] = matchers
    report['oktaUsers'] = [x.to_dict() for x in okta_users]
    report['oktaUsersCount'] = len(okta_users)

    client = strongdm.Client(SDM_API_ACCESS_KEY, SDM_API_SECRET_KEY)

    accounts = {o.email: o for o in client.accounts.list('type:user')}
    permissions = [v for v in client.account_grants.list('')]

    report['sdmUsers'] = {k: v.to_dict() for (k, v) in accounts.items()}
    report['sdmUsersCount'] = len(accounts)

    # define current state
    current = {}
    for p in permissions:
        if p.account_id not in current:
            current[p.account_id] = set()
        current[p.account_id].add((p.resource_id, p.id))

    # define desired state
    desired = {}
    overlapping = 0
    for group in matchers["groups"]:
        for resourceQuery in group["resources"]:
            for res in client.resources.list(resourceQuery):
                report['sdmResources'] = res
                for u in okta_users:
                    if group["name"] in u.groups:
                        if u.login not in accounts:
                            continue
                        overlapping += 1
                        aid = accounts[u.login].id
                        if aid not in desired:
                            desired[aid] = set()
                        desired[aid].add(res.id)

    report['bothUsersCount'] = overlapping
    report['sdmResourcesCount'] = len(report['sdmResources'])

    # revoke things
    revocations = 0
    for aid, curRes in current.items():
        desRes = desired.get(aid, set())
        for rid in curRes:
            if rid[0] not in desRes:
                if plan:
                    print('Plan: revoke {} from user {}'.format(rid[1], aid))
                else:
                    client.account_grants.delete(rid[1])
                report['revocations'].append(rid[1])
                revocations += 1
    report['permissionsRevoked'] = revocations

    # grant things
    grants = 0
    for aid, desRes in desired.items():
        curRes = current.get(aid, set())
        for rid in desRes:
            for cr in curRes:
                if rid != cr[0]:
                    ag = strongdm.AccountGrant(resource_id=rid, account_id=aid)
                    if plan:
                        print('Plan: grant {} to user {}'.format(rid, aid))
                    else:
                        ag = client.account_grants.create(ag)
                    report['grants'].append(ag)
                    grants += 1
    report['permissionsGranted'] = grants
    report['complete'] = str(datetime.datetime.now())

    if verbose:
        print(json.dumps(report, indent=4, sort_keys=True))
    else:
        print("{} Okta users, {} strongDM users, {} overlapping users, {} grants, {} revocations".format(\
            len(okta_users),len(accounts), overlapping, grants, revocations))