8 мин

Доступ к базе PostgreSQL для AI-конструкторов приложений

Настройте доступ AI-конструктора приложений к PostgreSQL: обнаружение только для чтения, ограниченные учетные данные, утвержденные миграции и безопасный пул подключений.

Доступ к базе PostgreSQL для AI-конструкторов приложений

AI-конструктор приложений может подключаться к существующей базе PostgreSQL, не владея ее схемой, но только если вы реально закрепите эту границу в PostgreSQL. Подсказка «не меняй продакшен» не служит контролем. Контролем служат отдельная роль, настройки транзакций по умолчанию, явная проверка миграций и проверки схемы.

Безопасная модель делит работу с базой на три направления. Обнаружение читает метаданные и разрешенные образцы данных. Приложение читает и записывает только те таблицы и выполняет только те операции, которые ему нужны. Изменение схемы идет через отдельную учетную запись миграций после того, как человек утвердит точный SQL. Я видел, как команды сводили эти направления к одним удобным учетным данным владельца, а потом обнаруживали, что агент принял правдоподобное имя столбца за разрешение переделать рабочую таблицу. Удобство продержалось один день, исправление последствий заняло гораздо больше времени.

Обнаружение должно быть только для чтения по своей конструкции

Подключению для обнаружения нужен доступ, достаточный для понимания разрешенной схемы, но недостаточный для ее «улучшения». Создайте роль входа, которая не может создавать базы или роли, не может обходить защиту строк и не наследует неожиданные права от широкой группы. PostgreSQL создает новые роли без этих возможностей, но явные настройки позволяют проверить намерение.

CREATE ROLE app_discovery
  LOGIN
  NOSUPERUSER
  NOCREATEDB
  NOCREATEROLE
  NOINHERIT
  NOBYPASSRLS
  CONNECTION LIMIT 3
  PASSWORD 'replace-through-secret-manager';

ALTER ROLE app_discovery SET default_transaction_read_only = on;
GRANT CONNECT ON DATABASE customer_portal TO app_discovery;
GRANT USAGE ON SCHEMA app TO app_discovery;
GRANT SELECT ON ALL TABLES IN SCHEMA app TO app_discovery;

default_transaction_read_only блокирует обычную запись в сессиях, которые сохраняют настройку по умолчанию. Это полезный ремень, но не подтяжки. Отсутствие INSERT, UPDATE, DELETE, TRUNCATE, CREATE и владения объектами удерживает роль в рамках, если клиент поменяет настройку транзакции. Не добавляйте роль в группу владельцев приложения и не делайте ее владельцем схемы.

Перед подключением конструктора проверьте существующие права. Следующий запрос выводит по одной строке на каждое право для таблицы, поэтому проверяющий заметит все, что выходит за пределы SELECT:

SELECT table_schema, table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee = 'app_discovery'
ORDER BY table_schema, table_name, privilege_type;

Нормальный результат выглядит как app | invoices | SELECT. Пустой результат может означать, что обнаружение не видит нужную таблицу, а строка с UPDATE в конце означает, что у роли слишком много прав. Также проверьте права на схемы через has_schema_privilege и права на базу через has_database_privilege, потому что права на таблицы не показывают, может ли роль создавать объекты где-то еще.

Не используйте снимок продакшена как повод делиться учетными данными владельца. Копия все равно может содержать данные клиентов, а агент с правами владельца может изменить ее настолько, что последующие сравнения потеряют смысл. Дайте обнаружению отдельную учетную запись в каждом окружении.

Проверка каталога должна оставаться в списке разрешенных объектов

Конструктор должен обнаруживать только утвержденные схемы и сохранять то, что реально сообщает PostgreSQL. information_schema дает переносимые представления для таблиц, столбцов, ограничений и прав. pg_catalog показывает детали PostgreSQL: индексы, типы, сгенерированные выражения и защиту строк. Оба источника надежнее, чем память LLM о типичной таблице клиентов.

