diff --git a/troveclient/auth_plugin.py b/troveclient/auth_plugin.py
new file mode 100644
index 00000000..e8a7d976
--- /dev/null
+++ b/troveclient/auth_plugin.py
@@ -0,0 +1,107 @@
+# Copyright 2014 Rackspace
+# Copyright 2013 OpenStack Foundation
+# Copyright 2013 Spanish National Research Council.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import logging
+
+import pkg_resources
+import six
+
+from troveclient import exceptions
+from troveclient.openstack.common.gettextutils import _  # noqa
+
+
+logger = logging.getLogger(__name__)
+
+
+_discovered_plugins = {}
+
+
+def discover_auth_systems():
+    """Discover the available auth-systems.
+
+    This won't take into account the old style auth-systems.
+    """
+    ep_name = 'openstack.client.auth_plugin'
+    for ep in pkg_resources.iter_entry_points(ep_name):
+        try:
+            auth_plugin = ep.load()
+        except (ImportError, pkg_resources.UnknownExtra, AttributeError) as e:
+            logger.debug(_("ERROR: Cannot load auth plugin %s") % ep.name)
+            logger.debug(e, exc_info=1)
+        else:
+            _discovered_plugins[ep.name] = auth_plugin
+
+
+def load_auth_system_opts(parser):
+    """Load options needed by the available auth-systems into a parser.
+
+    This function will try to populate the parser with options from the
+    available plugins.
+    """
+    for name, auth_plugin in six.iteritems(_discovered_plugins):
+        add_opts_fn = getattr(auth_plugin, "add_opts", None)
+        if add_opts_fn:
+            group = parser.add_argument_group("Auth-system '%s' options" %
+                                              name)
+            add_opts_fn(group)
+
+
+def load_plugin(auth_system):
+    if auth_system in _discovered_plugins:
+        return _discovered_plugins[auth_system]()
+
+    raise exceptions.AuthSystemNotFound(auth_system)
+
+
+class BaseAuthPlugin(object):
+    """Base class for authentication plugins.
+
+    An authentication plugin needs to override at least the authenticate
+    method to be a valid plugin.
+    """
+    def __init__(self):
+        self.opts = {}
+
+    def get_auth_url(self):
+        """Return the auth url for the plugin (if any)."""
+        return None
+
+    @staticmethod
+    def add_opts(parser):
+        """Populate and return the parser with the options for this plugin.
+
+        If the plugin does not need any options, it should return the same
+        parser untouched.
+        """
+        return parser
+
+    def parse_opts(self, args):
+        """Parse the actual auth-system options if any.
+
+        This method is expected to populate the attribute self.opts with a
+        dict containing the options and values needed to make authentication.
+        If the dict is empty, the client should assume that it needs the same
+        options as the 'keystone' auth system (i.e. os_username and
+        os_password).
+
+        Returns the self.opts dict.
+        """
+        return self.opts
+
+    def authenticate(self, cls, auth_url):
+        """Authenticate using plugin defined method."""
+        raise exceptions.AuthSystemNotFound(self.auth_system)
diff --git a/troveclient/client.py b/troveclient/client.py
index d9dcc48f..ecfaf598 100644
--- a/troveclient/client.py
+++ b/troveclient/client.py
@@ -22,7 +22,6 @@ OpenStack Client interface. Handles the REST calls and responses.
 from __future__ import print_function
 
 import logging
-import os
 import requests
 
 from keystoneclient import adapter
@@ -89,7 +88,16 @@ class HTTPClient(TroveClientMixin):
         self.password = password
         self.projectid = projectid
         self.tenant_id = tenant_id
-        self.auth_url = auth_url.rstrip('/')
+
+        if auth_system and auth_system != 'keystone' and not auth_plugin:
+            raise exceptions.AuthSystemNotFound(auth_system)
+
+        if not auth_url and auth_system and auth_system != 'keystone':
+            auth_url = auth_plugin.get_auth_url()
+            if not auth_url:
+                raise exceptions.EndpointNotFound()
+
+        self.auth_url = auth_url.rstrip('/') if auth_url else auth_url
         self.version = 'v1'
         self.region_name = region_name
         self.endpoint_type = endpoint_type
