diff --git a/funkwhale_cli/cli.py b/funkwhale_cli/cli.py
index 12bc25f09459f519405cfcfb96526a9e8560e770..fa892e39452385d8c852b857925d93a4a7ad6fb2 100644
--- a/funkwhale_cli/cli.py
+++ b/funkwhale_cli/cli.py
@@ -88,6 +88,35 @@ RAW_DECORATOR = click.option(
     "--raw", is_flag=True, help="Directly output JSON returned by the happy"
 )
 
+class lazy_credential():
+    """
+    A proxy object to request access to the proxy object at the later possible point,
+    cf #4
+    """
+    def __init__(self, *args):
+        self.args = args
+        self._cached_value = None
+
+    @property
+    def value(self):
+        if self._cached_value:
+            return self._cached_value
+        v = keyring.get_password(*self.args)
+        self._cached_value = v
+        return v
+
+    def __str__(self):
+        return str(self.value)
+
+    def __eq__(self, other):
+        return self.value == other
+
+    def __repr__(self):
+        return str(self.value)
+
+    def __bool__(self):
+        return bool(self.value)
+
 
 def set_server(ctx, url, token):
     ctx.ensure_object(dict)
@@ -96,7 +125,7 @@ def set_server(ctx, url, token):
     ctx.obj["SERVER_NETLOC"] = parsed.netloc
     ctx.obj["SERVER_PROTOCOL"] = parsed.scheme
     try:
-        token = token or keyring.get_password(url, "_")
+        token = token or lazy_credential(url, "_")
     except ValueError as e:
         raise click.ClickException("Error while retrieving password from keyring: {}. Your password may be incorrect.".format(e.args[0]))
     except Exception as e:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 4697133d04ea6fde038f95f64fc87c991edcf035..5ba5983e60299ae160843daab6884208a5fb1c69 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -1,5 +1,6 @@
 import pytest
 import click
+import keyring
 
 from funkwhale_cli import api
 from funkwhale_cli import cli
@@ -61,3 +62,20 @@ def test_delete_command(group, cli_ctx, session, responses):
 )
 def test_get_pagination_data(input, output):
     assert cli.get_pagination_data(input) == output
+
+
+def test_lazy_credential(mocker):
+    get_password = mocker.patch("keyring.get_password", return_value="password")
+    credential = cli.lazy_credential("http://testurl", "_")
+
+    get_password.assert_not_called()
+
+    str(credential)
+
+    get_password.assert_called_once_with("http://testurl", "_")
+
+    assert credential == "password"
+
+    # result is cached
+    str(credential)
+    assert get_password.call_count == 1