Начните со списка разрешенных схем, например app и reporting. Не допускайте pg_catalog, information_schema, временные схемы, схемы расширений и любые неуказанные схемы арендаторов в качестве целей приложения. Запрос должен фильтровать на уровнях базы, роли и SQL: список разрешений только в подсказке может исчезнуть в следующем чате.

SELECT
  c.table_schema,
  c.table_name,
  c.ordinal_position,
  c.column_name,
  c.data_type,
  c.is_nullable,
  c.column_default
FROM information_schema.columns AS c
WHERE c.table_schema IN ('app', 'reporting')
ORDER BY c.table_schema, c.table_name, c.ordinal_position;

Сохраните результат как снимок схемы со временем получения и идентификатором базы данных. Снимок служит свидетельством того, что видел генератор. Это не вечная истина. PostgreSQL может измениться между обнаружением и генерацией кода, поэтому перед развертыванием сравнивайте свежий слепок. Практичный слепок может хешировать упорядоченные описания таблиц, столбцов, типов, допуска NULL, значений по умолчанию, ограничений и индексов. Если слепки различаются, остановитесь и повторите обнаружение вместо догадок о безвредности изменения.

Получение образцов строк требует отдельного решения о правах. Метаданные столбцов редко содержат персональные данные, а образцы строк часто содержат. Для генерации кода лучше вообще не брать строки. Если примеры необходимы, откройте представление, которое удаляет или маскирует секреты и прямые идентификаторы, и выдайте SELECT только на это представление. LIMIT 10 не делает конфиденциальный запрос безопасным, он лишь уменьшает утечку.

search_path требует такого же подхода. Установите в нем утвержденную схему и pg_catalog, квалифицируйте имена сгенерированных таблиц и никогда не полагайтесь на объект, который PostgreSQL найдет первым. Злоумышленник или неосторожная миграция могут создать одноименный объект в доступной для записи схеме. Квалифицированные имена вроде app.orders убирают эту неоднозначность.

Роль времени выполнения должна соответствовать реальным действиям пользователя

Обнаружение и работа приложения решают разные задачи. Рабочему приложению может понадобиться добавить заказ, обновить черновик или вызвать тщательно спроектированную функцию, но это не оправдывает широкие права на запись во всей обнаруженной схеме. Составьте матрицу прав по действиям пользователя, затем переведите каждое действие в минимально необходимое право PostgreSQL.

Например, средству просмотра счетов могут понадобиться SELECT для app.invoices и app.invoice_lines, а функции заметок понадобятся SELECT и INSERT для app.invoice_notes. Ему вряд ли нужны DELETE для счетов, доступ к записям сброса паролей или создание схемы. Выдавайте право на последовательность, только если вставка действительно от нее зависит. PostgreSQL считает последовательности отдельными объектами, и это часто удивляет генераторы, которые тестируют код с учетной записью владельца.

Представления и функции помогают еще сильнее сузить поверхность доступа. Представление может показывать утвержденные столбцы и скрывать внутренние поля. Функция SECURITY DEFINER может выполнить одну контролируемую операцию, которую нельзя выразить обычными правами, но ей нужны фиксированный search_path, строгая проверка входных данных и владелец без лишних полномочий. Считайте такую функцию привилегированным кодом, а не обходом модели прав.

Защита на уровне строк добавляет границу данных внутри общей таблицы. Она не заменяет права на таблицу. PostgreSQL сначала проверяет, может ли роль выполнить операцию, а затем применяет политики защиты строк, если они включены и применимы. Тестируйте с точной рабочей ролью, потому что владельцы таблиц и роли с BYPASSRLS могут обходить политики. Проверка под владельцем миграций почти ничего не доказывает о том, что увидит конечный пользователь.

Не включайте секреты в подсказки, сгенерированный исходный код, сборки для браузера, журналы сборки и снимки экрана. Храните рабочие учетные данные в хранилище секретов среды хостинга и передавайте их только серверному процессу. Мобильные и браузерные приложения не могут надежно хранить пароль PostgreSQL, поэтому должны вызывать серверный API, а не подключаться напрямую. Ротируйте учетные данные обнаружения, работы приложения и миграций независимо друг от друга: утечка в одном направлении не должна открывать два других.

