MySQL Users and Roles
Every connection to MySQL logs in as an account, and each account has its own privileges. Applications, testers, analysts and administrators should never share the root account. This lesson creates accounts, sets passwords, groups privileges into roles and shows how to inspect and remove accounts.
- Create accounts with
CREATE USERand understanduser@host - Change passwords, lock and drop accounts
- Bundle privileges into roles
- Design accounts with least privilege
Accounts are user@host
A MySQL account is a user name plus the host it connects from: 'app'@'localhost' and 'app'@'%' are two different accounts.
| Host part | Meaning |
|---|---|
'localhost' | only from the database server itself |
'10.0.5.%' | any machine in that network |
'%' | from anywhere (use with care) |
CREATE USER
CREATE USER 'report_reader'@'localhost' IDENTIFIED BY 'Rep0rt#2026';CREATE USER 'shop_app'@'10.0.5.%' IDENTIFIED BY 'Sh0p#App2026';SELECT user, host, account_locked FROM mysql.userWHERE user IN ('report_reader', 'shop_app');| user | host | account_locked |
|---|---|---|
| shop_app | 10.0.5.% | N |
| report_reader | localhost | N |
- Each
CREATE USERcreates an account with a password. New accounts can log in but have no privileges on any data yet. mysql.useris the system table that lists accounts.
The passwords in this lesson are examples. Use long, unique passwords stored in a secrets manager, and never put real passwords in scripts or source code.
A new account sees only its own grant of USAGE (meaning “no privileges”):
CREATE USER 'report_reader'@'localhost' IDENTIFIED BY 'Rep0rt#2026';SHOW GRANTS FOR 'report_reader'@'localhost';| Grants for report_reader@localhost |
|---|
| GRANT USAGE ON *.* TO `report_reader`@`localhost` |
Change, lock and drop
CREATE USER 'intern'@'localhost' IDENTIFIED BY 'Int3rn#2026';ALTER USER 'intern'@'localhost' IDENTIFIED BY 'N3w#Passw0rd';ALTER USER 'intern'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;ALTER USER 'intern'@'localhost' ACCOUNT LOCK;SELECT user, host, account_locked, password_lifetime FROM mysql.user WHERE user = 'intern';DROP USER 'intern'@'localhost';| user | host | account_locked | password_lifetime |
|---|---|---|---|
| intern | localhost | Y | 90 |
ALTER USER ... IDENTIFIED BYchanges the password.PASSWORD EXPIRE INTERVAL 90 DAYforces a change every 90 days.ACCOUNT LOCKblocks logins without deleting the account (useACCOUNT UNLOCKto allow them again).DROP USERremoves the account and its privileges.
Roles
A role is a named bundle of privileges. Grant privileges to the role once, then grant the role to people:
CREATE ROLE 'analyst', 'developer';GRANT SELECT ON company.* TO 'analyst';GRANT SELECT, INSERT, UPDATE, DELETE ON company.* TO 'developer'; CREATE USER 'priya'@'localhost' IDENTIFIED BY 'Pr1ya#2026';GRANT 'analyst' TO 'priya'@'localhost';SET DEFAULT ROLE 'analyst' TO 'priya'@'localhost'; SHOW GRANTS FOR 'priya'@'localhost' USING 'analyst';| Grants for priya@localhost |
|---|
| GRANT USAGE ON *.* TO `priya`@`localhost` |
| GRANT SELECT ON `company`.* TO `priya`@`localhost` |
| GRANT `analyst`@`%` TO `priya`@`localhost` |
CREATE ROLEcreates two roles; they are locked accounts that nobody logs in as.- Privileges are granted to the roles (see GRANT).
- Priya receives the
analystrole.SET DEFAULT ROLEmakes it active automatically when she logs in; otherwise she would have to runSET ROLE 'analyst';. SHOW GRANTS ... USING 'analyst'shows what she can actually do through the role.
When Priya joins the development team, one statement changes her access: GRANT 'developer' TO 'priya'@'localhost'; and later REVOKE 'analyst' FROM 'priya'@'localhost';.
Least privilege
| Account | Should have |
|---|---|
| Web application | SELECT, INSERT, UPDATE, DELETE on its own database only |
| Reporting / BI tool | SELECT only, ideally on views |
| Test automation | full rights on a test database, nothing on production |
| Migrations / deploys | CREATE, ALTER, INDEX, DROP on the app database |
| DBA | administrative privileges, with strong authentication |
Never connect applications as root. If an application with only SELECT is attacked through SQL injection, the attacker cannot drop tables.
Quick quiz
1. Are ‘app’@’localhost’ and ‘app’@’%’ the same account?
MySQL identifies accounts by user and host together.
2. What privileges does a new user have right after CREATE USER?
Privileges must be granted explicitly.
3. Why use roles?
Change the role, and everyone who has it changes too.
Users and roles FAQ
How do I create a user in MySQL?
CREATE USER 'name'@'host' IDENTIFIED BY 'password'; then grant privileges with GRANT.
How do I see all users in MySQL?
SELECT user, host FROM mysql.user;
What is a role in MySQL?
A named collection of privileges (MySQL 8.0+). Grant privileges to the role and the role to users; activate it with SET DEFAULT ROLE or SET ROLE.
How do I change a MySQL user’s password?
ALTER USER 'name'@'host' IDENTIFIED BY 'new password';