Ejemplo n.º 1
0
    def verify_slice(self, slice_hrn, slice_record, peer, sfa_peer, options={}):
        slicename = hrn_to_pl_slicename(slice_hrn)
        parts = slicename.split("_")
        login_base = parts[0]
        slices = self.driver.shell.GetSlices([slicename]) 
        if not slices:
            slice = {'name': slicename,
                     'url': slice_record.get('url', slice_hrn), 
                     'description': slice_record.get('description', slice_hrn)}
            # add the slice                          
            slice['slice_id'] = self.driver.shell.AddSlice(slice)
            slice['node_ids'] = []
            slice['person_ids'] = []
            if peer:
                slice['peer_slice_id'] = slice_record.get('slice_id', None) 
            # mark this slice as an sfa peer record
#            if sfa_peer:
#                peer_dict = {'type': 'slice', 'hrn': slice_hrn, 
#                             'peer_authority': sfa_peer, 'pointer': slice['slice_id']}
#                self.registry.register_peer_object(self.credential, peer_dict)
        else:
            slice = slices[0]
            if peer:
                slice['peer_slice_id'] = slice_record.get('slice_id', None)
                # unbind from peer so we can modify if necessary. Will bind back later
                self.driver.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
	        #Update existing record (e.g. expires field) it with the latest info.
            if slice_record.get('expires'):
                requested_expires = int(datetime_to_epoch(utcparse(slice_record['expires'])))
                if requested_expires and slice['expires'] != requested_expires:
                    self.driver.shell.UpdateSlice( slice['slice_id'], {'expires' : requested_expires})
       
        return slice
Ejemplo n.º 2
0
    def verify_slice(self, slice_hrn, slice_record, expiration, options={}):
        slicename = hrn_to_unigetestbed_slicename(slice_hrn)
        parts = slicename.split("_")
        login_base = parts[0]
        slices = self.driver.shell.GetSlices({'slice_name': slicename})
        if not slices:
            slice = {'slice_name': slicename}
            # add the slice
            slice['slice_id'] = self.driver.shell.AddSlice(slice)
            slice['node_ids'] = []
            slice['user_ids'] = []
        else:
            slice = slices[0]
            if slice_record and slice_record.get('expires'):
                requested_expires = int(
                    datetime_to_epoch(utcparse(slice_record['expires'])))
                if requested_expires and slice['expires'] != requested_expires:
                    self.driver.shell.UpdateSlice({
                        'slice_id': slice['slice_id'],
                        'fields': {
                            'expires': expiration
                        }
                    })

        return slice
