mirror of
https://github.com/postgres/postgres.git
synced 2025-04-20 00:42:27 +03:00
Finish removing pg_audit
This commit is contained in:
parent
0381fefaa4
commit
cde9cf170c
@ -28,7 +28,6 @@ SUBDIRS = \
|
|||||||
oid2name \
|
oid2name \
|
||||||
pageinspect \
|
pageinspect \
|
||||||
passwordcheck \
|
passwordcheck \
|
||||||
pg_audit \
|
|
||||||
pg_buffercache \
|
pg_buffercache \
|
||||||
pg_freespacemap \
|
pg_freespacemap \
|
||||||
pg_prewarm \
|
pg_prewarm \
|
||||||
|
@ -1,678 +0,0 @@
|
|||||||
<!-- doc/src/sgml/pgaudit.sgml -->
|
|
||||||
|
|
||||||
<sect1 id="pgaudit" xreflabel="pgaudit">
|
|
||||||
<title>pg_audit</title>
|
|
||||||
|
|
||||||
<indexterm zone="pgaudit">
|
|
||||||
<primary>pg_audit</primary>
|
|
||||||
</indexterm>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The <filename>pg_audit</filename> 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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
An audit is an official inspection of an individual's or organization's
|
|
||||||
accounts, typically by an independent body. The information gathered by
|
|
||||||
<filename>pg_audit</filename> is properly called an audit trail or audit
|
|
||||||
log. The term audit log is used in this documentation.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>Why <literal>pg_audit</>?</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Basic statement logging can be provided by the standard logging facility
|
|
||||||
using <literal>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
|
|
||||||
<literal>pg_audit</> focuses on the details of what happened while
|
|
||||||
the database was satisfying the request.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
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:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
DO $$
|
|
||||||
BEGIN
|
|
||||||
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
|
|
||||||
END $$;
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Standard logging will give you this:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
LOG: statement: DO $$
|
|
||||||
BEGIN
|
|
||||||
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
|
|
||||||
END $$;
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
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 <literal>pg_audit</> comes in. For the same input,
|
|
||||||
it will produce this output in the log:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
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)
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Not only is the <literal>DO</> block logged, but substatement 2 contains
|
|
||||||
the full text of the <literal>CREATE TABLE</> with the statement type,
|
|
||||||
object type, and full-qualified name to make searches easy.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
When logging <literal>SELECT</> and <literal>DML</> statements,
|
|
||||||
<literal>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.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>Usage Considerations</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Depending on settings, it is possible for <literal>pg_audit</literal> 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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
To limit the number of relations audit logged for <literal>SELECT</>
|
|
||||||
and <literal>DML</> statments, consider using object audit logging
|
|
||||||
(see <xref linkend="pgaudit-object-audit-logging">). 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.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>Settings</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Settings may be modified only by a superuser. Allowing normal users to
|
|
||||||
change their settings would defeat the point of an audit log.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Settings can be specified globally (in
|
|
||||||
<filename>postgresql.conf</filename> or using
|
|
||||||
<literal>ALTER SYSTEM ... SET</>), at the database level (using
|
|
||||||
<literal>ALTER DATABASE ... SET</literal>), or at the role level (using
|
|
||||||
<literal>ALTER ROLE ... SET</literal>). Note that settings are not
|
|
||||||
inherited through normal role inheritance and <literal>SET ROLE</> will
|
|
||||||
not alter a user's <literal>pg_audit</> settings. This is a limitation
|
|
||||||
of the roles system and not inherent to <literal>pg_audit</>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The <literal>pg_audit</> extension must be loaded in
|
|
||||||
<xref linkend="guc-shared-preload-libraries">. Otherwise, an error
|
|
||||||
will be raised at load time and no audit logging will occur.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry id="guc-pgaudit-log" xreflabel="pg_audit.log">
|
|
||||||
<term><varname>pg_audit.log</varname> (<type>string</type>)
|
|
||||||
<indexterm>
|
|
||||||
<primary><varname>pg_audit.log</> configuration parameter</primary>
|
|
||||||
</indexterm>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Specifies which classes of statements will be logged by session
|
|
||||||
audit logging. Possible values are:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>READ</literal> - <literal>SELECT</literal> and
|
|
||||||
<literal>COPY</literal> when the source is a relation or a
|
|
||||||
query.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>WRITE</literal> - <literal>INSERT</literal>,
|
|
||||||
<literal>UPDATE</literal>, <literal>DELETE</literal>,
|
|
||||||
<literal>TRUNCATE</literal>, and <literal>COPY</literal> when the
|
|
||||||
destination is a relation.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>FUNCTION</literal> - Function calls and
|
|
||||||
<literal>DO</literal> blocks.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>ROLE</literal> - Statements related to roles and
|
|
||||||
privileges: <literal>GRANT</literal>,
|
|
||||||
<literal>REVOKE</literal>,
|
|
||||||
<literal>CREATE/ALTER/DROP ROLE</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>DDL</literal> - All <literal>DDL</> that is not included
|
|
||||||
in the <literal>ROLE</> class.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>MISC</literal> - Miscellaneous commands, e.g.
|
|
||||||
<literal>DISCARD</literal>, <literal>FETCH</literal>,
|
|
||||||
<literal>CHECKPOINT</literal>, <literal>VACUUM</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Multiple classes can be provided using a comma-separated list and
|
|
||||||
classes can be subtracted by prefacing the class with a
|
|
||||||
<literal>-</> sign (see <xref linkend="pgaudit-session-audit-logging">).
|
|
||||||
The default is <literal>none</>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-catalog" xreflabel="pg_audit.log_catalog">
|
|
||||||
<term><varname>pg_audit.log_catalog</varname> (<type>boolean</type>)
|
|
||||||
<indexterm>
|
|
||||||
<primary><varname>pg_audit.log_catalog</> configuration parameter</primary>
|
|
||||||
</indexterm>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
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 <literal>on</>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-level" xreflabel="pg_audit.log_level">
|
|
||||||
<term><varname>pg_audit.log_level</varname> (<type>boolean</type>)
|
|
||||||
<indexterm>
|
|
||||||
<primary><varname>pg_audit.log_level</> configuration parameter</primary>
|
|
||||||
</indexterm>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Specifies the log level that will be used for log entries (see
|
|
||||||
<xref linkend="RUNTIME-CONFIG-SEVERITY-LEVELS"> 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 <literal>log</>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-parameter" xreflabel="pg_audit.log_parameter">
|
|
||||||
<term><varname>pg_audit.log_parameter</varname> (<type>boolean</type>)
|
|
||||||
<indexterm>
|
|
||||||
<primary><varname>pg_audit.log_parameter</> configuration parameter</primary>
|
|
||||||
</indexterm>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
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
|
|
||||||
<literal>off</>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-relation" xreflabel="pg_audit.log_relation">
|
|
||||||
<term><varname>pg_audit.log_relation</varname> (<type>boolean</type>)
|
|
||||||
<indexterm>
|
|
||||||
<primary><varname>pg_audit.log_relation</> configuration parameter</primary>
|
|
||||||
</indexterm>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Specifies whether session audit logging should create a separate
|
|
||||||
log entry for each relation (<literal>TABLE</>, <literal>VIEW</>,
|
|
||||||
etc.) referenced in a <literal>SELECT</> or <literal>DML</>
|
|
||||||
statement. This is a useful shortcut for exhaustive logging
|
|
||||||
without using object audit logging. The default is
|
|
||||||
<literal>off</>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-statement-once" xreflabel="pg_audit.log_statement-once">
|
|
||||||
<term><varname>pg_audit.log_statement_once</varname> (<type>boolean</type>)
|
|
||||||
<indexterm>
|
|
||||||
<primary><varname>pg_audit.log_statement_once</> configuration parameter</primary>
|
|
||||||
</indexterm>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
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 <literal>off</>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-role" xreflabel="pg_audit.role">
|
|
||||||
<term><varname>pg_audit.role</varname> (<type>string</type>)
|
|
||||||
<indexterm>
|
|
||||||
<primary><varname>pg_audit.role</> configuration parameter</primary>
|
|
||||||
</indexterm>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
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.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="pgaudit-session-audit-logging">
|
|
||||||
<title>Session Audit Logging</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Session audit logging provides detailed logs of all statements executed
|
|
||||||
by a user in the backend.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<sect3>
|
|
||||||
<title>Configuration</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Session logging is enabled with the <xref linkend="guc-pgaudit-log">
|
|
||||||
setting.
|
|
||||||
|
|
||||||
Enable session logging for all <literal>DML</> and <literal>DDL</> and
|
|
||||||
log all relations in <literal>DML</> statements:
|
|
||||||
<programlisting>
|
|
||||||
set pg_audit.log = 'write, ddl';
|
|
||||||
set pg_audit.log_relation = on;
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Enable session logging for all commands except <literal>MISC</> and
|
|
||||||
raise audit log messages as <literal>NOTICE</>:
|
|
||||||
<programlisting>
|
|
||||||
set pg_audit.log = 'all, -misc';
|
|
||||||
set pg_audit.log_notice = on;
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
</sect3>
|
|
||||||
|
|
||||||
<sect3>
|
|
||||||
<title>Example</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In this example session audit logging is used for logging
|
|
||||||
<literal>DDL</> and <literal>SELECT</> statements. Note that the
|
|
||||||
insert statement is not logged since the <literal>WRITE</> class
|
|
||||||
is not enabled
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
SQL:
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
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;
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Log Output:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
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
|
|
||||||
</programlisting>
|
|
||||||
</sect3>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="pgaudit-object-audit-logging">
|
|
||||||
<title>Object Auditing</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Object audit logging logs statements that affect a particular relation.
|
|
||||||
Only <literal>SELECT</>, <literal>INSERT</>, <literal>UPDATE</> and
|
|
||||||
<literal>DELETE</> commands are supported. <literal>TRUNCATE</> is not
|
|
||||||
included because there is no specific privilege for it.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Object audit logging is intended to be a finer-grained replacement for
|
|
||||||
<literal>pg_audit.log = 'read, write'</literal>. 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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<sect3>
|
|
||||||
<title>Configuration</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Object-level audit logging is implemented via the roles system. The
|
|
||||||
<xref linkend="guc-pgaudit-role"> setting defines the role that
|
|
||||||
will be used for audit logging. A relation (<literal>TABLE</>,
|
|
||||||
<literal>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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Set <xref linkend="guc-pgaudit-role"> to <literal>auditor</> and
|
|
||||||
grant <literal>SELECT</> and <literal>DELETE</> privileges on the
|
|
||||||
<literal>account</> table. Any <literal>SELECT</> or
|
|
||||||
<literal>DELETE</> statements on <literal>account</> will now be
|
|
||||||
logged:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
set pg_audit.role = 'auditor';
|
|
||||||
|
|
||||||
grant select, delete
|
|
||||||
on public.account
|
|
||||||
to auditor;
|
|
||||||
</programlisting>
|
|
||||||
</sect3>
|
|
||||||
|
|
||||||
<sect3>
|
|
||||||
<title>Example</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In this example object audit logging is used to illustrate how a
|
|
||||||
granular approach may be taken towards logging of <literal>SELECT</>
|
|
||||||
and <literal>DML</> statements. Note that logging on the
|
|
||||||
<literal>account</> table is controlled by column-level permissions,
|
|
||||||
while logging on <literal>account_role_map</> is table-level.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
SQL:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
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
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Log Output:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
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
|
|
||||||
</programlisting>
|
|
||||||
</sect3>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>Format</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Audit entries are written to the standard logging facility and contain
|
|
||||||
the following columns in comma-separated format:
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>
|
|
||||||
Output is compliant CSV format only if the log line prefix portion
|
|
||||||
of each log entry is removed.
|
|
||||||
</para>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>AUDIT_TYPE</> - <literal>SESSION</> or
|
|
||||||
<literal>OBJECT</>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>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.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>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.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>CLASS</> - e.g. (<literal>READ</>,
|
|
||||||
<literal>ROLE</>) (see <xref linkend="guc-pgaudit-log">).
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>COMMAND</> - e.g. <literal>ALTER TABLE</>,
|
|
||||||
<literal>SELECT</>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>OBJECT_TYPE</> - <literal>TABLE</>,
|
|
||||||
<literal>INDEX</>, <literal>VIEW</>, etc.
|
|
||||||
Available for <literal>SELECT</>, <literal>DML</> and most
|
|
||||||
<literal>DDL</> statements.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>OBJECT_NAME</> - The fully-qualified object name
|
|
||||||
(e.g. public.account). Available for <literal>SELECT</>,
|
|
||||||
<literal>DML</> and most <literal>DDL</> statements.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>STATEMENT</> - Statement executed on the backend.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Use <xref linkend="guc-log-line-prefix"> to add any other fields that
|
|
||||||
are needed to satisfy your audit log requirements. A typical log line
|
|
||||||
prefix might be <literal>'%m %u %d: '</> which would provide the date/time,
|
|
||||||
user name, and database name for each audit log.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>Caveats</title>
|
|
||||||
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Object renames are logged under the name they were renamed to.
|
|
||||||
For example, renaming a table will produce the following result:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
ALTER TABLE test RENAME TO test2;
|
|
||||||
|
|
||||||
AUDIT: SESSION,36,1,DDL,ALTER TABLE,TABLE,public.test2,ALTER TABLE test RENAME TO test2
|
|
||||||
</programlisting>
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
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.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Autovacuum and Autoanalyze are not logged.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
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.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>Authors</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Abhijit Menon-Sen <email>ams@2ndQuadrant.com</email>, Ian Barwick <email>ian@2ndQuadrant.com</email>, and David Steele <email>david@pgmasters.net</email>.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
Loading…
x
Reference in New Issue
Block a user