diff --git a/src/args.rs b/src/args.rs
index a4db68e74752d76f1897ac3f362308e49b1dc391..20b8b0d68c47593dd50567672052218014e756ca 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -11,6 +11,7 @@ use thiserror::Error;
 use crate::failure_domain::FailureDomain;
 use crate::instance::InstanceId;
 use crate::replicaset::ReplicasetId;
+use crate::schema::AuthMethod;
 use crate::util::Uppercase;
 
 #[derive(Debug, Parser)]
@@ -316,13 +317,23 @@ pub struct Connect {
     #[clap(
         short = 'u',
         long = "user",
-        value_name = "user",
+        value_name = "USER",
         default_value = "guest",
         env = "PICODATA_USER"
     )]
     /// The username to connect with. Ignored if provided in <ADDRESS>.
     pub user: String,
 
+    #[clap(
+        short = 'a',
+        long = "auth-type",
+        value_name = "METHOD",
+        default_value = AuthMethod::ChapSha1.as_str(),
+        arg_enum,
+    )]
+    /// The preferred authentication method.
+    pub auth_method: AuthMethod,
+
     #[clap(value_name = "ADDRESS")]
     /// Picodata instance address. Format: `[user@][host][:port]`
     pub address: Address,
diff --git a/src/luamod.lua b/src/luamod.lua
index 3c2f6eb94032929f94ad573ae681ec4a310460f1..f7237aedb3daf0dac9d3b1c76bfefc7f5c0f5fdb 100644
--- a/src/luamod.lua
+++ b/src/luamod.lua
@@ -191,6 +191,7 @@ Params:
     2. password (string)
     3. opts (table)
         - timeout (number), seconds
+        - auth_type (string)
 
 Returns:
 
@@ -203,7 +204,10 @@ function pico.create_user(user, password, opts)
         box.internal.check_param(user, 'user', 'string')
         box.internal.check_param(password, 'password', 'string')
         -- TODO: check password requirements.
-        box.internal.check_param_table(opts, { timeout = 'number' })
+        box.internal.check_param_table(opts, {
+            timeout = 'number',
+            auth_type = 'string',
+        })
         opts = opts or {}
         if not opts.timeout then
             box.error(box.error.ILLEGAL_PARAMS, 'opts.timeout is mandatory')
@@ -217,7 +221,7 @@ function pico.create_user(user, password, opts)
 
     -- XXX: we construct this closure every time the function is called,
     -- which is bad for performance/jit. Refactor if problems are discovered.
-    local auth_type = box.cfg.auth_type
+    local auth_type = opts.auth_type or box.cfg.auth_type
     local auth_data = box.internal.prepare_auth(auth_type, password, user)
     local function make_op_if_needed()
         local grantee_def = box.space._user.index.name:get(user)
@@ -270,6 +274,7 @@ Params:
     2. password (string)
     3. opts (table)
         - timeout (number), seconds
+        - auth_type (string)
 
 Returns:
 