@@ -105,6 +113,8 @@ class HTTPClient(TroveClientMixin):
         self.proxy_tenant_id = proxy_tenant_id
         self.timeout = timeout
         self.bypass_url = bypass_url
+        self.auth_system = auth_system
+        self.auth_plugin = auth_plugin
 
         if insecure:
             self.verify_cert = False
@@ -326,10 +336,10 @@ class HTTPClient(TroveClientMixin):
         auth_url = self.auth_url
         if self.version == "v2.0":
             while auth_url:
-                if "TROVE_RAX_AUTH" in os.environ:
-                    auth_url = self._rax_auth(auth_url)
-                else:
+                if not self.auth_system or self.auth_system == 'keystone':
                     auth_url = self._v2_auth(auth_url)
+                else:
+                    auth_url = self._plugin_auth(auth_url)
 
             # Are we acting on behalf of another user via an
             # existing token? If so, our actual endpoints may
@@ -357,6 +367,9 @@ class HTTPClient(TroveClientMixin):
         if self.bypass_url is not None and self.bypass_url != '':
             self.management_url = self.bypass_url
 
+    def _plugin_auth(self, auth_url):
+        return self.auth_plugin.authenticate(self, auth_url)
+
     def _v1_auth(self, url):
         if self.proxy_token:
             raise exceptions.NoTokenLookupException()
@@ -393,16 +406,6 @@ class HTTPClient(TroveClientMixin):
 
         self._authenticate(url, body)
 
-    def _rax_auth(self, url):
-        """Authenticate against the Rackspace auth service."""
-        body = {"auth": {
-                "RAX-KSKEY:apiKeyCredentials": {
-                    "username": self.user,
-                    "apiKey": self.password,
-                    "tenantName": self.projectid}}}
-
-        self._authenticate(url, body)
-
     def _authenticate(self, url, body):
         """Authenticate and extract the service catalog."""
         token_url = url + "/tokens"
diff --git a/troveclient/shell.py b/troveclient/shell.py
index 3738d30d..fb8d4269 100644
--- a/troveclient/shell.py
+++ b/troveclient/shell.py
@@ -21,6 +21,7 @@ Command-line interface to the OpenStack Trove API.
 from __future__ import print_function
 
 import argparse
+import getpass
 import glob
 import imp
 import itertools
@@ -38,9 +39,9 @@ from keystoneclient.auth.identity import v3 as identity
 from keystoneclient import session as ks_session
 
 import troveclient
-import troveclient.extension
-
+import troveclient.auth_plugin
 from troveclient import client
+import troveclient.extension
 from troveclient.openstack.common.apiclient import exceptions as exc
 from troveclient.openstack.common import gettextutils as gtu
 from troveclient.openstack.common.gettextutils import _  # noqa