Полномочия для миграций должны идти по отдельному пути утверждения

Конструктор приложений может предлагать миграции, но не должен выполнять их через сессию обнаружения или работы приложения. Дайте миграциям отдельную роль или позвольте существующей системе развертывания получать эту роль для одной утвержденной задачи. Не предоставляйте ее учетные данные во время обычных чатов и предпросмотров.

Утверждение должно охватывать точный SQL, идентификатор целевой базы, слепок схемы, использованный для подготовки, и ожидаемое поведение блокировок или переписывания. Утверждение фразы на естественном языке вроде «добавить статус клиента» оставляет слишком много пространства для трактовок. Исполнимое изменение может добавить допускающий NULL текстовый столбец, перестроить большую таблицу, придумать enum или обновить все существующие строки. Это разные операции с разными сбоями.

Я использую компактный пакет миграции:

  1. Причина изменения и версия приложения, которой оно требуется.
  2. Точный прямой SQL и, если это честно возможно, точный обратный SQL.
  3. Объекты, права и строки, на которые могут повлиять команды.
  4. Предварительные запросы, ожидаемые результаты и свежий слепок схемы.
  5. Тайм-аут блокировки, тайм-аут оператора, ссылка на резервную копию или снимок и владелец релиза.

Скрипт отмены не всегда служит откатом. Удаление только что добавленного столбца может отменить изменение каталога, но также уничтожит данные, записанные после релиза. Транзакционный DDL PostgreSQL помогает со многими операциями каталога, но транзакция не восстановит внешние последствия или данные, удаленные последующей командой. Ясно помечайте разрушительные отмены вместо отношения к DOWN как к волшебному слову.

Установите lock_timeout, чтобы миграция завершалась ошибкой, а не ждала занятую транзакцию, блокируя новую работу. Установите statement_timeout по проверенной операции. Снова выполните предварительные запросы в окне изменения. Если размер таблицы, конфликтующие объекты, число NULL или слепок схемы отличаются от утвержденных предположений, прервите работу. Агент должен вернуть отчет о несоответствии, а не импровизировать новую миграцию против продакшена.

Никогда не утверждайте миграцию автоматически только потому, что прошли сгенерированные тесты. Обычно тесты работают на небольшой чистой схеме и не видят очередей блокировок, старых NULL, необычных ограничений, расширений и версий приложения, которые еще обслуживают трафик. При утверждении человек сопоставляет сгенерированное намерение с работающей системой.

Пул подключений меняет расчет безопасности

Отделите планирование от развертывания
Прорабатывайте изменения базы в режиме планирования до развертывания и хостинга в Koder.ai.

Пул повторно использует сессии базы, поэтому состояние сессии может пережить запрос, который его создал. Если один запрос выполняет SET search_path, меняет роль, создает временный объект или отключает тайм-аут, следующий клиент может унаследовать результат. Приложение должно либо избегать изменяемого состояния сессии, либо надежно сбрасывать его при возврате подключения в пул.

Пул транзакций делает границу строже. После каждой транзакции клиент может получить другую серверную сессию, поэтому ломаются предположения о подготовленных операторах сессии, временных таблицах, рекомендательных блокировках и настройках уровня сессии. Конструкторы часто генерируют код, который работает через прямое подключение и ломается за пулом, потому что не моделируют это различие. Решите, использует ли пул режим сессий или транзакций, и включите этот режим в генерацию и тесты.

До развертывания рассчитайте бюджет подключений. Начните с разрешенного базой числа подключений, оставьте запас для администрирования, миграций, мониторинга и других сервисов, затем разделите остаток между экземплярами приложения. Если десять экземпляров открывают по двадцать подключений, PostgreSQL видит двести возможных сессий даже при тихом трафике. Осторожный небольшой пул с очередью обычно безопаснее, чем умножать подключения, пока база не начнет их отклонять.

