Skip to content

Define least-privilege role design for Postgres #997

Closed

Description

ateapi currently connects to PostgreSQL as the postgres superuser. The HBA rule accepts any database and requested role from any client holding a certificate issued by the pod-identity CA. ateapi also applies its embedded schema during startup, coupling normal runtime access with DDL privileges.

hostssl all all all trust clientcert=verify-ca

We should move to least-privilege application roles, but the correct role split depends on the PostgreSQL migration design (tracked separately in #901) which has not yet been established. For example, migrations may need a separate owner / migrator role while the running API server only receives DML privileges. HBA rules also should be restricted appropriately.

#940 (comment)

Activity

  1. added
    kind/designDesign discussion, investigation, or research required before implementation
    on Sep 17, 2026
  2. iplay88keys commented on Sep 18, 2026

    @iplay88keys
    Collaborator

    Bowei Du (@bowei), Joe Betz (@jpbetz), Julian Gutierrez Oschmann (@juli4n), Here's my proposal for review. I will work on an implementation:

    Problem

    ateapi currently uses one PostgreSQL identity to create the schema, apply Goose migrations, serve requests, and maintain outbox partitions. The reference PostgreSQL manifest also accepts any database and requested role from a client with a trusted certificate. This makes every database operation run as the schema owner.

    Startup migrations are only part of the problem: the running server also creates, truncates, and drops outbox partitions. Separating migrations without addressing that maintenance would not produce a DML-only runtime.

    Proposed design

    Give ateapi two PostgreSQL connection strings and role classes:

    • DDL/maintenance: owns the Substrate schema and may create the schema, apply Goose migrations, perform data migrations, and maintain outbox partitions. It is not a PostgreSQL superuser and has no cluster-wide administration privileges.
    • DML/runtime: may connect, use the Substrate schema, and perform the table and sequence operations required to serve API traffic. It cannot create schemas, modify the migration ledger, or create, alter, truncate, or drop objects.

    Keep the existing startup lifecycle. Schema creation and migrations use the DDL connection; request handling and watch polling use DML connections; outbox partition creation, stray cleanup, and retention drops use the DDL connection. The current advisory locks continue to coordinate migrations and maintenance across replicas.

    The existing PostgreSQL connection remains the DML input. A new DDL connection input defaults to the DML connection, allowing simpler single-role deployments. For two-role deployments, deployment tooling supplies the credentials and provisions a clean runtime role without ownership or DDL privileges.

    Update the reference PostgreSQL manifest to provision both roles and restrict pg_hba.conf to the Substrate database and those roles, requiring both a trusted client certificate and role credentials.

    Known risk

    Both credentials and the live DDL pool remain inside the serving ateapi process. This design prevents accidental DDL through normal runtime paths and provides database-level permission separation and auditing, but it is not a security boundary against compromise of the process itself.

    The stronger alternative is to run migrations outside the serving process and either move partition maintenance to a separate privileged worker or expose only narrowly scoped SECURITY DEFINER maintenance routines. That would let ateapi receive only the DML credential, but requires a new migration lifecycle and more deployment or database machinery. It is deferred from this change.

    References

  3. added this to the M3 milestone on Sep 23, 2026
  4. added a commit that references this issue on Oct 2, 2026
    41c5f01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/securitySecurity related issue/prkind/designDesign discussion, investigation, or research required before implementationkind/featureAn enhancement / feature request or implementation

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions