> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmodus.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PostgreSQL

> Connect your PostgreSQL database to Modus so your scopes have rich context about your data.

Connect a PostgreSQL database to Modus so it becomes context that Modus can
reason over. Modus understands your schemas, tables, and columns and makes them
available as context when Modus answers questions and queries your data.
Modus connects **read-only** and stores your credentials encrypted in AWS
Secrets Manager. This guide takes about five minutes.

## Prerequisites

Before you begin, make sure you have:

* **PostgreSQL 9.6 or later.**
* The **host**, **port**, and **database name** of the PostgreSQL instance you want to connect.
* **Admin access** to create a role (or an existing role Modus can log in as). We recommend a dedicated read-only role (see below).
* Network access from Modus to your database (see [Network access](#network-access)).

## Set up a read-only role

Modus only ever reads your data — it never writes, creates tables, or modifies
your schema. Create a dedicated least-privilege role for Modus.

First, create the login role and allow it to connect. Roles are cluster-wide, so
run this once (from any database, as a superuser or a role with `CREATEROLE`):

```sql theme={null}
-- Create a login role for Modus
CREATE ROLE modus_readonly WITH LOGIN PASSWORD '<strong-password>';

-- Allow it to connect to the database
GRANT CONNECT ON DATABASE <database> TO modus_readonly;
```

Next, grant read access. Choose one of the two options below.

<Tabs>
  <Tab title="PostgreSQL 14+ (simplest)">
    PostgreSQL 14 and later ship a built-in `pg_read_all_data` role that grants
    read access to every table in every schema — no per-schema grants needed:

    ```sql theme={null}
    GRANT pg_read_all_data TO modus_readonly;
    ```
  </Tab>

  <Tab title="Per-schema (any version / scoped access)">
    Use this to limit Modus to specific schemas, or on versions before 14.
    Schema and table grants apply only to the database you are connected to, so
    **connect to the target database first**, then run the grants for each schema:

    ```sql theme={null}
    -- Connect to the target database, e.g. in psql:
    \c <database>

    -- Grant read access to each schema Modus should use as context
    GRANT USAGE ON SCHEMA <schema> TO modus_readonly;
    GRANT SELECT ON ALL TABLES IN SCHEMA <schema> TO modus_readonly;

    -- Auto-grant SELECT on tables created in the future
    ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
      GRANT SELECT ON TABLES TO modus_readonly;
    ```
  </Tab>
</Tabs>

Replace the placeholders with your values:

| Placeholder         | Description                                                                     |
| ------------------- | ------------------------------------------------------------------------------- |
| `<database>`        | The database Modus should connect to (repeat the second block per database)     |
| `<schema>`          | A schema you want Modus to use as context (repeat the schema grants per schema) |
| `<strong-password>` | A strong password for the Modus role                                            |

<Note>
  `ALTER DEFAULT PRIVILEGES` only affects tables created by the role that runs
  it. If a different role owns your tables (for example, a dedicated application
  user), add `FOR ROLE <owner>` — e.g.
  `ALTER DEFAULT PRIVILEGES FOR ROLE <owner> IN SCHEMA <schema> GRANT SELECT ON TABLES TO modus_readonly;`
</Note>

<Note>
  `pg_catalog` and `information_schema` are readable by default in PostgreSQL,
  so no extra grants are needed for Modus to discover your table and column
  metadata.
</Note>

<Note>
  On managed PostgreSQL (AWS RDS, Google Cloud SQL, Azure, Supabase, etc.),
  creating roles may require a provider-specific admin role or console step.
  Refer to your provider's docs if `CREATE ROLE` is not permitted.
</Note>

Optionally, verify the new role can log in and read:

```bash theme={null}
psql -h <host> -p 5432 -U modus_readonly -d <database> -c "SELECT current_user;"
```

## Network access

If your database is behind a firewall, security group, or IP allowlist, allow
Modus's egress IP addresses so it can reach your instance. See
[IP Allowlisting](/guides/ip-allowlist) for the addresses and setup steps.

## Connect in Modus

<Steps>
  <Step title="Open the PostgreSQL connection form">
    1. Log into [Modus](https://app.getmodus.com).
    2. Click **Integrations** in the left sidebar.
    3. Find the **PostgreSQL** card under **Databases** and click **Connect**.
  </Step>

  <Step title="Fill in the connection details">
    Complete the form using the [field reference](#connection-form-field-reference) below.

    <Frame>
      <img src="https://mintcdn.com/modus-c77f86cb/1jIq7yXvNUfzqZYd/images/postgresql-integration/connection-form.png?fit=max&auto=format&n=1jIq7yXvNUfzqZYd&q=85&s=d34dc78316d3d0f5a127a35bf74076e8" alt="Modus PostgreSQL New Connection form" width="1440" height="900" data-path="images/postgresql-integration/connection-form.png" />
    </Frame>
  </Step>

  <Step title="Test and save">
    1. Click **Test Connection** to verify Modus can reach your database.
    2. Click **Save Connection**.
  </Step>

  <Step title="Select schemas">
    After saving, Modus lists the databases and schemas the role can access.
    Select the schemas you want Modus to use as context, then click **Save schemas**.
    Nothing is scanned without your explicit selection.
  </Step>
</Steps>

## Connection form field reference

### Basic information

| Field               | Description                         | Example               |
| ------------------- | ----------------------------------- | --------------------- |
| **Connection Name** | A friendly name for this connection | `Production Database` |

### Connection details

| Field             | Description                               | Example          |
| ----------------- | ----------------------------------------- | ---------------- |
| **Host**          | Hostname or IP of your PostgreSQL server  | `db.example.com` |
| **Port**          | PostgreSQL port                           | `5432`           |
| **Database Name** | The database to connect to                | `myapp`          |
| **SSL Mode**      | How the connection is secured (see below) | `Require`        |

### Authentication

| Field        | Description               | Example           |
| ------------ | ------------------------- | ----------------- |
| **Username** | The login role Modus uses | `modus_readonly`  |
| **Password** | The role's password       | *(your password)* |

## SSL modes

| Mode                    | Behavior                                                                  |
| ----------------------- | ------------------------------------------------------------------------- |
| **Disable**             | No TLS. Use only for trusted private networks.                            |
| **Require** *(default)* | Encrypts the connection but does not verify the server certificate.       |
| **Verify CA**           | Encrypts and verifies the server certificate against trusted CAs.         |
| **Verify Full**         | Encrypts, verifies the certificate, and checks the hostname. Most secure. |

## Troubleshooting

| Symptom                            | Likely cause                                                                                             |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------- |
| **Connection refused / timeout**   | Modus's egress IPs aren't allowlisted, or the host/port is wrong. See [Network access](#network-access). |
| **Authentication failed**          | Wrong username or password.                                                                              |
| **SSL error**                      | The selected SSL Mode doesn't match your server's configuration. Try `Require`.                          |
| **No schemas listed after saving** | The role lacks `USAGE`/`SELECT` on the schema, or `CONNECT` on the database.                             |

## Verification

Your PostgreSQL database is now connected. Modus turns the selected schemas,
tables, and columns into context so Modus can give accurate,
data-aware answers.

Need help? Contact us at [support@getmodus.com](mailto:support@getmodus.com).

<Note>
  Modus connects read-only and requests only the minimum permissions needed to
  understand and query your data. All credentials are encrypted and stored in AWS
  Secrets Manager — your password is never stored in plaintext.
</Note>