Используйте серверные тайм-ауты как страховку: statement_timeout ограничивает долгие операторы, lock_timeout ограничивает ожидание блокировок, а idle_in_transaction_session_timeout убирает сессии, которые держат транзакцию открытой и ничего не делают. Задавайте значения для каждой роли, а не надейтесь, что каждый сгенерированный клиент не забудет об этом. Проверяйте их через SHOW под реальной ролью и через реальный пул.

Проверки работоспособности должны быть недорогими. SELECT 1 подтверждает прохождение запроса, но не подтверждает, что приложение может обратиться к утвержденной таблице или что у него правильный путь поиска. Проверка готовности может запросить небольшое стабильное представление рабочей ролью. Не запускайте миграции при старте приложения: одновременные экземпляры, пытающиеся изменить схему, создают именно ту связанность, от которой этот подход должен избавить.

Придуманные столбцы должны вызывать ошибку до выполнения запроса

LLM придумывают правдоподобные идентификаторы. Если в подсказке говорится об отображаемом имени клиента, сгенерированный код может обратиться к customers.display_name, хотя база хранит given_name и family_name. База отклонит запрос, и это лучше, чем незаметно прочитать не то поле, но ошибка в продакшене все равно плохой способ проверки схемы.

Сгенерируйте типизированный артефакт схемы из утвержденного снимка каталога и сделайте его единственным источником для построения запросов. Таблица или столбец, которых нет в этом артефакте, должны вызывать ошибку генерации. Не позволяйте модели исправлять ошибку добавлением миграции, если задача явно не перешла в направление миграций. Отсутствующий идентификатор может означать устаревшее обнаружение, опечатку, неверное окружение или настоящее требование продукта. Для каждого случая нужен свой ответ.

Статические проверки должны разбирать SQL и сопоставлять каждую связь и столбец со снимком. Затем подготовьте операторы против одноразовой базы или транзакции, которая не может записывать. Парсер PostgreSQL ловит неизвестные столбцы, неоднозначные ссылки, ошибки типов операторов и многие неверные приведения без успешных бизнес-данных. Запускайте интеграционные тесты с рабочей ролью, чтобы участвовали права и политики строк.

Отчет об ошибке должен дать человеку достаточно деталей для решения. Включите позицию в SQL, неразрешенный идентификатор, близкие допустимые идентификаторы, слепок снимка и идентификатор целевой базы. Подсказки полезны, но автоматическая нечеткая замена опасна. Замена billing_address_id на shipping_address_id из-за схожести имен может дать допустимый SQL с неверным бизнес-смыслом.

Для динамических фильтров и сортировок сопоставляйте публичные имена API с закрытым набором квалифицированных SQL-выражений. Никогда не вставляйте в SQL идентификатор, предоставленный моделью, даже через параметр значения. Параметры защищают значения, а не имена таблиц и столбцов. Если пользователи могут выбрать поле сортировки, переводите created в известное выражение, например app.orders.created_at, и отклоняйте любой неизвестный токен.

Дрейф схемы должен останавливать релиз, а не запускать творческое согласование. Сгенерируйте снимок заново, покажите разницу и повторите тесты. Такая задержка может казаться излишней, но она дешевле развертывания кода, чье понимание базы существует только в стенограмме разговора.

Разрушительному SQL нужны политика запрета и доказательства

Сначала спланируйте границы базы данных
Режим планирования Koder.ai помогает определить границы схемы до начала работы над сгенерированным приложением.

Конструктор должен классифицировать SQL, прежде чем кто-либо сможет его выполнить. Блокируйте DROP, TRUNCATE, широкие DELETE или UPDATE без проверенного предиката, смену владения, повышение прав, изменения расширений и команды за пределами утвержденных схем. Считайте ALTER TABLE операцией, требующей проверки, а не автоматически безопасной. Изменение типа столбца или новое ограничение без NULL могут сканировать или переписывать данные и удерживать существенные блокировки.

Одна проверка текста ненадежна, потому что в SQL есть комментарии, заключенные в кавычки идентификаторы, функции и много способов выразить побочные эффекты. Разбирайте операторы парсером, который понимает PostgreSQL, проверяйте их синтаксические деревья и также полагайтесь на роль базы, которая откажет в запрещенных действиях. Классификатор улучшает проверку, права обеспечивают границу. Ни один из этих механизмов не должен нести всю нагрузку один.

