+++ /dev/null
-
-
-
-
pg_audit
-
-
-
-
- The pg_audit extension provides detailed session
- and/or object audit logging via the standard logging facility. The goal
- is to provide the tools needed to produce audit logs required to pass any
- government, financial, or ISO certification audit.
-
-
- An audit is an official inspection of an individual's or organization's
- accounts, typically by an independent body. The information gathered by
- pg_audit is properly called an audit trail or audit
- log. The term audit log is used in this documentation.
-
-
-
-
Why pg_audit>?
-
- Basic statement logging can be provided by the standard logging facility
- using log_statement = all>. This is acceptable for monitoring
- and other usages but does not provide the level of detail generally
- required for an audit. It is not enough to have a list of all the
- operations performed against the database. It must also be possible to
- find particular statements that are of interest to an auditor. The
- standard logging facility shows what the user requested, while
- pg_audit> focuses on the details of what happened while
- the database was satisfying the request.
-
-
- For example, an auditor may want to verify that a particular table was
- created inside a documented maintenance window. This might seem like a
- simple job for grep, but what if you are presented with something like
- this (intentionally obfuscated) example:
-
-
-DO $$
-BEGIN
- EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
-END $$;
-
-
- Standard logging will give you this:
-
-
-LOG: statement: DO $$
-BEGIN
- EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
-END $$;
-
-
- It appears that finding the table of interest may require some knowledge
- of the code in cases where tables are created dynamically. This is not
- ideal since it would be preferrable to just search on the table name.
- This is where pg_audit> comes in. For the same input,
- it will produce this output in the log:
-
-
-AUDIT: SESSION,33,1,FUNCTION,DO,,,"DO $$
-BEGIN
- EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
-END $$;"
-AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT)
-
-
- Not only is the DO> block logged, but substatement 2 contains
- the full text of the CREATE TABLE> with the statement type,
- object type, and full-qualified name to make searches easy.
-
-
- When logging SELECT> and DML> statements,
- pg_audit> can be configured to log a separate entry for each
- relation referenced in a statement. No parsing is required to find all
- statements that touch a particular table. In fact, the goal is that the
- statement text is provided primarily for deep forensics and should not be
- required for an audit.
-
-
-
-
-
Usage Considerations
-
- Depending on settings, it is possible for pg_audit to
- generate an enormous volume of logging. Be careful to determine
- exactly what needs to be audit logged in your environment to avoid
- logging too much.
-
-
- For example, when working in an OLAP environment it would probably not be
- wise to audit log inserts into a large fact table. The size of the log
- file will likely be many times the actual data size of the inserts because
- the log file is expressed as text. Since logs are generally stored with
- the OS this may lead to disk space being exhausted very
- quickly. In cases where it is not possible to limit audit logging to
- certain tables, be sure to assess the performance impact while testing
- and allocate plenty of space on the log volume. This may also be true for
- OLTP environments. Even if the insert volume is not as high, the
- performance impact of audit logging may still noticeably affect latency.
-
-
- To limit the number of relations audit logged for SELECT>
- and DML> statments, consider using object audit logging
- (see ). Object audit logging
- allows selection of the relations to be logged allowing for reduction
- of the overall log volume. However, when new relations are added they
- must be explicitly added to object audit logging. A programmatic
- solution where specified tables are excluded from logging and all others
- are included may be a good option in this case.
-
-
-
-
-
Settings
-
- Settings may be modified only by a superuser. Allowing normal users to
- change their settings would defeat the point of an audit log.
-
-
- Settings can be specified globally (in
- postgresql.conf or using
- ALTER SYSTEM ... SET>), at the database level (using
- ALTER DATABASE ... SET), or at the role level (using
- ALTER ROLE ... SET). Note that settings are not
- inherited through normal role inheritance and SET ROLE> will
- not alter a user's pg_audit> settings. This is a limitation
- of the roles system and not inherent to pg_audit>.
-
-
- The pg_audit> extension must be loaded in
- . Otherwise, an error
- will be raised at load time and no audit logging will occur.
-
-
-
-
- pg_audit.log (string)
-
-
pg_audit.log> configuration parameter
-
-
-
- Specifies which classes of statements will be logged by session
- audit logging. Possible values are:
-
-
-
-
- READ - SELECT and
- COPY when the source is a relation or a
- query.
-
-
-
- WRITE - INSERT,
- UPDATE, DELETE,
- TRUNCATE, and COPY when the
- destination is a relation.
-
-
-
- FUNCTION - Function calls and
- DO blocks.
-
-
-
- ROLE - Statements related to roles and
- privileges: GRANT,
- REVOKE,
- CREATE/ALTER/DROP ROLE.
-
-
-
- DDL - All DDL> that is not included
- in the ROLE> class.
-
-
-
- MISC - Miscellaneous commands, e.g.
- DISCARD, FETCH,
- CHECKPOINT, VACUUM.
-
-
-
-
- Multiple classes can be provided using a comma-separated list and
- classes can be subtracted by prefacing the class with a
- -> sign (see ).
- The default is none>.
-
-
-
-
-
- pg_audit.log_catalog (boolean)
-
-
pg_audit.log_catalog> configuration parameter
-
-
-
- Specifies that session logging should be enabled in the case where all
- relations in a statement are in pg_catalog. Disabling this setting
- will reduce noise in the log from tools like psql and PgAdmin that query
- the catalog heavily. The default is on>.
-
-
-
-
-
- pg_audit.log_level (boolean)
-
-
pg_audit.log_level> configuration parameter
-
-
-
- Specifies the log level that will be used for log entries (see
- for valid levels).
- This setting is used for regression testing and may also be useful
- to end users for testing or other purposes. It is not intended to
- be used in a production environment as it may leak which statements
- are being logged to the user. The default is log>.
-
-
-
-
-
- pg_audit.log_parameter (boolean)
-
-
pg_audit.log_parameter> configuration parameter
-
-
-
- Specifies that audit logging should include the parameters that
- were passed with the statement. When parameters are present they will
- be included in CSV format after the statement text. The default is
- off>.
-
-
-
-
-
- pg_audit.log_relation (boolean)
-
-
pg_audit.log_relation> configuration parameter
-
-
-
- Specifies whether session audit logging should create a separate
- log entry for each relation (TABLE>, VIEW>,
- etc.) referenced in a SELECT> or DML>
- statement. This is a useful shortcut for exhaustive logging
- without using object audit logging. The default is
- off>.
-
-
-
-
-
- pg_audit.log_statement_once (boolean)
-
-
pg_audit.log_statement_once> configuration parameter
-
-
-
- Specifies whether logging will include the statement text and
- parameters with the first log entry for a statement/substatement
- combination or with every entry. Disabling this setting will
- result in less verbose logging but may make it more difficult to
- determine the statement that generated a log entry, though the
- statement/substatement pair along with the process id should suffice
- to identify the statement text logged with a previous entry. The
- default is off>.
-
-
-
-
-
- pg_audit.role (string)
-
-
pg_audit.role> configuration parameter
-
-
-
- Specifies the master role to use for object audit logging. Muliple
- audit roles can be defined by granting them to the master role.
- This allows multiple groups to be in charge of different aspects
- of audit logging. There is no default.
-
-
-
-
-
-
-
-
Session Audit Logging
-
- Session audit logging provides detailed logs of all statements executed
- by a user in the backend.
-
-
-
-
Configuration
-
- Session logging is enabled with the
- setting.
-
- Enable session logging for all DML> and DDL> and
- log all relations in DML> statements:
-set pg_audit.log = 'write, ddl';
-set pg_audit.log_relation = on;
-
-
-
- Enable session logging for all commands except MISC> and
- raise audit log messages as NOTICE>:
-set pg_audit.log = 'all, -misc';
-set pg_audit.log_notice = on;
-
-
-
-
-
-
Example
-
- In this example session audit logging is used for logging
- DDL> and SELECT> statements. Note that the
- insert statement is not logged since the WRITE> class
- is not enabled
-
-
- SQL:
-
-set pg_audit.log = 'read, ddl';
-
-create table account
-(
- id int,
- name text,
- password text,
- description text
-);
-
-insert into account (id, name, password, description)
- values (1, 'user1', 'HASH1', 'blah, blah');
-
-select *
- from account;
-
-
- Log Output:
-
-
-AUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.account,create table account
-(
- id int,
- name text,
- password text,
- description text
-);
-AUDIT: SESSION,2,1,READ,SELECT,,,select *
- from account
-
-
-
-
-
-
Object Auditing
-
- Object audit logging logs statements that affect a particular relation.
- Only SELECT>, INSERT>, UPDATE> and
- DELETE> commands are supported. TRUNCATE> is not
- included because there is no specific privilege for it.
-
-
- Object audit logging is intended to be a finer-grained replacement for
- pg_audit.log = 'read, write'. As such, it may not
- make sense to use them in conjunction but one possible scenario would
- be to use session logging to capture each statement and then supplement
- that with object logging to get more detail about specific relations.
-
-
-
-
Configuration
-
- Object-level audit logging is implemented via the roles system. The
- setting defines the role that
- will be used for audit logging. A relation (TABLE>,
- VIEW>, etc.) will be audit logged when the audit role has
- permissions for the command executed or inherits the permissions from
- another role. This allows you to effectively have multiple audit roles
- even though there is a single master role in any context.
-
-
- Set to auditor> and
- grant SELECT> and DELETE> privileges on the
- account> table. Any SELECT> or
- DELETE> statements on account> will now be
- logged:
-
-
-set pg_audit.role = 'auditor';
-
-grant select, delete
- on public.account
- to auditor;
-
-
-
-
-
Example
-
- In this example object audit logging is used to illustrate how a
- granular approach may be taken towards logging of SELECT>
- and DML> statements. Note that logging on the
- account> table is controlled by column-level permissions,
- while logging on account_role_map> is table-level.
-
-
- SQL:
-
-
-set pg_audit.role = 'auditor';
-
-create table account
-(
- id int,
- name text,
- password text,
- description text
-);
-
-grant select (password)
- on public.account
- to auditor;
-
-select id, name
- from account;
-
-select password
- from account;
-
-grant update (name, password)
- on public.account
- to auditor;
-
-update account
- set description = 'yada, yada';
-
-update account
- set password = 'HASH2';
-
-create table account_role_map
-(
- account_id int,
- role_id int
-);
-
-grant select
- on public.account_role_map
- to auditor;
-
-select account.password,
- account_role_map.role_id
- from account
- inner join account_role_map
- on account.id = account_role_map.account_id
-
-
- Log Output:
-
-
-AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.account,select password
- from account
-AUDIT: OBJECT,2,1,WRITE,UPDATE,TABLE,public.account,update account
- set password = 'HASH2'
-AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account,select account.password,
- account_role_map.role_id
- from account
- inner join account_role_map
- on account.id = account_role_map.account_id
-AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account_role_map,select account.password,
- account_role_map.role_id
- from account
- inner join account_role_map
- on account.id = account_role_map.account_id
-
-
-
-
-
-
Format
-
- Audit entries are written to the standard logging facility and contain
- the following columns in comma-separated format:
-
-
- Output is compliant CSV format only if the log line prefix portion
- of each log entry is removed.
-
-
-
-
-
- AUDIT_TYPE> - SESSION> or
- OBJECT>.
-
-
-
- STATEMENT_ID> - Unique statement ID for this session.
- Each statement ID represents a backend call. Statement IDs are
- sequential even if some statements are not logged. There may be
- multiple entries for a statement ID when more than one relation
- is logged.
-
-
-
- SUBSTATEMENT_ID> - Sequential ID for each
- substatement within the main statement. For example, calling
- a function from a query. Substatement IDs are continuous
- even if some substatements are not logged. There may be multiple
- entries for a substatement ID when more than one relation is logged.
-
-
-
- CLASS> - e.g. (READ>,
- ROLE>) (see ).
-
-
-
- COMMAND> - e.g. ALTER TABLE>,
- SELECT>.
-
-
-
- OBJECT_TYPE> - TABLE>,
- INDEX>, VIEW>, etc.
- Available for SELECT>, DML> and most
- DDL> statements.
-
-
-
- OBJECT_NAME> - The fully-qualified object name
- (e.g. public.account). Available for SELECT>,
- DML> and most DDL> statements.
-
-
-
- STATEMENT> - Statement executed on the backend.
-
-
-
-
-
- Use to add any other fields that
- are needed to satisfy your audit log requirements. A typical log line
- prefix might be '%m %u %d: '> which would provide the date/time,
- user name, and database name for each audit log.
-
-
-
-
-
Caveats
-
-
-
- Object renames are logged under the name they were renamed to.
- For example, renaming a table will produce the following result:
-
-
-ALTER TABLE test RENAME TO test2;
-
-AUDIT: SESSION,36,1,DDL,ALTER TABLE,TABLE,public.test2,ALTER TABLE test RENAME TO test2
-
-
-
-
- It is possible to have a command logged more than once. For example,
- when a table is created with a primary key specified at creation time
- the index for the primary key will be logged independently and another
- audit log will be made for the index under the create entry. The
- multiple entries will however be contained within one statement ID.
-
-
-
-
- Autovacuum and Autoanalyze are not logged.
-
-
-
-
- Statements that are executed after a transaction enters an aborted state
- will not be audit logged. However, the statement that caused the error
- and any subsequent statements executed in the aborted transaction will
- be logged as ERRORs by the standard logging facility.
-
-
-
-
-
-
-
Authors
-
-
-
-