wiki:KeyRingProposal

Version 1 (modified by exarkun, 6 years ago) (diff)

--

Prior Art

  1. gnome-keyring - password keyring
  2. ssh-agent - SSH key ring
  3. Apple Keychain

Goal

  1. To create an API by which applications acting as clients may authenticate themselves against servers without concerning themselves with the details of how the authentication is performed.
  2. To centralize the storage and representation of credentials for use by clients.
  3. To integrate with platform keyring services to be able to load credentials which have already been supplied by a user for general use on a system.

API

(incomplete, probably partially inconsistent)

class IKey(Interface):
    """
    Represents one authentication credentials for a specific 
    """


class IRemoteHost(Interface):
    host = Attribute()
    port = Attribute()


class IRemoteHTTP(IRemoteHost):
    realm = Attribute()


class IScope(Interface):
    def includes(remote):
        pass


class IKeyRing(Interface):
    """
    Represent one or more authentication credentials for a particular client-user-facing account identifier.
    """
    avatarId = Attribute("The client-user-facing account identifier to which all keys in this ring belong.")

    def add(key, scope):
        """
        Add a new key to this ring.
        @param key: An IKey provider
        """


    def remove(key, scope):
        pass


    def find(interface, remote):
        """
        Return all keys which provide the given interface and which are for the given remote system.

        remote is an object describing the location of the remote system.  It should be used by `IScope.includes` to decide if a particular key should be returned.
        """


class HostScope(object):
    implements(IScope):

    def __init__(self, name):
        self._name = name

    def includes(self, remote):
        remote = IRemoteHost(remote, None)
        if remote is None:
            return False
        return remote.host == self._name


class HTTPRealmScope(object):
    implements(IScope)

    def __init__(self, host, port, realm):
        self._host = host
        self._port = port
        self._realm = realm

    def includes(self, remote):
        remote = IRemoteHTTP(remote, None)
        if remote is None:
            return None
        return remote.host == self._host and remote.port == self._port and remote.realm == self._realm


if __name__ == '__main__':
    rings = RingCollection(GnomeKeyRing(), SSHKeyAgent())
    POP3Client().login("exarkun", rings.get("exarkun")