@@ -281,7 +286,10 @@ function pico.change_password(user, password, opts)
     local ok, err = pcall(function()
         box.internal.check_param(user, 'user', 'string')
         box.internal.check_param(password, 'password', 'string')
-        box.internal.check_param_table(opts, { timeout = 'number' })
+        box.internal.check_param_table(opts, {
+            timeout = 'number',
+            auth_type = 'string',
+        })
         opts = opts or {}
         if not opts.timeout then
             box.error(box.error.ILLEGAL_PARAMS, 'opts.timeout is mandatory')
@@ -297,7 +305,7 @@ function pico.change_password(user, password, opts)
 
     -- XXX: we construct this closure every time the function is called,
     -- which is bad for performance/jit. Refactor if problems are discovered.
-    local auth_type = box.cfg.auth_type
+    local auth_type = opts.auth_type or box.cfg.auth_type
     local auth_data = box.internal.prepare_auth(auth_type, password, user)
     local function make_op_if_needed()
         -- TODO: allow `user` to be a user id instead of name
diff --git a/src/main.rs b/src/main.rs
index adcfc12c1cda24a3a026d181100e3fdb3240fdf2..191e8baf575b6ea8b2c36b7fe93ca815744827d9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -254,8 +254,8 @@ fn main_connect(args: args::Connect) -> ! {
     };
 
     let address = format!(
-        "{user}:{password}@{}:{}",
-        args.address.host, args.address.port
+        "{user}:{password}@{}:{}?auth_type={}",
+        args.address.host, args.address.port, args.auth_method
     );
 
     let rc = tarantool_main!(
diff --git a/src/schema.rs b/src/schema.rs
index f63b8c10c61f9afa5c7a0798660fb45da702dd11..3c9e3e9df836cd7050874d57a1e4a39947e81286 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -196,6 +196,7 @@ pub struct AuthDef {
 }
 
 ::tarantool::define_str_enum! {
+    #[derive(clap::ArgEnum)]
     pub enum AuthMethod {
         ChapSha1 = "chap-sha1",
         MD5 = "md5",
diff --git a/tarantool-sys b/tarantool-sys
index 4056a2006d93e2cd8a96a52b689deacab640d48e..ea487f51c1b7ad2e6d6731e64958b37041d82395 160000
--- a/tarantool-sys
+++ b/tarantool-sys
@@ -1 +1 @@
-Subproject commit 4056a2006d93e2cd8a96a52b689deacab640d48e
+Subproject commit ea487f51c1b7ad2e6d6731e64958b37041d82395
diff --git a/test/int/test_cli_connect.py b/test/int/test_cli_connect.py
index 411c822c67193c40cee8c56b9b8e20c75833bcea..68527813529b4a24acbd75b41074dbc7072f9b03 100644
--- a/test/int/test_cli_connect.py
+++ b/test/int/test_cli_connect.py
@@ -162,3 +162,61 @@ def test_connection_refused(binary_path: str):
 
     cli.expect_exact("Connection is not established")
     cli.expect_exact(pexpect.EOF)
+
+
+def test_connect_auth_type_ok(i1: Instance):
+    cli = pexpect.spawn(
+        command=i1.binary_path,
+        args=["connect", f"{i1.host}:{i1.port}", "-u", "testuser", "-a", "chap-sha1"],
+        encoding="utf-8",
+        timeout=1,
+    )
+    cli.logfile = sys.stdout
+
+    cli.expect_exact("Enter password for testuser: ")
+    cli.sendline("testpass")
+
+    cli.expect_exact(f"connected to {i1.host}:{i1.port}")
+    cli.expect_exact(f"{i1.host}:{i1.port}>")
+
+    cli.sendline("box.session.user()")
+    cli.expect_exact("---\r\n")
+    cli.expect_exact("- testuser\r\n")
+    cli.expect_exact("...\r\n")
+    cli.expect_exact("\r\n")
+
+    eprint("^D")
+    cli.sendcontrol("d")
+    cli.expect_exact(pexpect.EOF)
+
+
+def test_connect_auth_type_different(i1: Instance):
+    cli = pexpect.spawn(
+        command=i1.binary_path,
+        args=["connect", f"{i1.host}:{i1.port}", "-u", "testuser", "-a", "chap-sha1"],
+        encoding="utf-8",
+        timeout=1,
+    )
+    cli.logfile = sys.stdout
+
+    cli.expect_exact("Enter password for testuser: ")
+    cli.sendline("")
+
+    cli.expect_exact("Connection is not established")
+    cli.expect_exact(pexpect.EOF)
+
+
+def test_connect_auth_type_unknown(binary_path: str):
+    cli = pexpect.spawn(
+        command=binary_path,
+        args=["connect", ":0", "-u", "testuser", "-a", "deadbeef"],
+        env={"NO_COLOR": "1"},
+        encoding="utf-8",
+        timeout=1,
+    )
+    cli.logfile = sys.stdout
+
+    cli.expect_exact(
+        "error: \"deadbeef\" isn't a valid value for '--auth-type <METHOD>"
+    )
+    cli.expect_exact(pexpect.EOF)