Ejemplo n.º 3
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn     
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        record=dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            if caller_type:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn,type=caller_type).first()
            else:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first()
            if not caller_record:
                raise RecordNotFound("Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"%(caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)i

        object_hrn = record.get_gid_object().get_hrn()
        # call the builtin authorization/credential generation engine
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError("%s has no rights to %s (%s)" % \
                                  (caller_hrn, object_hrn, xrn))
        object_gid = GID(string=record.gid)
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record,'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
Ejemplo n.º 4
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn     
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        record=dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            if caller_type:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn,type=caller_type).first()
            else:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first()
            if not caller_record:
                raise RecordNotFound("Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"%(caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)

        object_hrn = record.get_gid_object().get_hrn()
        # call the builtin authorization/credential generation engine
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError("%s has no rights to %s (%s)" % \
                                  (caller_hrn, object_hrn, xrn))
        object_gid = GID(string=record.gid)
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record,'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
Ejemplo n.º 5
0
    def verify_slice(self,
                     slice_hrn,
                     slice_record,
                     sfa_peer,
                     expiration,
                     options={}):
        #top_auth_hrn = top_auth(slice_hrn)
        #site_hrn = '.'.join(slice_hrn.split('.')[:-1])
        #slice_part = slice_hrn.split('.')[-1]
        #if top_auth_hrn == self.driver.hrn:
        #    login_base = slice_hrn.split('.')[-2][:12]
        #else:
        #    login_base = hash_loginbase(site_hrn)
        #slice_name = '_'.join([login_base, slice_part])
        plxrn = PlXrn(xrn=slice_hrn)
        slice_hrn = plxrn.get_hrn()
        type = plxrn.get_type()
        site_hrn = plxrn.get_authority_hrn()
        authority_name = plxrn.pl_authname()
        slicename = plxrn.pl_slicename()
        login_base = plxrn.pl_login_base()

        slices = self.driver.shell.GetSlices({'peer_id': None},
                                             ['slice_id', 'name', 'hrn'])
        # Filter slices by HRN
        slice_exists = [slice for slice in slices if slice['hrn'] == slice_hrn]
        expires = int(datetime_to_epoch(utcparse(expiration)))
        if not slice_exists:
            if slice_record:
                url = slice_record.get('url', slice_hrn)
                description = slice_record.get('description', slice_hrn)
            else:
                url = slice_hrn
                description = slice_hrn
            slice = {
                'name': slice_name,
                'url': url,
                'description': description
            }
            # add the slice
            slice['slice_id'] = self.driver.shell.AddSlice(slice)
            # set the slice HRN
            self.driver.shell.SetSliceHrn(int(slice['slice_id']), slice_hrn)
            # Tag this as created through SFA
            self.driver.shell.SetSliceSfaCreated(int(slice['slice_id']),
                                                 'True')
            # set the expiration
            self.driver.shell.UpdateSlice(int(slice['slice_id']),
                                          {'expires': expires})

        else:
            slice = slice_exists[0]
            #Update expiration if necessary
            if slice.get('expires', None) != expires:
                self.driver.shell.UpdateSlice(int(slice['slice_id']),
                                              {'expires': expires})

        return self.driver.shell.GetSlices(int(slice['slice_id']))[0]
Ejemplo n.º 6
0
 def renew (self, urns, expiration_time, options={}):
     aggregate = unigetestbedAggregate(self)
     slivers = aggregate.get_slivers(urns)
     if not slivers:
         raise SearchFailed(urns)
     slice = slivers[0]
     requested_time = utcparse(expiration_time)
     record = {'expires': int(datetime_to_epoch(requested_time))}
     self.shell.UpdateSlice({'slice_id': slice['slice_id'], 'fileds': record})
     description = self.describe(urns, 'GENI 3', options)
     return description['geni_slivers']
Ejemplo n.º 7
0
 def renew(self, urns, expiration_time, options={}):
     aggregate = PlAggregate(self)
     slivers = aggregate.get_slivers(urns)
     if not slivers:
         raise SearchFailed(urns)
     slice = slivers[0]
     requested_time = utcparse(expiration_time)
     record = {'expires': int(datetime_to_epoch(requested_time))}
     self.shell.UpdateSlice(slice['slice_id'], record)
     description = self.describe(urns, 'GENI 3', options)
     return description['geni_slivers']
Ejemplo n.º 8
0
 def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
     slicename = hrn_to_pl_slicename(slice_hrn)
     slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
     if not slices:
         raise RecordNotFound(slice_hrn)
     slice = slices[0]
     requested_time = utcparse(expiration_time)
     record = {'expires': int(datetime_to_epoch(requested_time))}
     try:
         self.shell.UpdateSlice(slice['slice_id'], record)
         return True
     except:
         return False
Ejemplo n.º 9
0
 def renew_sliver(self, slice_urn, slice_hrn, creds, expiration_time, options):
     slicename = hrn_to_dummy_slicename(slice_hrn)
     slices = self.shell.GetSlices({"slice_name": slicename})
     if not slices:
         raise RecordNotFound(slice_hrn)
     slice = slices[0]
     requested_time = utcparse(expiration_time)
     record = {"expires": int(datetime_to_epoch(requested_time))}
     try:
         self.shell.UpdateSlice({"slice_id": slice["slice_id"], "fields": record})
         return True
     except:
         return False
Ejemplo n.º 10
0
    def renew_sliver(self, slice_urn, slice_hrn, creds, expiration_time,
                     options):
        slicename = hrn_to_nitos_slicename(slice_hrn)
        slices = self.shell.GetSlices({'slicename': slicename}, ['slice_id'])
        if not slices:
            raise RecordNotFound(slice_hrn)
        slice = slices[0]
        requested_time = utcparse(expiration_time)
        record = {'expires': int(datetime_to_epoch(requested_time))}
        try:
            self.shell.UpdateSlice(slice['slice_id'], record)

            return True
        except:
            return False
Ejemplo n.º 11
0
    def verify_slice(self, slice_hrn, slice_record, sfa_peer, expiration, options=None):
        if options is None: options={}
        top_auth_hrn = top_auth(slice_hrn)
        site_hrn = '.'.join(slice_hrn.split('.')[:-1])
        slice_part = slice_hrn.split('.')[-1]
        if top_auth_hrn == self.driver.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)
        slice_name = '_'.join([login_base, slice_part])

        expires = int(datetime_to_epoch(utcparse(expiration)))
        # Filter slices by HRN
        slices = self.driver.shell.GetSlices({'peer_id': None, 'hrn':slice_hrn},
                                             ['slice_id','name','hrn','expires'])
        
        if slices:
            slice = slices[0]
            slice_id = slice['slice_id']
            #Update expiration if necessary
            if slice.get('expires', None) != expires:
                self.driver.shell.UpdateSlice( slice_id, {'expires' : expires})
        else:
            if slice_record:
                url = slice_record.get('url', slice_hrn)
                description = slice_record.get('description', slice_hrn)
            else:
                url = slice_hrn
                description = slice_hrn
            slice = {'name': slice_name,
                     'url': url,
                     'description': description,
                     'hrn': slice_hrn,
                     'sfa_created': 'True',
                     #'expires': expires,
            }
            # add the slice
            slice_id = self.driver.shell.AddSlice(slice)
            # plcapi tends to mess with the incoming hrn so let's make sure
            self.driver.shell.SetSliceHrn (slice_id, slice_hrn)
            # cannot be set with AddSlice
            # set the expiration
            self.driver.shell.UpdateSlice(slice_id, {'expires': expires})

        return self.driver.shell.GetSlices(slice_id)[0]
