Chapter 12 · Accounts, Roles, Authentication, Authorization, and Security Hardening

Privileges, Roles, Default Roles, Grant Design, and Delegated Administration

Design least-privilege MariaDB authorization with scoped grants and roles, verify effective privileges and role activation, and delegate administration without spreading broad GRANT OPTION or administrator access.

Advanced125–145 minutesRBAC + denied-operation labMariaDB Community 12.3.2 baselineCurriculum anchor: 11.8 LTS · verify target versionLast reviewed: August 2026

Learning outcomes

ServiceHub now has separate identities, but identity alone does not protect data. An application that only reads and updates ticket status should not be able to create users; an analyst should not update internal notes; a migration job may need DDL that the runtime application never receives. MariaDB authorization is built from privileges granted at scopes such as global, database, table, column and routine, plus roles that bundle privileges into named operational capabilities.

01

Map MariaDB privileges to global, database, table, column and routine scopes.

02

Create roles and understand that MariaDB activates one current role at a time.

03

Use default roles deliberately and verify role activation in real sessions.

04

Separate owner/admin, migration, application and read-only capabilities.

05

Delegate role administration with WITH ADMIN OPTION without broadly granting GRANT OPTION.

MariaDB vs MySQL role behavior

MariaDB SET ROLE has one current role at a time. That differs materially from MySQL role behavior where multiple roles can be active. Do not copy a MySQL role design without testing it on the target MariaDB version.

1. Create a role-based lab with explicit denied operations

sql · schema and principals
DROP DATABASE IF EXISTS servicehub_rbac_lab;CREATE DATABASE servicehub_rbac_lab;USE servicehub_rbac_lab;CREATE TABLE tickets (  ticket_id BIGINT PRIMARY KEY,  customer_name VARCHAR(120) NOT NULL,  severity VARCHAR(16) NOT NULL,  internal_note VARCHAR(255),  status VARCHAR(16) NOT NULL) ENGINE=InnoDB;INSERT INTO tickets VALUES(3001,'Northwind Clinic','high','security callback','open'),(3002,'Caspian Foods','medium','billing context','assigned');DROP USER IF EXISTS 'svc_dispatch'@'localhost';DROP USER IF EXISTS 'analyst_ro'@'localhost';DROP USER IF EXISTS 'release_bot'@'localhost';CREATE USER 'svc_dispatch'@'localhost' IDENTIFIED BY 'LabOnly-Dispatch-42!';CREATE USER 'analyst_ro'@'localhost' IDENTIFIED BY 'LabOnly-Analyst-42!';CREATE USER 'release_bot'@'localhost' IDENTIFIED BY 'LabOnly-Release-42!';DROP ROLE IF EXISTS r_dispatch,r_readonly,r_migration,r_security_delegate;CREATE ROLE r_dispatch;CREATE ROLE r_readonly;CREATE ROLE r_migration;CREATE ROLE r_security_delegate;

Roles start with no useful privileges. That is valuable: a role should express a reviewed capability, not “all access because it is convenient.”

2. Grant the smallest scope that represents the job

Scope Example Security reasoning
Global *.* CREATE USER, FILE, PROCESS and version-specific administrative privileges High blast radius; reserve for tightly controlled operators.
Database db.* CREATE, ALTER, SELECT, INSERT on one application database Useful for migrations or database owners.
Table SELECT/UPDATE on one table Good application boundary when only specific objects are needed.
Column SELECT or UPDATE only selected columns Narrow interface but can become complex to operate.
Routine EXECUTE on PROCEDURE/FUNCTION Useful when a reviewed routine is the supported write API.
sql · build four distinct capability sets
GRANT SELECT(ticket_id,customer_name,severity,status),      UPDATE(status)ON servicehub_rbac_lab.tickets TO r_dispatch;GRANT SELECT(ticket_id,customer_name,severity,status)ON servicehub_rbac_lab.tickets TO r_readonly;GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,ALTER,INDEXON servicehub_rbac_lab.* TO r_migration;GRANT r_dispatch TO 'svc_dispatch'@'localhost';GRANT r_readonly TO 'analyst_ro'@'localhost';GRANT r_migration TO 'release_bot'@'localhost';SET DEFAULT ROLE r_dispatch FOR 'svc_dispatch'@'localhost';SET DEFAULT ROLE r_readonly FOR 'analyst_ro'@'localhost';SET DEFAULT ROLE r_migration FOR 'release_bot'@'localhost';

The application can update only status; it cannot read internal_note. The analyst cannot modify rows. The release bot can make schema/data changes inside this database but does not receive global user-management or FILE privileges.

3. Roles are granted and activated separately

Granting a role makes it available to an account. Its privileges are used when the role becomes current. A default role is activated automatically at connection time. In a session, SET ROLE replaces the active role rather than accumulating multiple active roles.

