def check_validity( self, early_return=True, check_type=True, check_external_access=True, check_policy_accessible=True, ): logger.debug( "Validating Google Service Account {} for Google Project {}.".format( self.account_id, self.google_project_id ) ) self.google_cloud_manager.open() # check ownership logger.debug( "Determining if {} is owned by the Google Project.".format(self.account_id) ) is_owned_by_google_project = is_service_account_from_google_project( self.account_id, self.google_project_id, self.google_project_number ) self.set("owned_by_project", is_owned_by_google_project) if not is_owned_by_google_project: logger.warning( "INVALID SA {}, it is NOT owned by the Google Project {}.".format( self.account_id, self.google_project_id ) ) if early_return: self.google_cloud_manager.close() return # select the GCM to use for the remainder of the checks # if the account is not owned by the google project then # it is invalid, however, if Fence has access to the SA's # project, we can still check the other conditions if is_owned_by_google_project: gcm = self.google_cloud_manager else: self.google_cloud_manager.close() try: # check to see if we can access the project the SA belongs to project_id = self.account_id.split("@")[-1].split(".")[0] gcm = GoogleCloudManager(project_id) gcm.open() except Exception: logger.debug( "Could not access the Google Project for Service " "Account {}. Unable to continue validity " "checkingwithout access to the project, " "early exit.".format(self.account_id) ) return # check if the SA's policy is accessible policy_accessible = None sa_policy = None if check_policy_accessible: try: policy_accessible = True sa_policy = get_service_account_policy(self.account_id, gcm) except Exception: policy_accessible = False gcm.close() return finally: self.set("policy_accessible", policy_accessible) if check_external_access: if not policy_accessible: logger.warning( "Invalid function use. External Access check requires " "Service Account Policy & may fail if policy is not " "accessible. If you want to check external access, make " "sure you are also checking policy_accessible. " ) gcm.close() return no_external_access = not ( service_account_has_external_access(self.account_id, gcm, sa_policy) ) self.set("no_external_access", no_external_access) if not no_external_access: logger.warning( "INVALID SA {}, it has external access " "(keys generated or roles on it).".format(self.account_id) ) if early_return: gcm.close() return # check if the SA is an allowed type if check_type: if not policy_accessible: logger.warning( "Policy access was not checked. If the service account's " "policy is not accessible or the service account does not " "exist, this check may fail." ) # don't return early, we can still check type without checking # policy, however, if the SA doesn't exist, this will fail valid_type = is_valid_service_account_type(self.account_id, gcm) self.set("valid_type", valid_type) if not valid_type: logger.warning( "INVALID SA {}, it is not a valid SA type.".format(self.account_id) ) if early_return: gcm.close() return gcm.close()
def test_service_account_does_not_exist(cloud_manager): (cloud_manager.get_service_account_policy.return_value) = MockResponse({}, 404) with pytest.raises(NotFound): get_service_account_policy("test", cloud_manager)