Chapter 12 · Accounts, Roles, Authentication, Authorization, and Security Hardening
Hardening Checklist, Audit Options, Plugin Risk, File Privileges, and Patch Discipline
Turn MariaDB hardening into an evidence-based operating process covering exposure, dangerous privileges, file access, plugins, Community auditing, OS permissions, secrets, backups and supported security updates.
Learning outcomes
Security hardening fails when it becomes a copied checklist with no evidence. ServiceHub needs a repeatable process that asks: what can reach MariaDB, which accounts and privileges exist, which server features can touch the filesystem, which plugins add executable code, what is logged, who can read those logs, where secrets/backups live, and is the server still on a supported security-update path?
Build an evidence packet for exposure, accounts, privileges, TLS, file access and plugins.
Explain why FILE, local_infile and secure_file_priv are separate controls.
Install/verify the Community Audit Plugin only when its library is present and understand audit overhead/data sensitivity.
Treat plugin installation and OS filesystem permissions as part of the database trust boundary.
Tie hardening to supported releases, security advisories, backup protection and patch/change discipline.
MariaDB Community Server has the Community Audit Plugin when the plugin library is available in the package. MariaDB Enterprise has distinct enterprise audit capabilities. Do not imply identical filtering, packaging or support behavior; verify the exact product/version documentation.
1. Start hardening with an evidence snapshot
SELECT VERSION() AS server_version;SHOW VARIABLES LIKE 'version_comment';SHOW GLOBAL VARIABLES WHERE Variable_name IN ( 'bind_address','port','skip_name_resolve','require_secure_transport', 'local_infile','secure_file_priv','plugin_dir','log_error');SELECT User,Host,is_role,default_roleFROM mysql.userORDER BY is_role,User,Host;SHOW PRIVILEGES;SELECT PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE,PLUGIN_LIBRARYFROM information_schema.PLUGINSORDER BY PLUGIN_TYPE,PLUGIN_NAME;
Run this only from an appropriately privileged administrative session. The result is a point-in-time inventory, not a compliance certificate. Pair database evidence with OS/container evidence: listening sockets, firewall rules, ownership/mode of the data/config/TLS directories, service identity and backup permissions.
2. Exposure, anonymous accounts and test surfaces
Hardening should minimize paths into the server before tuning
privilege details. Bind only where needed, restrict network
paths externally, remove anonymous or unused accounts, and
remove test schemas that have no production owner. Do not assume
the historical mariadb-secure-installation workflow
replaces review of a modern package’s actual defaults.
SELECT User,HostFROM mysql.userWHERE User='' OR User IS NULL;SHOW DATABASES;-- Review before deletion; do not run DROP on a production schema merely because of its name.SELECT SCHEMA_NAMEFROM information_schema.SCHEMATAWHERE SCHEMA_NAME IN ('test');
Every destructive cleanup should have an owner-approved change
and backup/rollback strategy. A schema named
test can still contain real data in a poorly
governed system.
3. FILE, local_infile and
secure_file_priv are different controls
The global FILE privilege allows server-side file
read/write operations used by statements such as
LOAD DATA INFILE and
SELECT ... INTO OUTFILE, subject to server
filesystem permissions and secure_file_priv.
LOAD DATA LOCAL INFILE is different: the client
provides the file contents and the server’s
local_infile capability governs support. Conflating
them creates bad hardening decisions.
SHOW GLOBAL VARIABLES LIKE 'local_infile';SHOW GLOBAL VARIABLES LIKE 'secure_file_priv';SELECT User,HostFROM mysql.userWHERE File_priv='Y';-- For every account found, review complete effective grants:-- SHOW GRANTS FOR 'account'@'host';
On MariaDB, an empty/unset secure_file_priv does
not mean “deny all”; official documentation notes that the
affected server-side file statements can operate on files
accessible to the server when no path restriction is set. Treat
the filesystem service account and OS mandatory-access controls
as part of the boundary.
Do not grant FILE to routine application accounts. If a controlled import/export process requires it, isolate the identity, constrain server filesystem access, configure an approved directory where appropriate, and remove the privilege when the workflow is complete.
4. Plugins extend the server’s trusted code base
INSTALL PLUGIN or INSTALL SONAME loads
executable code from the configured plugin directory. A plugin
can add authentication, storage, auditing or other server
capabilities, but every plugin adds package, compatibility,
patching and startup dependencies. Never install a plugin merely
because a tutorial mentions it.
SHOW GLOBAL VARIABLES LIKE 'plugin_dir';SELECT PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE,PLUGIN_LIBRARY,LOAD_OPTIONFROM information_schema.PLUGINSORDER BY PLUGIN_NAME;
Before installing anything, verify the library comes from the trusted MariaDB/OS package for the exact target version, check file ownership/permissions, confirm restart/load semantics and document uninstall/recovery behavior. Production plugin changes should go through change control just like native libraries loaded by an application.
5. Community auditing: visibility with operational cost
The MariaDB Community Audit Plugin can record connections, queries, table access and variable changes, writing to a rotating file or syslog depending on configuration. It is useful evidence, but audit logs can contain sensitive SQL and can add I/O/CPU overhead. “Log everything forever” is neither a privacy strategy nor a capacity plan.
SELECT PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_LIBRARY,LOAD_OPTIONFROM information_schema.PLUGINSWHERE PLUGIN_NAME='SERVER_AUDIT';SHOW GLOBAL VARIABLES LIKE 'plugin_dir';
If SERVER_AUDIT is absent, confirm the package
actually contains server_audit.so or
server_audit.dll before installing. The following
is therefore a conditional lab step, not a universal command:
INSTALL SONAME 'server_audit';SELECT PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_LIBRARY,LOAD_OPTIONFROM information_schema.PLUGINSWHERE PLUGIN_NAME='SERVER_AUDIT';SHOW GLOBAL VARIABLES LIKE 'server_audit%';SHOW GLOBAL STATUS LIKE 'server_audit%';
Enable a small, reviewed event set in the disposable lab,
generate a connection/query, confirm the chosen log destination,
then disable or remove the plugin configuration according to
your lab method. For production persistence, use option-file
configuration such as plugin_load_add=server_audit;
official documentation also describes
FORCE_PLUS_PERMANENT for environments that must
prevent runtime uninstall.
Restrict who can read audit logs, rotate them, ship them securely if required, and define retention. Slow/general/audit logs may capture literals, identifiers or operational secrets embedded in SQL. Redaction must be designed rather than assumed.
6. Deliberately wrong: broad FILE + LOCAL + plugin-admin privileges for convenience
A common operations shortcut is a “utility” account with
ALL PRIVILEGES ON *.* WITH GRANT OPTION because it
sometimes imports files or installs plugins. That turns one
leaked password into filesystem access, plugin changes and
privilege delegation. The repair is to separate duties and make
temporary elevation explicit.
SHOW PRIVILEGES;-- Review all accounts with FILE privilege:SELECT User,Host FROM mysql.user WHERE File_priv='Y';-- Review global grants account by account using SHOW GRANTS.-- Remove FILE/GRANT OPTION/plugin-management authority when no longer required.
Use a dedicated import identity for approved file workflows, a separately controlled plugin/server administrator, and runtime application roles with none of those capabilities. If temporary elevation is required, make the start/end time and cleanup verification part of the change ticket.
7. Patch discipline is a security control, not a maintenance afterthought
A hardened configuration on an unsupported server eventually becomes an unpatched configuration. Record the exact MariaDB Community/Enterprise product, release series, maintenance version, connectors, plugins and Galera/provider components. Follow official release notes and security advisories, test maintenance/release upgrades in a representative environment, and keep a rollback/recovery plan.
| Asset | Evidence to retain | Why |
|---|---|---|
| MariaDB Server | Exact version, release notes, support status | Security fixes and behavior changes are version-specific. |
| Connectors/clients | Exact versions and TLS/auth support | A secure server policy can break old clients. |
| Plugins | Library/package version and load policy | Plugins are executable code with independent compatibility risk. |
| Backups | Encryption/access controls + successful restore drill | Security incident recovery requires usable, protected backups. |
| Secrets/certificates | Owner, rotation date, consuming systems | Prevents orphaned credentials and expired identity material. |
Do not patch by copying binaries into a running data directory. Use supported package/container upgrade workflows, take/verify backups, review deprecated/changed settings, and validate authentication, TLS, stored definers and application queries after the change.
8. Chapter 12 security acceptance matrix
| Area | Accept when | Stop / remediate when |
|---|---|---|
| Identity | Every account has a purpose/owner and narrow host pattern. | Shared/dormant/anonymous accounts lack ownership. |
| Authorization | Allowed and denied tests match role design. | Runtime identities hold global administrative privileges. |
| Stored code | Definers exist and are least-privilege. | Administrator definers appear without documented need. |
| Transport | TLS is observed and server identity is verified. | Encryption is assumed from a flag/default without evidence. |
| File/plugin | FILE and plugin authority are isolated and reviewed. | Application accounts can read/write server files or load code. |
| Audit | Required events are captured with protected retention. | Audit logs expose secrets or create unmanaged resource pressure. |
| Patch/recovery | Supported versions and restore-tested backups exist. | Security fixes cannot be applied safely or restore is unproven. |
Check your understanding
- How are FILE, local_infile and secure_file_priv different?
- Why can an audit plugin increase security risk if operated badly?
- Why is plugin_dir part of the trust boundary?
- What is wrong with using ALL PRIVILEGES WITH GRANT OPTION as a generic utility account?
- Why does patch discipline belong in a hardening chapter?
Review the answers
FILE governs server-side file operations; local_infile controls LOCAL loading support; secure_file_priv constrains certain server-side file paths. Audit logs can contain sensitive SQL and create overhead. Plugin libraries are executable server code loaded from plugin_dir. A generic all-powerful utility account combines unrelated blast radii and delegation power. Supported patched software is necessary because configuration cannot compensate indefinitely for known vulnerabilities.
9. Reproducible hardening lab cleanup and bridge to backup/recovery
- Export the evidence snapshot before cleanup.
-
If you installed
server_auditonly for the disposable lab, disable logging and uninstall it only if the server startup configuration will not immediately reload it and no other user depends on it. - Drop disposable accounts/schemas created for this chapter.
- Restore any dynamic lab variable changes to their pre-lab values rather than guessing a default.
- Keep the written findings: risky privileges, unsupported versions, unresolved plugin dependencies and required remediation owners.
-- Only if this lab installed the plugin dynamically and startup config does not require it:-- SET GLOBAL server_audit_logging=OFF;-- UNINSTALL SONAME 'server_audit';DROP DATABASE IF EXISTS servicehub_security_lab;DROP DATABASE IF EXISTS servicehub_rbac_lab;DROP DATABASE IF EXISTS servicehub_definer_lab;DROP USER IF EXISTS 'svc_tls_app'@'localhost';
Chapter 12 built the security boundary from identity through transport and hardening. Chapter 13 turns to backup, restore and point-in-time recovery. The connection is direct: backups contain the same sensitive data, account definitions, definers and possibly credentials/keys referenced by the server, so recovery media must receive equal or stronger protection than the live database.
Authoritative references
- MariaDB Documentation — MariaDB Community Audit Plugin
- MariaDB Documentation — Audit Plugin Installation
- MariaDB Documentation — GRANT / FILE privilege
- MariaDB Documentation — LOAD DATA INFILE
- MariaDB Documentation — Server System Variables
- MariaDB Documentation — Plugin Overview
- MariaDB Security
- MariaDB Release Notes