sql · verify role assignment and activation
SHOW GRANTS FOR 'svc_dispatch'@'localhost';SHOW GRANTS FOR r_dispatch;SELECT * FROM information_schema.APPLICABLE_ROLESWHERE GRANTEE LIKE '%svc_dispatch%';-- Run in a session connected as svc_dispatch:SELECT CURRENT_ROLE();SHOW GRANTS;SET ROLE NONE;SELECT CURRENT_ROLE();SET ROLE r_dispatch;SELECT CURRENT_ROLE();

Do not infer effective runtime privilege only from the role’s definition. Test a connection using the exact account and confirm its default/current role.

4. Deliberate failures prove least privilege

A security test suite needs denied operations. If every test succeeds, you have tested functionality rather than authorization.

sql · run as svc_dispatch with r_dispatch active
SELECT ticket_id,customer_name,severity,statusFROM servicehub_rbac_lab.tickets;UPDATE servicehub_rbac_lab.ticketsSET status='assigned'WHERE ticket_id=3001;-- Expected denial: internal_note was not granted for SELECT.SELECT ticket_id,internal_noteFROM servicehub_rbac_lab.tickets;-- Expected denial: only status was granted for UPDATE.UPDATE servicehub_rbac_lab.ticketsSET internal_note='should fail'WHERE ticket_id=3001;-- Expected denial: application role has no DDL authority.ALTER TABLE servicehub_rbac_lab.tickets ADD COLUMN unsafe_col INT;

Record the exact denial and verify the row/table remained unchanged. Denials are acceptance evidence: they prove the capability boundary is narrower than an administrator session.

sql · verify as an administrative lab session
SELECT ticket_id,status,internal_noteFROM servicehub_rbac_lab.ticketsWHERE ticket_id=3001;SHOW COLUMNS FROM servicehub_rbac_lab.tickets;

5. Delegated administration: role admin is not global grant power

WITH GRANT OPTION can let an account grant privileges it holds and becomes dangerous at broad scopes. For role delegation, WITH ADMIN OPTION is the narrower concept: it allows the grantee to grant that role onward, without automatically handing over arbitrary global privileges.

sql · delegate one role deliberately
CREATE USER IF NOT EXISTS 'team_lead'@'localhost'  IDENTIFIED BY 'LabOnly-TeamLead-42!';GRANT r_readonly TO 'team_lead'@'localhost' WITH ADMIN OPTION;SHOW GRANTS FOR 'team_lead'@'localhost';

That does not mean the team lead can grant FILE, CREATE USER or any unrelated capability. Keep delegation explicit and reviewable. Avoid name collisions between users and roles because MariaDB can prefer the role interpretation in ambiguous grant syntax.

6. Privilege discovery must be version-aware

MariaDB has evolved from broad administrative capabilities toward more fine-grained privileges. Do not freeze a privilege list into your architecture. Ask the target server what it supports.

sql · inspect the target privilege vocabulary
SHOW PRIVILEGES;SHOW GRANTS FOR 'release_bot'@'localhost';SHOW GRANTS FOR r_migration;

Privileges such as SHOW CREATE ROUTINE are version-sensitive. A migration framework should declare required capabilities and fail closed when the target server does not support or grant them.

Role Do Avoid
Runtime application Only data/routine operations needed by the service. DDL, FILE, CREATE USER, broad grant delegation.
Read-only analyst Curated SELECT access. Writes and raw sensitive columns not required for analysis.
Migration identity Schema changes within the owned database. Permanent runtime use.
Security administrator Account/role lifecycle needed for the job. Using the same identity for normal application traffic.

7. Production verification and cleanup

  1. Capture SHOW GRANTS for every account and role.
  2. Connect as each account and verify CURRENT_ROLE().
  3. Run at least one allowed and one denied operation per role.
  4. Review every use of global scope *.*, WITH GRANT OPTION and WITH ADMIN OPTION.
  5. Keep account-to-role mappings under change control.

Check your understanding

  1. Why is a default role different from merely granting a role?
  2. How many roles can be current in a MariaDB session?
  3. Why are denied-operation tests necessary?
  4. When is a database-level privilege preferable to a global privilege?
  5. What is the security difference between WITH ADMIN OPTION and broad WITH GRANT OPTION?
Review the answers

A granted role is available; a default role is automatically activated at connection. MariaDB uses one current role at a time. Denied tests prove the negative boundary. Database scope limits blast radius when the job only concerns one database. WITH ADMIN OPTION delegates a particular role, while GRANT OPTION can delegate privileges and is especially dangerous at broad scopes.

sql · cleanup
DROP USER IF EXISTS 'svc_dispatch'@'localhost';DROP USER IF EXISTS 'analyst_ro'@'localhost';DROP USER IF EXISTS 'release_bot'@'localhost';DROP USER IF EXISTS 'team_lead'@'localhost';DROP ROLE IF EXISTS r_dispatch,r_readonly,r_migration,r_security_delegate;DROP DATABASE IF EXISTS servicehub_rbac_lab;

Lesson 3 applies these authorization ideas to stored objects, where the caller and the stored object’s definer may be different security identities.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.