training-web.ruГлавнаяКатегорииО насКарта сайтаПоискТёмная тема

Категории

Как готовить базу данных postgres API приложения для prod режима

Создано: 19 декабря 2025Автор: Егор Астапов105 просмотровСложность: легкий

Допустим у вас есть база postgres и у вас есть автоматические тесты. Для автоматических тестов вам нужна отдельная база с пользователей к этой базе. Сколько баз и пользователей сделать ? Тут есть масса тонкостей. Покажу вам лучшие практики.

Для нашего случая с двумя основными базами (db — продакшн, db_test — тестовая) и, возможно, третьей (postgres или шаблонной) — рекомендуемое количество пользователей (ролей) в PostgreSQL зависит от среды (development vs production) и принципа least privilege (минимальных необходимых прав).

Минимальное количество пользователей

Всего 3–5 ролей (не считая системных вроде postgres).

  1. 1 суперпользователь/админ (например, admin или стандартный postgres) — для инициализации, миграций, бэкапов. Не используйте его в приложении!
  2. 1 пользователь для продакшн-базы (user_prod или user) — только для db. Права: CONNECT, USAGE/CREATE на схему public (для миграций), DML на таблицы (SELECT/INSERT/UPDATE/DELETE). 1 пользователь для тестовой базы (test_user или user_test) — только для db_test. Те же права, но отдельно.
  3. Опционально: отдельная роль для миграций (DDL — CREATE/ALTER/DROP) — если используете ОРМ Alembic/Flyway. Она может быть временной или с повышенными правами только на время деплоя. Опционально: read-only роль — для мониторинга/отчётов.

Это минимум для безопасности: каждый пользователь имеет доступ только к своей базе.

Лучшие практики (best practices)

Принцип least privilege — основной в PostgreSQL (рекомендации AWS, Crunchy Data, официальной документации):

  1. Никогда не подключайте приложение под суперпользователем.
  2. REVOKE CONNECT FROM PUBLIC на всех базах, затем GRANT CONNECT только нужным пользователям.
  3. Отдельные пользователи для прод и тест — чтобы утечка пароля из теста не затронула прод.
  4. В продакшн: приложение имеет только DML-права (не DDL, не DROP).

Разделение сред:

  1. Development: Можно 1–2 пользователя (даже с CREATEDB для удобства разработчиков). Локально — часто один пользователь на всё.
  2. Test/Staging: Как прод, но с отдельным пользователем. Тестовая база — копия прод (анонимизированная).
  3. Production: Строго отдельные пользователи, разные пароли. Нет CREATEDB/CREATEROLE.

Дополнительные роли:

  1. Group roles (без LOGIN) для группировки прав: например, app_readwrite — с USAGE + DML, затем GRANT этой роли пользователям.
  2. Для миграций: отдельный пользователь с DDL-правами (или временно повышайте права админом).
  • Безопасность подключений (pg_hba.conf):
    1. Явные правила для каждой комбинации база + пользователь.
    2. Reject для запрещённых (перекрёстных) подключений.
    3. scram-sha-256 (не md5).

    Другие рекомендации:

    1. Пароли: сильные, храните в секретах (Docker secrets, .env не в git).
    2. Мониторинг: pgAudit для логов доступа.
    3. Миграции: ALTER DEFAULT PRIVILEGES — чтобы новые таблицы автоматически получали права.
    4. Не используйте schema public в прод без ограничений (или создайте отдельную schema).

    Вы можете пойти простым путём. Создать простого пользователя user. У этого пользователя не должно быть суперадминских прав на все базы данных, а доступ только к одной базе. Этого пользователя можно использовать и для миграций тоже. Проследите чтобы пользователей не мог переключаться с одной базы в другую. Один пользователь должен пользоваться только одной базой данных! Не удаляёте суперадмина postgres и не переименовывайте его! Если ваша база открыта наружу и видна в сети, то отрежьте пользователя postgres от всех баз и системных тоже. Вы должны сделать такие настройки чтобы вы могли легко подключаться под postgres локально в контейнере. Также в контейнере вы у вас должна быть возможность перемещаться из одной базы в другую. У вас не должно быть возможности подключаться под postgres по ip к любой базе.

    Используйте запреты для postgres в pg_hba.conf.

    # pg_hba.conf
    # Запрещаем суперпользователю postgres подключаться к прод- и тестовой базам с внешних IP
    host db postgres 0.0.0.0/0 reject
    host db postgres ::/0 reject
    -- для простых пользователей используйте REVOKE CONNECT и GRANT CONNECT
    REVOKE CONNECT ON DATABASE "db" FROM PUBLIC;
    GRANT CONNECT ON DATABASE "db" TO "user";

    Лучше добавлять права через CONNECT, чем постоянно менять права в pg_hba.conf. Помните, что CONNECT не работает для суперпользователей таких как postgres!

    Комментарии

    реклама