Postgres как управляемый источник контекста
Коннектор содержимого postgres (olivares.pg-content) позволяет направить
control plane на базу PostgreSQL и превратить её строки в управляемые документы
знаний. Они проходят тот же pipeline, что и любой другой источник содержимого:
redact → classify → chunk → embed → index → предоставление через MCP, с ACL для
каждого документа и классификацией для каждого столбца.
Для операционных баз это аналог источников содержимого SaaS/хранилищ данных (gdrive, confluence, s3content, snowflake…). Но он не является двумя вещами:
- Не
pgaudit.pgauditнаблюдает рёбра доступа R/RW для карты доступа, но никогда не читает содержимое строк.pg-contentматериализует строки как документы. Это разные коннекторы для разных задач. - Не NL-to-SQL. Этот коннектор загружает строки как содержимое и не генерирует SQL из естественного языка во время запроса. (Некоторые конкуренты называют функцию text-to-SQL «базой знаний со структурированными данными», но это поверхность запросов агента, а не управляемый источник содержимого. Этот коннектор намеренно является вторым.)
Только чтение по конструкции
Заголовок раздела «Только чтение по конструкции»Коннектор никогда не пишет в вашу базу и принуждает это на трёх независимых уровнях, чтобы запись была невозможной, а не просто нежелательной:
- Только запросы SELECT. Коннектор всегда строит лишь выражения
SELECT. Если вы задаёте свойquery, он проверяется как единственный запросSELECT/WITHтолько для чтения. Второе выражение, изменяющий данные CTE (WITH x AS (DELETE …)),COPY,SELECT … INTOили любой DDL отклоняются deny-closed приOpen. - Сессия только для чтения. Каждое выражение выполняется в транзакции
READ ONLYв сессии, открытой сdefault_transaction_read_only = on, поэтому PostgreSQL сам отказывает в записи. ПриOpenконнектор проверяет, что сессия доступна только для чтения, и отказывается запускаться в противном случае. Это гарантия постуры, а не совет. - Роль с минимальными привилегиями. Вы выдаёте коннектору роль, имеющую
SELECTи ничего больше. См. эталонную роль ниже.
Эта защита сильнее, чем у всех управляемых конкурирующих сервисов, которые в документации представляют чтение без записи лишь как рекомендацию.
Роль с минимальными привилегиями
Заголовок раздела «Роль с минимальными привилегиями»CREATE ROLE olivares_ro LOGIN PASSWORD '…';GRANT USAGE ON SCHEMA public TO olivares_ro;GRANT SELECT ON ALL TABLES IN SCHEMA public TO olivares_ro;ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO olivares_ro;-- Never grant INSERT/UPDATE/DELETE/DDL. Optionally pin the role read-only:ALTER ROLE olivares_ro SET default_transaction_read_only = on;Для самой узкой области выдайте SELECT только на таблицы, которые хотите
загружать.
Определите превращение строки в документ
Заголовок раздела «Определите превращение строки в документ»Определение документа декларативно: вы указываете столбцы ключа, тела, заголовка, ACL, классификации и курсора синхронизации:
// OLIVARES_SOURCES_CONFIG — document sources live under "documents"{ "documents": [ { "name": "support-articles", "kind": "postgres", "config": { "mode": "live", "dsn": "vault:secret/data/pg-ro#dsn", // secret-store REFERENCE, never inline "schema": "public", "table": "kb_articles", "key_columns": "id", // the stable document id "body_columns": "title,body", // concatenated into the document body "title_column": "title", "updated_at_column": "updated_at", // drives incremental (delta) sync "acl_columns": "owner_group", // → ACL "group:<value>" "acl_prefix": "group:", "classification_column": "sensitivity", "sensitive_columns": "email,ssn", // → external label "pii:<column>" "sensitive_label": "pii", "metadata_columns": "url_path", "sslmode": "require", "statement_timeout": "30s", "max_rows": "100000" } } ]}Вместо table можно указать query только для чтения (проверенный SELECT),
например, чтобы присоединить таблицу ACL или отфильтровать публикуемые строки.
Учётные данные всегда задаются ссылкой на хранилище секретов (vault:…,
aws-secretsmanager:… и т. п.); секрет открытым текстом отклоняется.
Честное отображение ACL
Заголовок раздела «Честное отображение ACL»Коннектор отображает только то, что выражает строка. ACL документа строится
из значений объявленных acl_columns (например, столбец owner_group →
group:eng). Коннектор не выдумывает ACL для строки, которой нет в
источнике, и явно указывает ограничения:
| Ситуация | Действие коннектора |
|---|---|
Столбец owner_group / роли | Каждое значение отображается в ссылку ACL (<acl_prefix><value>). |
acl_columns не объявлены | Документ наследует ACL по умолчанию базы знаний, и извлечение по-прежнему её принуждает. |
| Row-level security (RLS) таблицы | Неявно соблюдается: роль коннектора видит ровно те строки, которые ей разрешает RLS. Коннектор не реализует RLS повторно, а наследует её. |
| Разрешение, которое таблица не моделирует столбцом | Невыводимо → не отображается. Если его нужно принуждать, смоделируйте столбец (или присоедините таблицу ACL через query). |
В этом намеренное отличие от управляемых конкурентов, которые заставляют вручную создавать столбцы ACL и не предлагают passthrough RLS. Здесь столбцы ACL тоже отображаются вручную, но коннектор дополнительно соблюдает RLS и никогда не фабрикует отсутствующие в строке разрешения.
Классификация столбцов
Заголовок раздела «Классификация столбцов»Перечислите чувствительные столбцы в sensitive_columns. Если в одном из них у
строки есть значение, документ получает внешнюю метку
"<sensitive_label>:<column>" (например, pii:ssn). Эти метки поступают в DLP
извлечения и принуждаются deny-closed вместе с classification_column строки.
Live и export
Заголовок раздела «Live и export»mode: liveчитает базу через пул только для чтения и поддерживает инкрементальную (delta) синхронизацию по курсоруupdated_at_column. Если курсор не настроен, fallback — сверка полного списка.mode: exportразбирает статический снимок строк (созданный вами вне системы JSON dump). Снимок никогда не представляется как live: источник честно сообщает свой режим.
Честные ограничения
Заголовок раздела «Честные ограничения»- Тело документа ограничено 1 МиБ; более крупная строка обрезается (streaming очень больших столбцов — последующая работа).
- В заданном оператором
queryстолбцу с именем, буквально совпадающим с ключевым словом SQL (например,update), нужен alias: гейт только для чтения работает deny-closed. - Коннектор читает содержимое; действия над базой вне области (пути записи нет по конструкции), как и CDC streaming и NL-to-SQL.
Доказательство на реальном соединении
Заголовок раздела «Доказательство на реальном соединении»Коннектор поставляется с E2E на реальном соединении (-tags e2e, CI), который
работает с настоящей PostgreSQL: проверяет сессию только для чтения при Open,
загружает подготовленные строки с отображёнными ACL/классификацией и доказывает,
что PostgreSQL отклоняет запись в сессии только для чтения. См.
connectors/pgcontent/testdata/docker-compose.e2e.yml.