Используйте промежуточную базу, восстановленную из недавнего надлежащим образом защищенного снимка, когда миграция зависит от реальных форм таблиц или распределения данных. Примените там точный пакет миграции, зафиксируйте длительность и наблюдения о блокировках, запустите тесты приложения с рабочими учетными данными, затем удалите окружение. Не меняйте SQL незаметно между промежуточной средой и продакшеном. Любая правка создает новый артефакт, которому нужны новый слепок и утверждение.

Журналы должны связывать предложение с выполнением, не записывая секреты и конфиденциальные строки. Фиксируйте, кто утвердил неизменяемый артефакт миграции, его дайджест, идентификатор цели, статус начала и завершения и детали ошибки PostgreSQL. Сохраняйте сгенерированную разницу и результаты предварительных проверок. Чат с агентом полезен как контекст, но не служит аудитной записью, потому что пользователи могут ветвить, повторять и перефразировать инструкции.

Снимки и средства отката сокращают время восстановления, но не делают разрушительный SQL приемлемым. Снимок может восстановить всю базу к более раннему моменту, когда нужно вернуть один удаленный столбец, а восстановление может отбросить законные записи, появившиеся после снимка. Отдельно тестируйте восстановление и документируйте, кто может его запускать.

Когда я использую Koder.ai для приложения, которое работает с уже существующей базой, я остаюсь в режиме планирования, пока не проверю экспортированный исходный код и предложенную границу базы. Снимки и откат служат средствами восстановления, а не разрешением пропустить эту проверку. То же правило относится к любому конструктору: удобство продукта должно находиться за защитой базы данных.

Изменения схемы должны выдерживать одновременную работу разных версий приложения

Сделайте изменения схемы восстанавливаемыми
Снимки и откат в Koder.ai создают точку восстановления приложения перед изменениями.

Миграция безопасна, только когда и старое, и новое приложение могут работать в окне релиза. Продакшен редко переключается с одной версии на другую мгновенно. Запросы могут попадать на старые экземпляры, пока запускаются новые, задания в очереди могут нести старые данные, а откат может вернуть вчерашний код к сегодняшней схеме. Конструктор приложений, который проверяет только финальный код по финальной схеме, пропускает это перекрытие.

Сначала предпочитайте добавочные изменения. Добавьте допускающий NULL столбец, новую таблицу или индекс, не убирая старый путь. Разверните код, который умеет читать оба представления и при необходимости записывает новое представление. Заполните существующие строки отдельной проверенной задачей, следите за ошибками и отставанием, затем сделайте новое поле основным. Удалите старый столбец или ограничение в следующем релизе, когда появятся доказательства, что работающий код его не использует.

Эта последовательность занимает больше времени, чем генерация одного оператора ALTER TABLE, но изолирует сбои. Если новый код ведет себя неверно до удаления, старый путь остается. Если заполнение отстает, его можно остановить, не удерживая релиз приложения. Если развертывание откатывается, старое приложение все еще понимает базу. Дополнительный релиз дешевле, чем обнаружить при откате, что предыдущая сборка запрашивает столбец, уже удаленный миграцией.

Переименования требуют особой осторожности, потому что PostgreSQL меняет имя сразу. Генератор может предложить переименовать customer_ref в customer_id, потому что новое имя звучит лучше. Старые экземпляры перестанут работать, как только миграция зафиксируется. Добавьте customer_id, поддерживайте оба поля синхронно в коде приложения или через узко проверенный триггер, перенесите читателей и удалите customer_ref только после исчезновения старых писателей. Временное дублирование - видимый долг с условием удаления, а немедленное переименование создает невидимую связанность релиза.

Значения по умолчанию и ограничения без NULL тоже могут скрывать работу. Перед утверждением SET NOT NULL посчитайте существующие NULL и докажите, что каждый активный писатель передает значение. Для больших или загруженных таблиц проверьте, как версия PostgreSQL валидирует ограничение и какие блокировки берет. Конструктор должен сообщать об этих предварительных условиях, а не выводить их из схемы без репрезентативного трафика.

Заполнение данных не должно идти внутри неограниченной транзакции схемы. Обновляйте строки измеряемыми пакетами через утвержденный обработчик, фиксируйте ход стабильным курсором и делайте повторы идемпотентными. Повтор идемпотентен, когда двукратное применение дает нужное состояние, а не просто когда PostgreSQL принимает второй запрос. Для производных значений сохраняйте версию расчета, если будущий код может считать их иначе.

Пакет релиза должен назвать четыре точки совместимости:

  1. Самую старую версию приложения, которой разрешено работать до миграции.
  2. Состояние схемы, принимаемое старой и новой версиями.
  3. Сигнал, разрешающий разрушительный релиз очистки.
  4. Путь восстановления, если новый код откатится после изменения данных.

Сгенерированные запросы должны избегать SELECT * во время таких переходов. Добавление столбца может изменить стоимость сканирования, декодирование результата, позиционное сопоставление и раскрытие данных, хотя старый SQL все еще разбирается. Явно перечисляйте квалифицированные столбцы и генерируйте декодеры из того же снимка схемы. Так проверка исходного кода сразу показывает, какие именно данные пересекают границу базы.

Готовые инструменты миграции часто записывают примененную версию в таблицу, но один номер версии не доказывает совместимость. Сохраняйте дайджест точного SQL-артефакта, потому что два файла с одинаковым понятным именем могут содержать разные команды. Исполнитель должен отклонять уже записанную версию с другим дайджестом. Он также должен отклонять более позднюю миграцию, если не хватает обязательной предыдущей.

Не позволяйте каждому экземпляру приложения запускать миграции при старте. Даже если инструмент миграций использует рекомендательную блокировку, запуск теперь зависит от привилегированных учетных данных и завершения работ со схемой до истечения проверок готовности. Выполняйте миграцию одной задачей релиза, дождитесь ее зафиксированного результата и запускайте рабочие экземпляры с учетной записью, которая не может менять схему. Если система релизов не способна разделить эти фазы, исправьте систему релизов до выдачи приложению прав владельца.

Тестируйте эту последовательность, а не только конечное состояние: старый код со старой схемой, старый код с расширенной схемой, новый код с расширенной схемой и откатившийся код после новых записей. Очистку тестируйте отдельно позже. Эта матрица ловит изменения, которые синтаксически допустимы, но операционно не поддаются откату.

Подтвердите границу негативными тестами

Безопасная конструкция неполна, пока запрещенные действия не завершаются ошибкой в тестах. Подключитесь как роль обнаружения и попробуйте вставку, создание таблицы и SET TRANSACTION READ WRITE. Подключитесь как рабочая роль и попробуйте обратиться к невыданной таблице, прочитать данные другого арендатора, закрытые защитой строк, и изменить схему. Ожидаемый результат - ошибка прав PostgreSQL, а не обещание в журнале агента.

Проводите и позитивные тесты. Обнаружение должно по-прежнему читать все разрешенные записи каталога. Рабочая роль должна выполнять каждое утвержденное действие пользователя через пул. Выполнение миграции должно работать только через путь утверждения. Граница, которая блокирует обычную работу продукта, подтолкнет кого-то заменить ее учетными данными владельца во время инцидента.

Храните рядом с исходным кодом приложения небольшой контракт доступа. В нем нужно назвать базу, разрешенные схемы, область обнаружения, рабочие операции, режим пула, политику тайм-аутов, утверждающих миграции, метод слепка схемы и запрещенные операторы. В непрерывных проверках сравнивайте реальные права с этим контрактом. Дрейф прав PostgreSQL - это дрейф конфигурации, даже если никто не менял код приложения.

Проверяйте снова после изменений ролей, появления новых таблиц, восстановления баз, обновлений пула и изменений хостинга. Права по умолчанию важны для будущих объектов: GRANT SELECT ON ALL TABLES охватывает текущие таблицы, но не таблицы, созданные позже. Решите, должны ли новые объекты быть невидимыми до проверки или включаться через узко настроенные права по умолчанию. Я предпочитаю невидимость по умолчанию, потому что явная выдача прав заставляет обсудить доступ к новой таблице.

