MariaDB Enterprise Audit
This page is part of MariaDB's Documentation.
The parent of this page is: Log Archive
Topics on this page:
Overview
MariaDB Enterprise Audit logs database access and database operations:
Changes to audit configuration are logged
Filters define what information is logged, reducing unnecessary output
If filter definitions are malformed, the system fails safe by logging everything
Compatibility
Multi-Node Analytics
Replicated Transactions
Single Node Analytics
Single Node Transactions
Lifecycle
When | What | How |
---|---|---|
Before initial setup or changes | Planning (Recommended) |
|
Before initial setup or changes | Evaluate Control Requirements (As Needed) |
|
Initial setup | Enable Enterprise Audit functionality (Required) |
|
Initial setup | Define Audit Filters (Required) |
|
Initial setup | Verification (Recommended) |
|
Ongoing | Update Audit Filters (As Needed) |
|
Ongoing | Download logs (As Needed) |
|
Ongoing | Verification (As Needed) |
|
Ongoing | Evidence capture (As Needed) |
|
Configuration Manager
Audit logging functionality is available only when the MariaDB Enterprise Audit plugin is loaded and audit logging is enabled.
Two SkySQL Configuration Manager configuration parameters must be set to enable audit logging functionality:
The
server_audit
configuration parameter defines how the MariaDB Enterprise Audit plugin is loaded:Setting
Plugin loaded?
Server start requires plugin load?
Plugin can be uninstalled?
OFF
No
No
Yes
ON
Yes
No
Yes
FORCE
Yes
Yes
Yes
FORCE_PLUS_PERMANENT
(default)Yes
Yes
No
The
server_audit_logging
parameter defines whether audit logging is enabled:Audit logging is disabled when
server_audit_logging
isOFF
(default).Audit logging is enabled when
server_audit_logging
isON
.
After a configuration has been prepared with the intended parameters, it must be applied to the desired service for this change to take effect. The service will be restarted when the configuration is applied.
MariaDB Enterprise Audit can only perform logging if the plugin is loaded and audit logging is enabled.
Log Archive
MariaDB Enterprise Audit log data is available in the Log Archive.
To download log data:
Log in to the MariaDB SkySQL portal.
Access "Monitoring" in left navigation.
From SkySQL Monitoring, access "Logs" in left navigation.
Select the desired server(s), log types (such as "Enterprise Audit Log"), and time frame, then click the "Download" button to download the logs.
Log files can be downloaded in your choice of JSON and/or plain text formats.
The downloaded
.zip
archive will contain one file per server, log, day, and format.
Data Retention
The Log Archive retains log data for 7 years. Data is retained even if the SkySQL service is deleted.
Logs are stored in GCS buckets with HTTPS data-in-transit encryption and Google default (AES256) data-at-rest encryption.
Logs are stored by day, by service, by server, by log type.
To request log data expungement, submit a Support Request.
Data retention requirements vary by business. A business process may be needed to download audit log data and error log data in support of your data retention requirements.
Log Format
Fields
timestamp
server host
database username
user host
connection ID
query ID
operation
database name
object
return code
Note
MariaDB Enterprise Audit logs can contain sensitive information, such as PII and SPII.
Plain Text
In plain text format, MariaDB Enterprise Audit log has this format for each line:
<timestamp>,<serverhost>,<username>,<host>,<connectionid>,<queryid>,
<operation>,<database>,<object>,<retcode>
JSON
In JSON format, MariaDB Enterprise Audit log has this format for each line, incorporating the plain text format:
{"log":"PLAIN_TEXT","offset":OFFSET_VALUE}
One JSON object is produced for each logical line from the original plain text log file.
JSON key order is not guaranteed.
Audit Filters and Audit Users
Audit logging should be configured based on business-specific control requirements which define the database objects and/or users whose activity must be logged.
Audit Filters and Audit Users are mechanisms used to specify what what will be audit logged.
Audit Filters
Audit Filters define what MariaDB Enterprise Audit should log:
The Default Audit Filter, if present, is an Audit Filter with
filtername
ofdefault
.Named Audit Filters are any Audit Filters with
filtername
other thandefault
.The Default Audit Filter is applied for any user not subject to a Named Audit Filter.
Named Audit Filters are applied as defined by Audit Users.
Audit Filters are stored in the
mysql.server_audit_filters
table.Audit Filter rules can contain Event Filters, Logging Filters, and Object Filters.
Audit Users
Audit Users assign a Named Audit Filter to a specific user:
User is specified as a hostname and username combination.
Audit Users are stored in the
mysql.server_audit_users
table.
Audit Filter Display
Audit Filter behavior is defined in the mysql.server_audit_filters
and mysql.server_audit_users
tables.
Displaying JSON Data
In many of the examples on this page, the JSON_
Using a function to make JSON objects more human-readable is optional but recommended.
Default Audit Filter
To view the Default Audit Filter, if one exists, query the database server:
SELECT filtername,
JSON_DETAILED(rule)
FROM mysql.server_audit_filters
WHERE filtername='default'\G
Named Audit Filters
To view Named Audit Filters, if any exist, query the database server:
SELECT filtername,
JSON_DETAILED(rule)
FROM mysql.server_audit_filters
WHERE filtername != 'default'\G
*************************** 1. row ***************************
filtername: reporting
JSON_DETAILED(rule): {
"table_event":
[
"WRITE",
"CREATE",
"DROP",
"RENAME",
"ALTER",
{
"log_databases":
[
"production",
"reporting"
]
}
]
}
Audit Users
User assignments for Named Audit Filters can be understood by joining the mysql.server_
To view user assignments for Named Audit Filters, if any exist, query the database server:
SELECT sau.host, sau.user, saf.filtername,
JSON_DETAILED(saf.rule)
FROM mysql.server_audit_filters saf
JOIN mysql.server_audit_users sau
ON saf.filtername = sau.filtername
WHERE saf.filtername != 'default'\G
*************************** 1. row ***************************
host: %
user: reader
filtername: reporting
JSON_DETAILED(saf.rule): {
"table_event":
[
"WRITE",
"CREATE",
"DROP",
"RENAME",
"ALTER",
{
"log_databases":
[
"production",
"reporting"
]
}
]
}
*************************** 2. row ***************************
host: %
user: writer
filtername: reporting
JSON_DETAILED(saf.rule): {
"table_event":
[
"WRITE",
"CREATE",
"DROP",
"RENAME",
"ALTER",
{
"log_databases":
[
"production",
"reporting"
]
}
]
}
Audit Filter Management
Audit Filter behavior is defined in the mysql.server_audit_filters
and mysql.server_audit_users
tables.
Changes to Audit Filters are applied by stopping and starting the service.
Compacting JSON Data
In many of the examples on this page, the JSON_
This is optional but recommended.
Named Audit Filters
Audit filters are customized based on your specific business requirements. There is no one-size-fits-all approach.
As a simple example, we consider audit logging which may be appropriate for a read-only user that queries data to produce business reports. For this user, we might want to record their connect and disconnect events, but ignore read activity. For this user, table writes and schema changes would be illegitimate activities.
To create our
reporting
Audit Filter:INSERT INTO mysql.server_audit_filters (filtername, rule) VALUES ('reporting', JSON_COMPACT( '{ "connect_event": [ "CONNECT", "DISCONNECT" ], "table_event":[ "WRITE", "CREATE", "DROP", "RENAME", "ALTER" ] }' ));
Our filter must now be applied to the user. To apply the
reporting
Audit Filter to thereader@%
user account:INSERT INTO mysql.server_audit_users (host, user, filtername) VALUES ("%", "reader", "reporting");
Finally, to apply this Audit Filter change, we will stop and start the service.
MariaDB Enterprise Audit includes advanced filter settings to define which events are logged.
Default Audit Filter
Any user account not assigned to a Named Audit Filter is subject to the Default Audit Filter (if one is defined).
Audit filters are customized based on your specific business requirements. There is no one-size-fits-all approach.
As a simple example, we consider logging all connection events and all table writes for users otherwise un-audited.
To create our Default Audit Filter:
INSERT INTO mysql.server_audit_filters (filtername, rule) VALUES ('default', JSON_COMPACT( '{ "connect_event":"ALL", "table_event":"WRITE" }' ));
Finally, to apply this Audit Filter change, we will stop and start the service.
MariaDB Enterprise Audit includes advanced filter settings to define which events are logged.
Event Filters
Event Type | Purpose |
---|---|
Logs changes to the audit log configuration | |
Logs connection attempts, authentication failures, and user account changes due to certain authentication plugins | |
Logs execution of a specific subset of SQL statements | |
Logs when a table is accessed or modified |
Logging Filters and Object Filters can change the logging behavior of other filters.
Special configuration is needed when SQL statements use the DELAYED
keyword. See "Auditing DELAYED Statements".
Audit Config Events
Detail | Description |
---|---|
Purpose | Log changes to the audit log configuration |
JSON Key | Audit Config Events are not customer-configurable and are always logged |
Event Types |
|
Behavior |
|
Sample Filter:
Audit Config events are always logged. These events are not configurable.
Sample Log:
In the following example output, 3 Audit Config Events and 1 Query Event are shown:
20190622 02:10:21,localhost.localdomain,,,0,0,AUDIT_CONFIG,,file_path=server_audit.log,0
20190622 02:10:21,localhost.localdomain,,,0,0,AUDIT_CONFIG,,rotate_size=1000000,0
20190622 02:10:21,localhost.localdomain,,,0,0,AUDIT_CONFIG,,file_rotations=9,0
20190622 02:10:21,localhost.localdomain,root,localhost,8,7,QUERY,mysql,'set global server_audit_logging = on',0
Connection Events
Detail | Description |
---|---|
Purpose | Logs connection attempts, authentication failures, and user account changes due to certain authentication plugins |
JSON Key |
|
Event Types |
|
Behavior |
|
Sample Filter:
INSERT INTO mysql.server_audit_filters (filtername, rule)
VALUES ('connections',
JSON_COMPACT(
'{
"connect_event": [
"CONNECT",
"DISCONNECT"
]
}'
));
Sample Log:
In the following example output, 4 Connection Events are shown:
20190710 00:05:30,localhost.localdomain,root, localhost,2,0,CONNECT,,,0
20190710 00:05:53,localhost.localdomain,root, localhost,2,0,DISCONNECT,,,0
20190710 00:06:28,localhost.localdomain,unknownuser,localhost,3,0,FAILED_CONNECT,,,1045
20190710 00:06:28,localhost.localdomain,unknownuser, localhost,3,0,DISCONNECT,,,0
Query Events
Detail | Description |
---|---|
Purpose | Logs execution of a specific subset of SQL statements |
JSON Key |
|
Event Types |
|
Behavior |
|
Sample Filter:
INSERT INTO mysql.server_audit_filters (filtername, rule)
VALUES ('queries',
JSON_COMPACT(
'{
"query_event": [
"DML",
"DDL"
]
}'
));
Sample Log:
In the following example output, 1 Query Event is shown:
20190710 02:21:07,localhost.localdomain,John,localhost,3,30,QUERY,db1,'SELECT * FROM services WHERE typeid IN (SELECT id FROM services_types WHERE name="consulting")',0
Table Events
Detail | Description |
---|---|
Purpose | Logs when a table is accessed or modified |
JSON Key |
|
Event Types |
|
Behavior |
|
Sample Filter:
INSERT INTO mysql.server_audit_filters (filtername, rule)
VALUES ('tables',
JSON_COMPACT(
'{
"table_event": [
"WRITE",
"CREATE",
"DROP",
"RENAME",
"ALTER"
]
}'
));
Sample Log:
In the following example output, 6 sub-classes of Table Events are shown:
20190710 02:21:06,localhost.localdomain,John,localhost,3,25,CREATE,db1,services,
20190710 02:21:06,localhost.localdomain,John,localhost,3,27,READ,db1,services,
20190710 02:21:07,localhost.localdomain,John,localhost,3,29,WRITE,db1,services,
20190710 02:21:27,localhost.localdomain,John,localhost,3,35,ALTER,db1,services,
20190710 02:21:27,localhost.localdomain,John,localhost,3,36,RENAME,db1,services,db1,services_new
20190710 02:21:45,localhost.localdomain,John,localhost,3,38,DROP,db1,services_new,
Auditing DELAYED Statements
When a query uses the DELAYED
keyword, behavior changes:
The query is executed by a system user.
Any Table Event associated with the query is written to the audit log with the user set to
DELAYED
Any Query Event associated with the query is written to the audit log with the original user.
For example:
20190622 02:10:21,localhost.localdomain,root,localhost,8,5,QUERY,test,'INSERT DELAYED INTO t1 VALUES(1),(2),(3);',0
20190622 02:10:25,localhost.localdomain,root,localhost,2,2,WRITE,test,t1,
20190622 02:10:25,localhost,DELAYED,localhost,2,2,WRITE,test,t1,
To support audit of queries with the DELAYED
keyword, it is recommended to use both Query Events and Table Events as to ensure that a complete set of details are logged.
Logging Filters
Detail | Description |
---|---|
Purpose | Turn on or turn off all Audit Filters for a user or users |
JSON Key |
|
Event Types |
|
Behavior |
|
Sample Filter:
The following example defines a Default Audit Filter that enables logging for all Events for any user account without a Named Audit Filter:
INSERT INTO mysql.server_audit_filters (filtername, rule)
VALUES ('default',
JSON_COMPACT(
'{
"logging": "ON"
}'
));
Object Filters
Object Filters allow Audit Filters to be limited to specific databases and/or tables.
Examples
An Object Filter to audit log the production
and reporting
databases, and to skip audit logging for all other databases and tables:
{"log_tables": ["production.*", "reporting.*"]}
An Object Filter to skip audit logging for the production.app_log
table:
{"ignore_tables": "production.app_log"}
Object Filter Types
Object Filters are formatted as JSON objects, which are key-value pairs.
The Object Filter key specifies the behavior to apply:
Object Filter Key | Behavior |
---|---|
|
|
|
|
|
|
|
|
Specify a Single Object
Object Filters are formatted as JSON objects, which are key-value pairs.
The Object Filter value specifies one or more object names.
When the Object Filter only applies to one object, the object name can be specified as a string scalar value in the JSON object:
{"object_filter_key": "object"}
Specify Multiple Objects
Object Filters are formatted as JSON objects, which are key-value pairs.
The Object Filter value specifies one or more object names.
When the Object Filter applies to multiple objects, the object names can be specified in a JSON array in the JSON object:
{"object_filter_key": [ "object", "object" ]}
Set Object Filters at Event Scope
The location of an Object Filter within the Audit Filter's JSON object will depend on the desired scope of the Object Filter. Several scopes are possible.
At Event Scope, an Object Filter can be specified for a Query Event or Table Event within an Audit Filter.
This is done by specifying the Object Filter's JSON object as part of the JSON object for the Event Filter.
Audit filters are customized based on your specific business requirements. There is no one-size-fits-all approach.
As a simple example, we consider a reporting
Audit Filter to audit log the specified table events for only the production
and reporting
databases:
INSERT INTO mysql.server_audit_filters (filtername, rule)
VALUES (
'reporting',
JSON_COMPACT(
'{
"table_event": [
"WRITE",
"CREATE",
"DROP",
"RENAME",
"ALTER",
{
"log_tables": [
"production.*",
"reporting.*"
]
}
]
}'
)
);
Set Object Filters at Audit Filter Scope
The location of an Object Filter within the Audit Filter's JSON object will depend on the desired scope of the Object Filter. Several scopes are possible.
At Audit Filter Scope, an Object Filter can be specified for an entire Audit Filter.
This is done by specifying the Object Filter's JSON object as part of the root JSON object for the Audit Filter.
Audit filters are customized based on your specific business requirements. There is no one-size-fits-all approach.
As a simple example, we consider a reporting
Audit Filter to audit log for only the production
and reporting
databases:
INSERT INTO mysql.server_audit_filters (filtername, rule)
VALUES (
'reporting',
JSON_COMPACT(
'{
"log_tables": [
"production.*",
"reporting.*"
]
}'
)
);
Embedded Event Filters
When an Object Filter is specified at Audit Filter Scope, it can contain embedded Event Filters.
Query Events and Table Events support Object Filters.
Audit filters are customized based on your specific business requirements. There is no one-size-fits-all approach.
As a simple example, we consider a reporting
Audit Filter to include Event Filters on specific Query Event sub-classes and Table Event sub-classes:
INSERT INTO mysql.server_audit_filters (filtername, rule)
VALUES (
'reporting',
JSON_COMPACT(
'{
"log_tables": [
"production.*",
"reporting.*",
{
"query_event": [
"DML",
"DDL"
],
"table_event": [
"WRITE",
"CREATE",
"DROP",
"RENAME",
"ALTER"
]
}
]
}'
)
);
Combine Object Filters at Audit Filter and Event Scope
When an Object Filter is specified at Audit Filter Scope with embedded Event Filters, the embedded Event Filters can contain additional Object Filters. When you combine Object Filters at different levels, it is possible to combine Object Filters that are normally incompatible, like tables
and ignore_tables
.
To create Object Filters at Audit Filter and Event Type Scope, specify the JSON object for the Object Filter at Audit Filter Scope as part of the root JSON object for the Audit Filter and specify the JSON object for the Object Filter at Event Type Scope as part of the JSON object for the Event Filter.
Audit filters are customized based on your specific business requirements. There is no one-size-fits-all approach.
As a simple example, we consider a reporting
Audit Filter to specify an Event Filter for Table Events with an embedded Object Filter that includes all tables in the production
and reporting
databases, but it excludes Query Events that target specific tables that store Personally Identifiable Information (PII), so that the sensitive information does not appear in the audit log:
INSERT INTO mysql.server_audit_filters (filtername, rule)
VALUES (
'reporting',
JSON_COMPACT(
'{
"log_tables": [
"production.*",
"reporting.*",
{
"table_event": [
"WRITE",
"CREATE",
"DROP",
"RENAME",
"ALTER"
],
"query_event": [
"DML",
"DDL",
{
"ignore_tables": [
"production.customer_profiles",
"production.customer_addresses"
]
}
]
}
]
}'
)
);
Implementation Considerations
Business requirements may vary, and there is no one-size-fits-all approach to audit.
Migration
When migrating to MariaDB SkySQL from MariaDB Server, some changes may be necessary to your Enterprise Audit user and filter tables. Contact us for assistance.
Privileges
When Enterprise Audit is used, applications should connect to the database with user accounts that do not have privileges to modify the Audit Filters:
The default user for the database has privileges to modify Audit Filters, so this user should not be used for application database access.
Applications should connect to the database using non-default database users who do not have privileges to
DELETE
,INSERT
, orUPDATE
themysql.server_audit_filters
ormysql.server_audit_users
tables.
User Renames and Deletes
Manual action may be needed to update Named Audit Filters when a database user account is renamed or deleted:
When a user is deleted, manual deletion may be needed to clean-up any
mysql.server_audit_users
rows for the old username.When a user is renamed, manual update may be needed for any
mysql.server_audit_users
rows for the old username.The Default Audit Filter is applied for any user without a Named Audit Filter matching their username.
Query Cache
By default, the query cache is disabled.
If the query cache is enabled, READ
Table Events may not be audit logged. If MariaDB Enterprise Audit detects that the query cache is enabled during startup, MariaDB Enterprise Audit writes the following message to the MariaDB error log:
2021-07-23 0:11:26 server_audit: Query cache is enabled with the TABLE events. Some table reads can be veiled.
Application Checks
Application code could perform checks when connecting to the database to verify that:
MariaDB Enterprise Audit plugin is active (
Server_audit_active
status variable)Audit Logging is enabled (
server_audit_logging
system variable)
Error Log Checks
MariaDB Enterprise Server error logs indicate presence of MariaDB Enterprise Audit:
If MariaDB Enterprise Server starts with auditing disabled, no error is generated.
If MariaDB Enterprise Server starts with auditing enabled, MariaDB Enterprise Audit logs a message to the MariaDB error log.
Verification
Business requirements may vary, and there is no one-size-fits-all approach to audit.
The following are common steps that could be used to help verify proper operation of MariaDB Enterprise Audit.
This is not the only way to verify correct operation of MariaDB Enterprise Audit. Different steps may be suitable for your specific business needs.
Plugin Loaded
Detail | Description |
---|---|
How | With sufficient privileges, query the database server |
Sample Query | SELECT * FROM information_schema.PLUGINS
WHERE PLUGIN_NAME = 'server_audit'\G
|
Output Details |
|
Expected Result | If the correct plugin is loaded, a row with |
Sample Output | MariaDB> SELECT * FROM information_schema.PLUGINS WHERE PLUGIN_NAME ='server_audit'\G
*************************** 1. row ***************************
PLUGIN_NAME: SERVER_AUDIT
PLUGIN_VERSION: 2.1
PLUGIN_STATUS: ACTIVE
PLUGIN_TYPE: AUDIT
PLUGIN_TYPE_VERSION: 3.2
PLUGIN_LIBRARY: server_audit2.so
PLUGIN_LIBRARY_VERSION: 1.14
PLUGIN_AUTHOR: Alexey Botchkov (MariaDB Corporation)
PLUGIN_DESCRIPTION: MariaDB Enterprise Audit
PLUGIN_LICENSE: GPL
LOAD_OPTION: FORCE_PLUS_PERMANENT
PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 2.0.2
|
Failure Indication | If MariaDB Enterprise Audit is supposed to be enabled but |
Plugin Active
Detail | Description |
---|---|
How | With sufficient privileges, query the database server |
Sample Query | SHOW STATUS LIKE 'Server_audit_active';
|
Expected Result | If the plugin is active, the value of the |
Sample Output | +---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| Server_audit_active | ON |
+---------------------+-------+
|
Failure Indication | If MariaDB Enterprise Audit is supposed to be enabled but |
Audit Logging Enabled
Detail | Description |
---|---|
How | With sufficient privileges, query the database server |
Sample Query | SHOW VARIABLES LIKE 'server_audit_logging';
|
Expected Result | If audit logging is enabled, the value of the |
Sample Output | +----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| server_audit_logging | ON |
+----------------------+-------+
|
Failure Indication | If MariaDB Enterprise Audit is supposed to be enabled but |
Enterprise Audit Started
Detail | Description |
---|---|
How | Examine MariaDB Enterprise Server error logs |
Prior Analysis | Before examining log data, first determine the time periods subject to review. Consider whether there were periods where database server activity was not subject to audit, such as with new servers not yet housing data subject to controls. |
Log Details |
|
Expected Result | After the server start line, a line referencing |
Sample Output |
|
Failure Indication | If MariaDB Enterprise Audit was supposed to be enabled but there is no error log line noting that |
Audit Filters Loaded
Detail | Description |
---|---|
How | Examine MariaDB Enterprise Server error logs |
Log Details |
|
Sample Output |
|
Expected Result | No line states |
Failure Indication | The presence of a |
Enterprise Audit Running
Detail | Description |
---|---|
How | Examine MariaDB Enterprise Server error logs |
Log Details |
|
Sample Output |
|
Expected Result | Any line indicating |
Failure Indication | The presence of an error log line indicating |
Audit Filter Review
As needed, review Audit Filters and Audit Users:
Detail | Description |
---|---|
How | With sufficient privileges, query the database server |
Sample Output | See "Audit Filters and Audit Users" for details on how to query this information. |
Expected Result | The expected result is business-specific. |
Audit Log Review
As needed, confirm correct filter configuration:
Detail | Description |
---|---|
How | Examine MariaDB Enterprise Audit logs |
Log Details |
|
Expected Result | The expected result is business-specific. |