diff --git a/pybis/src/python/pybis/cli.py b/pybis/src/python/pybis/cli.py
index 6ec697a081b498aa123909a399ddbbc0cc361be8..ba713c36a5135efd76219db0a5d3c9b4881eae47 100644
--- a/pybis/src/python/pybis/cli.py
+++ b/pybis/src/python/pybis/cli.py
@@ -56,17 +56,19 @@ def get_openbis(
     1. direct specification via --hostname https://openbis.domain
     2. Environment variable: OPENBIS_HOST=https://openbis.domain
     3. local pybis configuration (hostname.pybis.json)
-    4. local obis configuration (in .obis)
-    5. global pybis configuration (~/.pybis/hostname.pybis.json)
-    6.
+    4. global pybis configuration (~/.pybis/hostname.pybis.json)
+    5. prompt for hostname
     """
 
-    config = pybis.get_local_config()
+    config_local = pybis.get_local_config()
+    config_global = pybis.get_global_config()
 
     if not hostname:
         hostname = os.getenv("OPENBIS_HOSTNAME")
     if not hostname:
-        hostname = config.get("hostname")
+        hostname = config_local.get("hostname")
+    if not hostname:
+        hostname = config_global.get("hostname")
     if not hostname:
         hostname = click.prompt("openBIS hostname")
 
@@ -435,30 +437,74 @@ def download_dataset(permid, destination, fileno, **kwargs):
     )
 
 
-@cli.command("local", context_settings=dict(ignore_unknown_options=True))
-@click.argument("hostname", required=False)
+@cli.group()
+@click.pass_obj
+def config(ctx):
+    """manage openBIS configurations"""
+    pass
+
+
+@config.group("local")
+@click.pass_obj
+def local_config(ctx):
+    """get or set local openBIS configurations"""
+    pass
+
+
+@local_config.command("get")
+@click.pass_obj
+def get_local_config(ctx):
+    config = pybis.get_local_config()
+    if config is None:
+        raise click.ClickException("No local configuration found.")
+    click.echo(
+        tabulate(
+            [[config.get("hostname", ""), config.get("token", "")]],
+            headers=["openBIS hostname", "token"],
+        )
+    )
+
+
+@local_config.command("set")
+@click.argument("hostname")
 @click.argument("token", required=False, type=click.UNPROCESSED)
-@click.option("--info", is_flag=True, help="get more detailed information")
-def get_set_hostname(hostname, token, info):
-    """show or set hostname and token that is used locally."""
-    if hostname:
-        if token and token.startswith("-"):
-            token = "$pat" + token
-        pybis.set_local_config(hostname=hostname, token=token)
-    else:
-        # get hostname and token stored in .pybis.json
-        config = pybis.get_local_config()
-        if info:
-            o = pybis.Openbis(url=config.get("hostname", ""))
-            session_info = o.get_session_info(token=config.get("token"))
-            click.echo(session_info)
-        else:
-            click.echo(
-                tabulate(
-                    [[config.get("hostname", ""), config.get("token", "")]],
-                    headers=["openBIS hostname", "token"],
-                )
-            )
+def set_local_config(hostname, token):
+    try:
+        o = pybis.Openbis(url=hostname, token=token)
+    except Exception as exc:
+        raise click.ClickException(exc) from exc
+    pybis.set_local_config(hostname=hostname, token=token)
+
+
+@config.group("global")
+@click.pass_obj
+def global_config(ctx):
+    """get or set global openBIS configurations"""
+    pass
+
+
+@global_config.command("get")
+def get_global_config():
+    config = pybis.get_global_config()
+    if config is None:
+        raise click.ClickException("No global configuration found.")
+    click.echo(
+        tabulate(
+            [[config.get("hostname", ""), config.get("token", "")]],
+            headers=["openBIS hostname", "token"],
+        )
+    )
+
+
+@global_config.command("set")
+@click.argument("hostname")
+@click.argument("token", required=False, type=click.UNPROCESSED)
+def set_global_config(hostname, token):
+    try:
+        o = pybis.Openbis(url=hostname, token=token)
+    except Exception as exc:
+        raise click.ClickException(exc) from exc
+    pybis.set_global_config(hostname=hostname, token=token)
 
 
 @cli.group()
@@ -468,7 +514,30 @@ def token(ctx):
     pass
 
 
-@token.command("pats")
+@token.group("session")
+@click.pass_obj
+def session_token(ctx):
+    """manage openBIS Session Tokens"""
+    pass
+
+
+@session_token.command("list")
+@click.pass_obj
+def get_tokens(ctx, **kwargs):
+    """list stored openBIS Session Tokens"""
+    tokens = pybis.get_saved_tokens()
+    token_list = [[key, tokens[key]] for key in tokens]
+    click.echo(tabulate(token_list, headers=["openBIS hostname", "session token"]))
+
+
+@token.group("pat")
+@click.pass_obj
+def pat_token(ctx):
+    """manage openBIS Personal Access Tokens (PAT)"""
+    pass
+
+
+@pat_token.command("list")
 @click.argument("hostname", required=False)
 @click.argument("session-name", required=False)
 @click.pass_obj
@@ -490,23 +559,7 @@ def get_pats(ctx, hostname, session_name=None):
     )
 
 
-@token.command("session")
-@click.pass_obj
-def new_token(ctx, **kwargs):
-    """create new openBIS Session Token"""
-    click.echo("new_token()")
-
-
-@token.command("sessions")
-@click.pass_obj
-def get_tokens(ctx, **kwargs):
-    """list stored openBIS Session Tokens"""
-    tokens = pybis.get_saved_tokens()
-    token_list = [[key, tokens[key]] for key in tokens]
-    click.echo(tabulate(token_list, headers=["openBIS hostname", "session token"]))
-
-
-@token.command("pat")
+@pat_token.command("new")
 @login_options
 @click.argument("session-name")
 @click.option("--validity-days", help="Number of days the token is valid")
@@ -524,9 +577,11 @@ def new_pat(ctx, hostname, session_name, **kwargs):
         validTo += relativedelta(days=int(kwargs.get("validity_days")))
     else:
         validTo += relativedelta(years=1)
-    o = get_openbis(hostname=hostname, session_token_needed=True, **kwargs)
+    o = get_openbis(hostname=hostname, session_token_needed=True)
     try:
-        new_pat = o.new_personal_access_token(sessionName=session_name, validTo=validTo)
+        new_pat = o.get_or_create_personal_access_token(
+            sessionName=session_name, validTo=validTo
+        )
     except Exception as exc:
         raise click.ClickException(
             f"Creation of new personal access token failed: {exc}"