# kdb user > Add, list and remove the users of the KDB server, set their passwords and roles, from the command line. - Category: Command line - Keywords: users, user management, reset-2fa, two-factor, add user, password, change password, reset password, role, admin, ddl, write, read, none, list users, remove user, delete user, first user, last admin, --role, pipe password, \_system - See also: [Users and roles](users-and-roles.md), [Keeping kdb serve safe](server-security.md), [kdb serve](cli-serve.md), [Logins, tokens and roles over HTTP](http-login.md) `kdb user` manages the **users of the server**: the people and programs that log in to `kdb serve` (the web console, the HTTP API, the PostgreSQL port). They are not the users of your app (for those, see [users and roles](users-and-roles.md)). - Users belong to the **data folder**. KDB keeps them in a hidden database `_system` inside it. Use `--data-dir ` (or `KDB_DATA_DIR`) to choose the data folder. - As soon as one user exists, the server asks every request for a login. - `kdb user` works only while `kdb serve` is **stopped**. While the server runs, it has the users open; use SQL in its console then (`CREATE USER`, `ALTER USER`, `DROP USER`, `SHOW USERS`, `GRANT`, `REVOKE`). - **Passwords are never given on the command line** (other users of the computer could see command lines). `kdb user add` and `kdb user passwd` ask for the password on the keyboard (the typed text is not shown, and you type it twice), or read one line from a pipe. | Role | May do | |---|---| | `none` | nothing, until a `GRANT` on a database | | `read` | `SELECT`, `SHOW`, `EXPLAIN`, CSV export, cursors, transactions | | `write` | everything of `read`, and `INSERT`, `UPDATE`, `DELETE`, `CALL`, the line protocol | | `admin` | everything, also `CREATE`/`ALTER`/`DROP`, `BACKUP`, `CHECK`, databases and users | A role given here is for **every** database. For one database only, use `GRANT ... ON DATABASE` in SQL. Details: [users and roles](users-and-roles.md). `kdb user reset-2fa ` turns [two-factor login](two-factor-login.md#kdb-user-reset-2fa) off for a user who lost the phone. ## kdb user add Syntax: ```sql kdb user add [--role admin|ddl|write|read|none] [--data-dir ] ``` Adds a user. The password is asked for, or read from a pipe. | Option | Meaning | Default | |---|---|---| | `` | Letters, digits, `_` and `-`, 1 to 63 characters. `Bob` and `bob` are the same user. | required | | `--role` | `admin`, `ddl`, `write`, `read` or `none` | `admin` for the first user, `none` for later users | | `--data-dir ` | The data folder that gets the user | `KDB_DATA_DIR`, else `data` next to kdb | - **Exit code:** `0` added; `1` for every error. - **The first user must be `admin`.** Otherwise nobody could manage users after the server starts asking for logins. - **Password:** at least 12 characters, not the user name, at most 1024 bytes. Long random passwords (20 characters or more, from a password manager) are best for programs. - Adding a user takes a moment: the password is hashed slowly on purpose (PBKDF2, 600,000 rounds), so a stolen copy is hard to guess. - **From a script:** pipe the password, for example `Get-Content admin-password.txt | kdb user add admin --role admin`. Keep that file readable only by you. **Command line: The first user, with the password from a pipe** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd ``` Output: ```text user 'admin' added with role admin in ./kdb-data ``` **Command line: More users: a report reader and an app with no role yet** ```bash kdb user add admin > Long-Admin-Passw0rd kdb user add report --role read > Reports-only-secret-7 kdb user add shop_app > Another-long-secret-42 kdb user list ``` Output: `> kdb user add admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user add report --role read` ```text user 'report' added with role read in ./kdb-data ``` `> kdb user add shop_app` ```text user 'shop_app' added with role none in ./kdb-data ``` `> kdb user list` ```text USER ROLE GRANTS CHANGED admin admin - 2026-10-22 11:28:33 report read - 2026-10-22 11:28:33 shop_app none - 2026-10-22 11:28:33 3 users in ./kdb-data ``` **Command line: The first user must be admin** ```bash kdb user add report --role read > Reports-only-secret-7 ``` Output: ```text error: Invalid argument: the first user must have ROLE admin (CREATE USER name WITH PASSWORD '...' ROLE admin): once a user exists the server asks for a login, and only an admin can manage users ``` exit code 1 **Command line: A password that is too short** ```bash kdb user add admin --role admin > short ``` Output: ```text error: the password is too short: use at least 12 characters (a password manager can make a long random one) ``` exit code 1 ```powershell # Typed on the keyboard (not run here) PS> kdb user add admin --role admin --data-dir E:\kdb-data New password: Type it again: user 'admin' added with role admin in E:/kdb-data ``` ```bash # Linux, as the kdb system user, password from a file only root can read (not run here) sudo cat /root/kdb-admin-password | sudo -u kdb kdb user add admin --role admin --data-dir /srv/kdb/data ``` ## kdb user passwd Syntax: ```sql kdb user passwd [--data-dir ] ``` Sets a new password for a user. The password is asked for, or read from a pipe. - **Exit code:** `0` set; `1` for every error (unknown user, short password, passwords not the same). - Every login of that user ends at once (web console sessions and `POST /api/login` tokens). They must log in again with the new password. - The new password is asked for before KDB looks for the user, so a wrong name is reported after you typed the password. - In SQL: `ALTER USER WITH PASSWORD '...'` (every user may change their own password). **Command line: A new password** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd kdb user passwd admin > Even-Longer-Admin-Passw0rd-2026 ``` Output: `> kdb user add admin --role admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user passwd admin` ```text new password set for user 'admin'; logins with the old password end ``` **Command line: An unknown user** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd kdb user passwd nobody > Some-long-password-1 ``` Output: `> kdb user add admin --role admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user passwd nobody` ```text error: Not found: user 'nobody' does not exist ``` exit code 1 ## kdb user role Syntax: ```sql kdb user role admin|ddl|write|read|none [--data-dir ] ``` Changes the role of a user. The role is for every database. - **Exit code:** `0` changed; `1` for every error. - **The last admin** cannot lose the admin role while other users exist. Make another user admin first. - In SQL: `ALTER USER ROLE write`. **Command line: Give the app the right to write** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd kdb user add shop_app > Another-long-secret-42 kdb user role shop_app write kdb user list ``` Output: `> kdb user add admin --role admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user add shop_app` ```text user 'shop_app' added with role none in ./kdb-data ``` `> kdb user role shop_app write` ```text user 'shop_app' now has role write ``` `> kdb user list` ```text USER ROLE GRANTS CHANGED admin admin - 2026-10-22 11:28:33 shop_app write - 2026-10-22 11:28:33 2 users in ./kdb-data ``` **Command line: The last admin keeps the role** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd kdb user add report --role read > Reports-only-secret-7 kdb user role admin read ``` Output: `> kdb user add admin --role admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user add report --role read` ```text user 'report' added with role read in ./kdb-data ``` `> kdb user role admin read` ```text error: Invalid argument: 'admin' is the last user with ROLE admin; make another user admin first (ALTER USER ROLE admin), or nobody could manage users any more ``` exit code 1 **Command line: A role that does not exist** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd kdb user role admin superuser ``` Output: `> kdb user add admin --role admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user role admin superuser` ```text error: the role must be admin, ddl, write, read or none (got 'superuser') ``` exit code 1 ## kdb user list Syntax: ```sql kdb user list [--data-dir ] ``` Lists the users: name, role, grants (roles on single databases) and the time of the last change (local time). It never shows passwords or hashes. - **Exit code:** `0`, also when there are no users (then it says `no users in yet`). - `GRANTS` shows `-`, or `database=role` for each `GRANT` (for example `shop=write`). Grants are made with SQL: `GRANT write ON DATABASE shop TO shop_app`. - In SQL: `SHOW USERS`. **Command line: No users yet** ```bash kdb user list ``` Output: ```text no users in ./kdb-data yet (add one with: kdb user add --role admin) ``` **Command line: Users, and a grant made with SQL in kdb shell** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd kdb user add shop_app > Another-long-secret-42 kdb shell > CREATE DATABASE shop; > GRANT write ON DATABASE shop TO shop_app; kdb user list ``` Output: `> kdb user add admin --role admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user add shop_app` ```text user 'shop_app' added with role none in ./kdb-data ``` `> kdb shell` ```text KDB 0.2.0-dev shell on default (data folder ./kdb-data) End statements with ';'. Type .help for commands, .exit to quit. kdb> database 'shop' created kdb> user 'shop_app' has role write on database 'shop' kdb> ``` `> kdb user list` ```text USER ROLE GRANTS CHANGED admin admin - 2026-10-22 11:28:33 shop_app none shop=write 2026-10-22 11:28:34 2 users in ./kdb-data ``` ## kdb user remove Syntax: ```sql kdb user remove [--data-dir ] ``` Removes a user. It can no longer log in. - **Exit code:** `0` removed; `1` for every error (unknown user, the last admin). - **The last admin** cannot be removed while other users exist. - To stop the server asking for logins, remove every user. The last user (an admin) can be removed when it is alone. - In SQL: `DROP USER `. **Command line: Remove a user** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd kdb user add report --role read > Reports-only-secret-7 kdb user remove report kdb user list ``` Output: `> kdb user add admin --role admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user add report --role read` ```text user 'report' added with role read in ./kdb-data ``` `> kdb user remove report` ```text user 'report' removed ``` `> kdb user list` ```text USER ROLE GRANTS CHANGED admin admin - 2026-10-22 11:28:33 1 user in ./kdb-data ``` **Command line: The last admin cannot be removed while others exist** ```bash kdb user add admin --role admin > Long-Admin-Passw0rd kdb user add report --role read > Reports-only-secret-7 kdb user remove admin ``` Output: `> kdb user add admin --role admin` ```text user 'admin' added with role admin in ./kdb-data ``` `> kdb user add report --role read` ```text user 'report' added with role read in ./kdb-data ``` `> kdb user remove admin` ```text error: Invalid argument: 'admin' is the last user with ROLE admin; make another user admin first (ALTER USER ROLE admin), or nobody could manage users any more ``` exit code 1 ## Errors of kdb user Syntax: ```sql usage: kdb user add [--role admin|ddl|write|read|none] error: no password given (type it, or pipe it in: echo | kdb user add ...) error: the users database (...) is open in another program, for example a running kdb serve; ... ``` | Message | Why | Fix | |---|---|---| | `usage: kdb user ...` | Unknown sub-command, or a missing or extra argument | See the syntax above | | `no password given` | The pipe was empty | Pipe one line, or type it | | `the password is too short` | Fewer than 12 characters | A longer password (a password manager can make one) | | `the password must not be the user name` | The password is the user name | Another password | | `the two passwords are not the same; nothing was changed` | You typed two different passwords | Type it again | | `the first user must have ROLE admin` | The first user had `--role read`, `write` or `none` | `--role admin` (or no `--role`) | | `is the last user with ROLE admin` | The change would leave no admin | Make another user admin first | | `user '...' already exists` / `does not exist` | Wrong name | `kdb user list` | | `bad user name` | Other characters than letters, digits, `_`, `-` | Change the name | | `the users database ... is open in another program` | `kdb serve` runs on this data folder | Stop the server, or use SQL in its console | | `no users in yet` (for passwd, role, remove) | The data folder has no users; exit code `1` | Check `--data-dir` | **Command line: A missing argument** ```bash kdb user add ``` Output: ```text usage: kdb user add [--role admin|ddl|write|read|none] kdb user passwd kdb user role admin|ddl|write|read|none kdb user list kdb user remove kdb user reset-2fa turn two-factor login off (a lost phone) [--data-dir ] (the password is asked for, or read from a pipe) ``` exit code 1