Very nice branch Gary, thank you! LGTM (with some comments below), and QA ok! To QA this branch I deployed the charm in a local environment using "make deploy" and then I successfully run this script: http://pastebin.ubuntu.com/6473403/ https://codereview.appspot.com/31290043/diff/30001/server/guiserver/auth.py File server/guiserver/auth.py (right): https://codereview.appspot.com/31290043/diff/30001/server/guiserver/auth.py#newcode27 server/guiserver/auth.py:27: - login_succeeded(data) -> bool. - make_request(request_id, username, password) -> dict https://codereview.appspot.com/31290043/diff/30001/server/guiserver/auth.py#newcode29 server/guiserver/auth.py:29: requests' data based on the API implementation currently in use. Backends They can also be used to create authentication requests... or similar? https://codereview.appspot.com/31290043/diff/30001/server/guiserver/auth.py#newcode36 server/guiserver/auth.py:36: if the authentication succeeds. Since this docstring summarizes the purposes of objects in this module, it would be nice to provide some info about the AuthenticationTokenHandler here. https://codereview.appspot.com/31290043/diff/30001/server/guiserver/auth.py#newcode198 server/guiserver/auth.py:198: def make_request(self, request_id, username, password): """Create and return an authentication request."""? https://codereview.appspot.com/31290043/diff/30001/server/guiserver/auth.py#newcode349 server/guiserver/auth.py:349: def expire_token(): I know this is pre-existing code, but what do you think about logging the token expiration here? https://codereview.appspot.com/31290043/diff/30001/server/guiserver/auth.py#newcode385 server/guiserver/auth.py:385: if credentials is not None: ... and maybe here we could log the fact that someone is actually using the token? https://codereview.appspot.com/31290043/diff/30001/server/guiserver/handlers.py File server/guiserver/handlers.py (right): https://codereview.appspot.com/31290043/diff/30001/server/guiserver/handlers.py#newcode157 server/guiserver/handlers.py:157: elif self.tokens.token_requested(data): A token request is only handled by the guiserver if the user is authenticated. This means that a GUIToken Create request from an "anonymous" client is propagated to juju-core, and the response will be something like this: { 'RequestId': 0, 'Error': 'unknown object type "GUIToken"', 'Response': {}, } This can be ok but seems confusing from the client perspective; what we might want to send back is probably something like "unauthorized access: no user logged in". The quick fix is to always check if a token is requested (s/elif/if, similar to what already done with deployer requests at line 145) and ensure the user is authenticated in the process_token_request method itself, returning a response or an error accordingly. Of course this can be done (if you agree with the proposed change) in another branch. https://codereview.appspot.com/31290043/diff/30001/server/guiserver/tests/test_auth.py File server/guiserver/tests/test_auth.py (right): https://codereview.appspot.com/31290043/diff/30001/server/guiserver/tests/test_auth.py#newcode151 server/guiserver/tests/test_auth.py:151: def test_token_login_request(self): Great tests! https://codereview.appspot.com/31290043/