Ejemplo n.º 12
0
 def verify_slice(self, slice_hrn, slice_record, expiration, options={}):
     slicename = hrn_to_dummy_slicename(slice_hrn)
     parts = slicename.split("_")
     login_base = parts[0]
     slices = self.driver.shell.GetSlices({'slice_name': slicename}) 
     if not slices:
         slice = {'slice_name': slicename}
         # add the slice                          
         slice['slice_id'] = self.driver.shell.AddSlice(slice)
         slice['node_ids'] = []
         slice['user_ids'] = []
     else:
         slice = slices[0]
         if slice_record and slice_record.get('expires'):
             requested_expires = int(datetime_to_epoch(utcparse(slice_record['expires'])))
             if requested_expires and slice['expires'] != requested_expires:
                 self.driver.shell.UpdateSlice( {'slice_id': slice['slice_id'], 'fields':{'expires' : expiration}})
    
     return slice
Ejemplo n.º 13
0
    def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):

        pl_record = {}

        if type == "slice":
            pl_record["name"] = hrn_to_pl_slicename(hrn)
            if "instantiation" in sfa_record:
                pl_record['instantiation'] = sfa_record['instantiation']
            else:
                pl_record["instantiation"] = "plc-instantiated"
            if "url" in sfa_record:
                pl_record["url"] = sfa_record["url"]
            if "description" in sfa_record:
                pl_record["description"] = sfa_record["description"]
            if "expires" in sfa_record:
                date = utcparse(sfa_record['expires'])
                expires = datetime_to_epoch(date)
                pl_record["expires"] = expires

        elif type == "node":
            if not "hostname" in pl_record:
                # fetch from sfa_record
                if "hostname" not in sfa_record:
                    raise MissingSfaInfo("hostname")
                pl_record["hostname"] = sfa_record["hostname"]
            if "model" in sfa_record:
                pl_record["model"] = sfa_record["model"]
            else:
                pl_record["model"] = "geni"

        elif type == "authority":
            pl_record["login_base"] = PlXrn(xrn=hrn,
                                            type='authority').pl_login_base()
            if "name" not in sfa_record:
                pl_record["name"] = hrn
            if "abbreviated_name" not in sfa_record:
                pl_record["abbreviated_name"] = hrn
            if "enabled" not in sfa_record:
                pl_record["enabled"] = True
            if "is_public" not in sfa_record:
                pl_record["is_public"] = True

        return pl_record
