Перейти к содержимому

PostgreSQL pgAudit (чистый уровень R/RW)

Источник pgaudit превращает собственный журнал аудита PostgreSQL в рёбра карты доступа: одно ребро на каждый аудированный доступ к данным, причём режим чтения/записи берётся дословно из поля CLASS pgAudit — никогда не выводится из текста SQL. Это канонический источник чистого уровня: объектное/реляционное хранилище, которое классифицирует доступ в своём собственном журнале.

Коннектор работает только на чтение поверх файла журнала. Он никогда не подключается к базе данных, никогда не видит результаты запросов и никогда не захватывает тело SQL — личность, объект и классификация целиком являются собственным выводом pgAudit.

ПолеЗначение
Источник сигналаpg_audit
Режимиз CLASS, дословно: READ → read, WRITE → write, DDL → write (запись схемы), FUNCTION → unknown (pgAudit не сообщает); ROLE/MISC пропускаются, а не угадываются
Инициаторapplication_name, если присутствует (→ attributed), иначе роль сессии
Достоверностьattributed или approximate для ролей/приложений, объявленных вами общими
Уровень покрытияclean

1. Включите pgAudit, структурированные журналы, UTC

Заголовок раздела «1. Включите pgAudit, структурированные журналы, UTC»

На стороне PostgreSQL (стандартная настройка pgAudit — см. документацию pgAudit для вашей мажорной версии):

# postgresql.conf
shared_preload_libraries = 'pgaudit'
pgaudit.log = 'read, write' # the classes this source consumes
logging_collector = on
log_destination = 'csvlog' # or 'jsonlog' (PostgreSQL 15+)
log_timezone = 'UTC' # REQUIRED — see below

Два ограничения вытекают из того, как коннектор парсит, оба проверены по его реализации:

  • Сервер должен вести журнал в UTC. PostgreSQL записывает временные метки с аббревиатурой зоны, а не-UTC-аббревиатуру нельзя надёжно разрешить в смещение — поэтому коннектор пропускает такие записи, а не угадывает неверную метку времени. log_timezone = 'UTC' — поддерживаемая конфигурация.
  • csvlog — это пакет; jsonlog может отслеживаться. Записи csvlog могут занимать несколько строк, поэтому этот формат читается пакетом на каждом проходе; jsonlog разделён по строкам и поддерживает непрерывное чтение хвоста (follow, по умолчанию).

Чтобы атрибуция была чёткой, заставьте приложения устанавливать application_name на каждого агента — именно это повышает ребро с общей роли до атрибутированного инициатора (см. зависимость от личности).

В вашей конфигурации источников (OLIVARES_SOURCES_CONFIG):

{
"sources": [{
"name": "salesdb-pgaudit",
"kind": "pgaudit",
"tenant": "<tenant-id>",
"config": {
"log_path": "/var/log/postgresql/postgresql.csv",
"format": "csvlog",
"shared_accounts": "etl_role,app_pool"
}
}]
}

Ключи конфигурации (из поставляемого дескриптора коннектора):

КлючОбязателенПо умолчаниюЗначение
log_pathдапуть к файлу журнала PostgreSQL, который может читать хост движка
formatнетcsvlogcsvlog или jsonlog
followнетtrueнепрерывно читать хвост (только jsonlog — csvlog пакетный)
shared_accountsнетроли / application_names через запятую, являющиеся общими; их рёбра честно помечаются как approximate

Перезапустите движок и подтвердите строку загрузки ingest: wired source … kind=pgaudit.

Откройте Access map. Каждый аудированный доступ отображается как ребро от роли или приложения к таблице, окрашенное в чтение или запись, со значком покрытия CLEAN на ресурсах Postgres. Панель Permitted vs observed выводит любой доступ без соответствующего гранта — при подключённом pgAudit и пока не объявленных грантах каждый наблюдаемый доступ является честным дрейфом, что и есть ожидаемое первое состояние.

  • Он видит то, что логирует pgAudit. Классы, которые вы не включаете (pgaudit.log), не наблюдаются; отсутствие рёбер не является доказательством отсутствия доступа, если класс выключен.
  • Атрибуция принадлежит базе данных. Общая роль без application_name схлопывает вызывающих в одну личность — объявите её в shared_accounts, чтобы карта говорила approximate вместо притворства.
  • FUNCTION — это unknown по замыслу — выполнение функции может читать или писать, и pgAudit не сообщает, что именно; продукт не станет навязывать метку. Не-данные классы (ROLE, MISC) пропускаются, а не эмитируются как бессмысленные рёбра.