@@ -107,7 +108,10 @@ class OpenStackTroveShell(object):
 
         parser.add_argument('--os-auth-system',
                             metavar='<auth-system>',
-                            default=utils.env('OS_AUTH_SYSTEM'))
+                            default=utils.env('OS_AUTH_SYSTEM'),
+                            help='Defaults to env[OS_AUTH_SYSTEM].')
+        parser.add_argument('--os_auth_system',
+                            help=argparse.SUPPRESS)
 
         parser.add_argument('--service-type',
                             metavar='<service-type>',
@@ -175,6 +179,9 @@ class OpenStackTroveShell(object):
 
         self._append_global_identity_args(parser)
 
+        # The auth-system-plugins might require some extra options
+        troveclient.auth_plugin.load_auth_system_opts(parser)
+
         return parser
 
     def _append_global_identity_args(self, parser):
@@ -332,6 +339,9 @@ class OpenStackTroveShell(object):
         self.setup_debugging(options.debug)
         self.options = options
 
+        # Discover available auth plugins
+        troveclient.auth_plugin.discover_auth_systems()
+
         # build available subcommands based on version
         self.extensions = self._discover_extensions(
             options.os_database_api_version)
@@ -356,17 +366,20 @@ class OpenStackTroveShell(object):
             self.do_bash_completion(args)
             return 0
 
-        (os_username, os_password, os_tenant_name, os_auth_url,
-         os_region_name, os_tenant_id, endpoint_type, insecure,
-         service_type, service_name, database_service_name,
-         cacert, bypass_url, os_auth_system) = (
-             args.os_username, args.os_password,
-             args.os_tenant_name, args.os_auth_url,
-             args.os_region_name, args.os_tenant_id,
-             args.endpoint_type, args.insecure,
-             args.service_type, args.service_name,
-             args.database_service_name,
-             args.os_cacert, args.bypass_url, args.os_auth_system)
+        os_username = args.os_username
+        os_password = args.os_password
+        os_tenant_name = args.os_tenant_name
+        os_auth_url = args.os_auth_url
+        os_region_name = args.os_region_name
+        os_tenant_id = args.os_tenant_id
+        os_auth_system = args.os_auth_system
+        endpoint_type = args.endpoint_type
+        insecure = args.insecure
+        service_type = args.service_type
+        service_name = args.service_name
+        database_service_name = args.database_service_name
+        cacert = args.os_cacert
+        bypass_url = args.bypass_url
 
         if os_auth_system and os_auth_system != "keystone":
             auth_plugin = troveclient.auth_plugin.load_plugin(os_auth_system)
@@ -384,20 +397,22 @@ class OpenStackTroveShell(object):
         # for os_username or os_password but for compatibility it is not.
 
         if not utils.isunauthenticated(args.func):
-            if not os_username:
-                raise exc.CommandError(
-                    "You must provide a username "
-                    "via either --os-username or env[OS_USERNAME]")
+
+            if auth_plugin:
+                auth_plugin.parse_opts(args)
+
+            if not auth_plugin or not auth_plugin.opts:
+                if not os_username:
+                    raise exc.CommandError(
+                        "You must provide a username "
+                        "via either --os-username or env[OS_USERNAME]")
 
             if not os_password:
-                raise exc.CommandError("You must provide a password "
-                                       "via either --os-password or via "
-                                       "env[OS_PASSWORD]")
+                os_password = getpass.getpass()
 
             if not os_auth_url:
-                raise exc.CommandError(
-                    "You must provide an auth url "
-                    "via either --os-auth-url or env[OS_AUTH_URL]")
+                if os_auth_system and os_auth_system != 'keystone':
+                    os_auth_url = auth_plugin.get_auth_url()
 
         # V3 stuff
         project_info_provided = (self.options.os_tenant_name or
@@ -422,9 +437,12 @@ class OpenStackTroveShell(object):
                   "(env[OS_PROJECT_DOMAIN_NAME])"))
 
         if not os_auth_url:
-            raise exc.CommandError(
-                "You must provide an auth url "
-                "via either --os-auth-url or env[OS_AUTH_URL]")
+            raise exc.CommandError("You must provide an auth url "
+                                   "via either --os-auth-url or "
+                                   "env[OS_AUTH_URL] or specify an "
+                                   "auth_system which defines a default "
+                                   "url with --os-auth-system or "
+                                   "env[OS_AUTH_SYSTEM]")
 
         use_session = True
         if auth_plugin or bypass_url:
diff --git a/troveclient/tests/test_shell.py b/troveclient/tests/test_shell.py
index aaca9e16..853f2a4b 100644
--- a/troveclient/tests/test_shell.py
+++ b/troveclient/tests/test_shell.py
@@ -150,7 +150,9 @@ class ShellTest(testtools.TestCase):
 
     def test_no_auth_url(self):
         required = ('You must provide an auth url'
-                    ' via either --os-auth-url or env[OS_AUTH_URL]',)
+                    ' via either --os-auth-url or env[OS_AUTH_URL] '
+                    'or specify an auth_system which defines a default '
+                    'url with --os-auth-system or env[OS_AUTH_SYSTEM]',)
         self.make_env(exclude='OS_AUTH_URL')
         try:
             self.shell('list')