docs: def gpg_sign( path_to_sign, sender_key_info, config_dir=None, passphrase=None ):
      """
      Sign a file on disk.
      @sender_key_info should be a dict with
      {
          'key_id': ...
          'key_data': ...
          'app_name': ...
      }
      Return {'status': True, 'sig': ...} on success
      Return {'error': ...} on error
      """
  
      if config_dir is None:
          config_dir = get_config_dir()
  
      # ingest keys 
      tmpdir = make_gpg_tmphome( prefix="sign", config_dir=config_dir )
  
      try:
          sender_privkey = gpg_export_key( sender_key_info['app_name'], sender_key_info['key_id'], include_private=True, config_dir=config_dir )
      except Exception, e:
          log.exception(e)
          shutil.rmtree(tmpdir)
          return {'error': 'No such private key'}
  
      res = gpg_stash_key( "sign", sender_privkey, config_dir=config_dir, gpghome=tmpdir )
      if res is None:
          shutil.rmtree(tmpdir)
          return {'error': 'Failed to load sender private key'}
  
      # do the signature
      gpg = gnupg.GPG( homedir=tmpdir )
      res = None
  
      with open(path_to_sign, "r") as fd_in:
          res = gpg.sign_file( fd_in, keyid=sender_key_info['key_id'], passphrase=passphrase, detach=True )
  
      shutil.rmtree(tmpdir)
  
      if not res:
          log.debug("sign_file error: %s" % res.__dict__)
          log.debug("signer: %s" % sender_key_info['key_id'])
          return {'error': 'Failed to sign data'}
      
      return {'status': True, 'sig': res.data }