Ejemplo n.º 14
0
    def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):

        pl_record = {}
 
        if type == "slice":
            pl_record["name"] = hrn_to_pl_slicename(hrn)
            if "instantiation" in sfa_record:
                pl_record['instantiation']=sfa_record['instantiation']
            else:
                pl_record["instantiation"] = "plc-instantiated"
	    if "url" in sfa_record:
               pl_record["url"] = sfa_record["url"]
	    if "description" in sfa_record:
	        pl_record["description"] = sfa_record["description"]
            if "expires" in sfa_record:
                date = utcparse(sfa_record['expires'])
                expires = datetime_to_epoch(date)
                pl_record["expires"] = expires

        elif type == "node":
            if not "hostname" in pl_record:
                # fetch from sfa_record
                if "hostname" not in sfa_record:
                    raise MissingSfaInfo("hostname")
                pl_record["hostname"] = sfa_record["hostname"]
            if "model" in sfa_record: 
                pl_record["model"] = sfa_record["model"]
            else:
                pl_record["model"] = "geni"

        elif type == "authority":
            pl_record["login_base"] = PlXrn(xrn=hrn,type='authority').pl_login_base()
            if "name" not in sfa_record:
                pl_record["name"] = hrn
            if "abbreviated_name" not in sfa_record:
                pl_record["abbreviated_name"] = hrn
            if "enabled" not in sfa_record:
                pl_record["enabled"] = True
            if "is_public" not in sfa_record:
                pl_record["is_public"] = True

        return pl_record
Ejemplo n.º 15
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        filter = {'hrn': hrn}
        if type:
            filter['type'] = type
        record = dbsession.query(RegRecord).filter_by(**filter).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s" % (hrn, type))

        # verify_cancreate_credential requires that the member lists
        # (researchers, pis, etc) be filled in
        logger.debug("get credential before augment dict, keys=%s" %
                     record.__dict__.keys())
        self.driver.augment_records_with_testbed_info(record.__dict__)
        logger.debug("get credential after augment dict, keys=%s" %
                     record.__dict__.keys())
        if not self.driver.is_enabled(record.__dict__):
            raise AccountNotEnabled(
                ": PlanetLab account %s is not enabled. Please contact your site PI"
                % (record.email))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            caller_filter = {'hrn': caller_hrn}
            if caller_type:
                caller_filter['type'] = caller_type
            caller_record = dbsession.query(RegRecord).filter_by(
                **caller_filter).first()
            if not caller_record:
                raise RecordNotFound(
                    "Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"
                    % (caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)

        object_hrn = record.get_gid_object().get_hrn()
        rights = api.auth.determine_user_rights(caller_hrn, record.todict())
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError(caller_hrn + " has no rights to " +
                                  record.hrn)

        object_gid = GID(string=record.gid)
        new_cred = Credential(subject=object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(),
                                 auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record, 'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
Ejemplo n.º 16
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        filter = {"hrn": hrn}
        if type:
            filter["type"] = type
        record = dbsession.query(RegRecord).filter_by(**filter).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s" % (hrn, type))

        # verify_cancreate_credential requires that the member lists
        # (researchers, pis, etc) be filled in
        logger.debug("get credential before augment dict, keys=%s" % record.__dict__.keys())
        api.driver.augment_records_with_testbed_info(record.__dict__)
        logger.debug("get credential after augment dict, keys=%s" % record.__dict__.keys())
        if not api.driver.is_enabled(record.__dict__):
            raise AccountNotEnabled(
                ": PlanetLab account %s is not enabled. Please contact your site PI" % (record.email)
            )

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            caller_filter = {"hrn": caller_hrn}
            if caller_type:
                caller_filter["type"] = caller_type
            caller_record = dbsession.query(RegRecord).filter_by(**caller_filter).first()
            if not caller_record:
                raise RecordNotFound(
                    "Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"
                    % (caller_hrn, caller_type, hrn, type)
                )
            caller_gid = GID(string=caller_record.gid)

        object_hrn = record.get_gid_object().get_hrn()
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError(caller_hrn + " has no rights to " + record.hrn)

        object_gid = GID(string=record.gid)
        new_cred = Credential(subject=object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        # new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record, "expires"):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        # new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)