Включите отзыв прав в план тестирования. Отключите учетные данные обнаружения и подтвердите, что рабочий трафик продолжается. Отключите рабочие учетные данные и подтвердите, что инструменты миграции не подставляют незаметно более сильную учетную запись. Затем смените каждый секрет при активных подключениях и посмотрите, удаляет ли пул старые сессии в запланированное время. Смена пароля не завершает уже прошедшие проверку сессии, поэтому процедуре ротации нужен явный перезапуск пула или политика завершения сессий PostgreSQL.

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

Последняя проверка выявляет удивительно много небезопасных интеграций: полностью удалите учетные данные миграции и запустите набор тестов приложения. Если обычный старт, проверки работоспособности, предпросмотры или обработка запросов завершаются ошибкой, владение схемой проникло в рабочий путь. Устраните эту связанность до подключения конструктора к продакшену. AI-конструктор приложений может работать с базой, которой не владеет, но PostgreSQL должен уметь сказать «нет», когда сгенерированный код забывает об этой договоренности.

FAQ

Может ли AI-конструктор приложений использовать мою существующую базу PostgreSQL?

Да, если конструктор подключается через отдельные роли и изучает только утвержденные схемы. Разделите обнаружение, рабочие запросы и миграции по разным путям прав доступа, чтобы подключение инструмента не давало ему владения схемой.

Гарантирует ли пользователь PostgreSQL только для чтения, что данные не изменятся?

Главная защита - роль, у которой есть только SELECT и нет владения объектами. default_transaction_read_only добавляет защиты, но не должен компенсировать широкие права или унаследованное членство в ролях.

Стоит ли дать конструктору пароль владельца базы данных?

Нет. Учетные данные владельца разрушают границу и позволяют сгенерированному SQL менять права, таблицы и данные. Создайте отдельные учетные данные для обнаружения, работы приложения и контролируемой задачи миграции.

Как конструктор приложений может безопасно изучить мою схему?

Разрешите ему запрашивать утвержденные представления information_schema и pg_catalog через роль с ограниченными правами, а затем сохраните снимок со слепком. Не берите образцы строк, если специально для этого не подготовлено представление с маскированием.

Что произойдет, если AI придумает столбец PostgreSQL?

Генерация должна завершиться ошибкой по типизированному снимку схемы до развертывания. Сообщите неизвестное имя и близкие допустимые имена, но решение, исправлять ли код, заново изучать схему или утверждать миграцию, должен принять человек.

Может ли приложение подключаться напрямую из браузера или мобильного приложения?

Подключаться к PostgreSQL напрямую не стоит, потому что такие клиенты не могут надежно хранить пароль базы данных. Разместите доступ к базе в серверном процессе, а браузерному или мобильному приложению дайте обращаться к его API.

Нужен ли пул подключений для сгенерированных приложений?

Обычно да, но настраивать пул нужно осознанно. Ограничьте общее число сессий, выберите режим сессий или транзакций, сбрасывайте изменяемое состояние и проверяйте сгенерированный код через тот же пул, что используется в продакшене.

Можно ли безопасно откатить миграции PostgreSQL?

Некоторые изменения каталога чисто отменяются внутри транзакции, а потерю данных и внешние последствия так не исправить. Отдельно проверяйте прямой и обратный SQL, а снимки считайте средством восстановления, а не доказательством безопасности изменения.

Как запретить конструктору менять неутвержденные таблицы?

Используйте списки разрешенных схем, квалифицированные имена, узкие права, политику на основе разбора SQL и негативные проверки прав. Роль PostgreSQL должна отклонить операцию, даже если модель или проверка политики ошибется.

Как часто конструктор приложений должен заново изучать схему?

Заново изучайте схему при расхождении сохраненного слепка, а также после миграций, восстановления или изменений окружения. Не обновляйте ее незаметно во время релиза: покажите разницу и повторите проверку по новому снимку.

Похожие статьи