New Cred: Authentication for the 24th Century

Old Cred

Authentication in Twisted services comes from modules in the 'twisted.cred' package. The old API for authentication was complex, large, and did not handle multiple types of authentication well. The new API is much smaller and easier to use, and hopefully will be widely adopted outside of the Twisted internals.

The Portal

This is the ineffable mystery at the core of login. There is one concrete implementation of Portal, and no interface - it does a very simple task. A Portal associates one (1) Realm with a collection of CredentialChecker instances. (More on those later.)

The closest analogue of this in Old Cred was the Authorizer.

If you are writing a protocol that needs to authenticate against something, you will need a reference to a Portal, and to nothing else. This has only 2 methods -

login(credentials, mind, *interfaces)

The docstring is quite expansive (see twisted.cred.portal), but in brief, this is what you call when you need to call in order to connect a user to the system. The result is a deferred which fires a tuple of:

registerChecker(checker, *credentialInterfaces)

which adds a CredentialChecker to the portal.

The Mind

Masters of Perspective Broker already know this object as the ill-named client object. There is no mind class, or even interface, but it is an object which serves an important role - any notifications which are to be relayed to an authenticated client are passed through a 'mind'.

The name may seem rather unusual, but considering that a Mind is representative of the entity on the other end of a network connection that is both receiving updates and issuing commands, I believe it is appropriate.

Although many protocols will not use this, it serves an important role. It is provided as an argument both to the Portal and to the Realm, although a CredentialChecker should interact with a client program exclusively through a Credentials instance.

Unlike the original Perspective Broker client object, a Mind's implementation is most often dictated by the protocol that is connecting rather than the Realm. A Realm which requires a particular interface to issue notifications will need to wrap the Protocol's mind implementation with an adapter in order to get one that conforms to its expected interface - however, Perspective Broker will likely continue to use the model where the client object has a pre-specified remote interface.

(If you don't quite understand this, it's fine. It's hard to explain, and it's not used in simple usages of cred, so feel free to pass None until you find yourself requiring something like this.)

The CredentialChecker

This is an object which resolves some Credentials to an avatar ID. Some examples of CredentialChecker implementations would be: InMemoryUsernamePassword, ApacheStyleHTAccessFile, UNIXPasswordDatabase, SSHPublicKeyDatabase. A credential checker stipulates some requirements of the credentials it can check by specifying a credentialInterfaces attribute, which is a list of interfaces. Credentials passed to its requestAvatarId method must implement one of those interfaces.

For the most part, these things will just check usernames and passwords and produce the username as the result, but hopefully we will be seeing some public-key, challenge-response, and certificate based credential checker mechanisms soon.

A credential checker should raise an error if it cannot authenticate the user, and return twisted.cred.checkers.ANONYMOUS for anonymous access.

The Credentials

Oddly enough, this represents some credentials that the user presents. Usually this will just be a small static blob of data, but in some cases it will actually be an object connected to a network protocol. For example, a username/password pair is static, but a challenge/response server is an active state-machine that will require several method calls in order to determine a result.

The Realm

A realm is an interface which connects your universe of business objects to the authentication system. This is similar to the Old Cred Service, but the name Service will be phased out when referring to cred - another planned refactoring is to move twisted.internet.app.ApplicationService into its own module and more heavily emphasize its use in start-up and shut-down.

IRealm is another one-method interface: requestAvatar(avatarId, mind, *interfaces)

This method will typically be called from 'Portal.login'. The avatarId is the one returned by a CredentialChecker.

The important thing to realize about this method is that if it is being called, _the user has already authenticated_. Therefore, if possible, the Realm should create a new user if one does not already exist whenever possible. Of course, sometimes this will be impossible without more information, and that is the case that the interfaces argument is for.

Since requestAvatar should be called from a Deferred callback, it may return a Deferred or a synchronous result.

At the moment, there is only an interface for the Realm. However, it is expected that a utility class will be written in the near future to facilitate log-in methods, a re-directing method similar to Perspective.attached for Avatars, and at least somewhat automated compositing of Realms. However, in writing the code for cred and guard, there has been no need for such a thing yet.

The Avatar

This object has the dubious distinction of appearing nowhere in the code; in fact, very few things will ever touch an actual Avatar, and it is not clear that it will have an interface. However, _aspects_ of an avatar are returned in deferreds from the above methods, which is to say, things that implement particular interfaces which communicate with various protocols that may access your Realm.

This is (hopefully, obviously) similar to a 'Perspective'. However, an Avatar separates 2 concerns which were muddied previously - _access_ to a realm and _storage of user data_ within a realm. The avatar itself stores the data, and the aspects interface to it. The avatar itself may of course implement its own aspects, but it is suggested in most cases to register adapters that do this. (Perspective Broker will keep its name, because the Avatar Aspect that communicates with the remote object protocol will still be called a Perspective.)

TODO (hopefully) short example of using new cred to authenticate

TODO example of writing a new kind of authentication