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

# PostgreSQL

> Connect Bytebase to PostgreSQL, including verified TLS and client certificates.

To add a PostgreSQL database, go to **Instances**, click **Connect instance**, and choose **PostgreSQL**.

## Supported versions

Bytebase supports PostgreSQL 12 and later, including Amazon Aurora PostgreSQL and AlloyDB. It connects through a built-in driver, so there is nothing to install.

## Create a user for Bytebase

Bytebase applies schema changes and reads the catalog of every database it manages, so give it a dedicated user with broad privileges instead of an application's account. The examples name the user `bytebase`.

On a self-managed server, connect as a superuser and run:

```sql theme={null}
CREATE USER bytebase WITH ENCRYPTED PASSWORD '<password>';
ALTER USER bytebase WITH SUPERUSER;
```

Managed services don't give out `SUPERUSER`. Connect as the admin account the service gives you, create the user the same way, and grant the service's admin role instead:

| Service | Grant |
| - | - |
| Amazon RDS and Aurora | `GRANT rds_superuser TO bytebase;` |
| Google Cloud SQL | `GRANT cloudsqlsuperuser TO bytebase;` Users you create in the Cloud SQL console get this role automatically. |
| Azure Database for PostgreSQL | Create the user with `CREATEDB CREATEROLE`, then run `GRANT azure_pg_admin TO bytebase;` |
| Supabase | Use the `postgres` user, which has admin privileges. See [Supabase](#supabase). |
| Neon | Create the role in the Neon Console, which gives it `neon_superuser`. Roles created with SQL don't get it. See [Neon](#neon). |

These admin roles still can't change objects that another role owns. To let Bytebase change them, grant it the owning role, such as `GRANT app_owner TO bytebase;`.

For a [read-only connection](#read-only-connection) on PostgreSQL 14 or later, create a separate user:

```sql theme={null}
CREATE USER bytebase_readonly WITH ENCRYPTED PASSWORD '<password>';
GRANT pg_read_all_data TO bytebase_readonly;
```

## Connection details

### Authentication

How Bytebase signs in:

* **Plain Password**: the **Username** and **Password** below.
* **AWS RDS IAM**: an IAM authentication token for Amazon RDS or Aurora. See [AWS](/get-started/connect/aws).
* **Google Cloud SQL IAM**: an IAM service account for Cloud SQL. See [GCP](/get-started/connect/gcp).

### Hostname

The host name or IP address of the PostgreSQL server, such as `db.example.com`. With **Verify server certificate** on, it must be one of the names in the server's certificate.

### Port

The server port. PostgreSQL's default is `5432`.

### Username

The PostgreSQL role Bytebase connects as.

### Password

The role's password. You can also read it from a [secret manager](/get-started/connect/overview#secret-manager-integration).

### Connection database

The database Bytebase connects to when it isn't working in a specific database, such as when it tests the connection or lists databases. If you leave it empty, Bytebase uses `postgres`. Set it when the role can't connect to `postgres`.

Bytebase lists every database on the server except `template0` and `template1` as a Bytebase database, whichever connection database you choose. Schemas such as `public` appear inside each one. See [Database](/concepts/database).

### TLS

**TLS mode** decides whether Bytebase encrypts the connection:

* **Disabled**: Bytebase adds no TLS settings, so the driver's default applies. It uses TLS when the server offers it, without verifying the server, and connects unencrypted when the server doesn't.
* **TLS**: Bytebase always encrypts the connection, and fails if the server doesn't offer TLS.
* **Mutual TLS**: the same as **TLS**, and Bytebase also presents a client certificate, for servers that require one.

Under **Server identity**, turn on **Verify server certificate** so that Bytebase checks the server's certificate and confirms that **Hostname** is one of the names in it. **CA certificate source** sets which certificate authority (CA) the check trusts:

* **System trust**: the CAs that the machine running Bytebase already trusts.
* **Paste PEM**: a CA certificate you paste in PEM format, for a private CA or a self-signed certificate.
* **File path**: a CA certificate file on the Bytebase server. Not available in Bytebase Cloud.

With verification off, the connection is encrypted, but Bytebase doesn't check which server it reached. Use that only for testing.

For **Mutual TLS**, set **Client identity source** to **Paste PEM** or **File path**, and provide the client certificate and its private key.

### SSH tunnel

Connects through a bastion host. See [SSH Tunnel](/get-started/connect/overview#ssh-tunnel).

### Extra Parameters

Connection parameters that Bytebase passes to the driver as key-value pairs, using [libpq names](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS) such as `connect_timeout`. With **TLS mode** set to **Disabled**, `sslmode` controls encryption, so `sslmode` with the value `disable` keeps the connection unencrypted even when the server offers TLS.

## Supabase

Bytebase connects to Supabase as a regular PostgreSQL server. To find the connection details, open your project in the Supabase dashboard and click **Connect** at the top of the page. Supabase offers three connection types:

| Type | Host and port | For Bytebase |
| - | - | - |
| **Direct connection** | `db.<project_ref>.supabase.co:5432` | Use it when Bytebase can reach IPv6, or when the project has the IPv4 add-on. |
| **Session pooler** | `aws-<n>-<region>.pooler.supabase.com:5432` | Use it when Bytebase reaches the internet over IPv4 only. |
| **Transaction pooler** | Port `6543` | Don't use it. It's built for serverless functions and drops session state between transactions. |

Copy the connection string for the type you chose. A session pooler string looks like this:

```text theme={null}
postgresql://postgres.<project_ref>:<password>@aws-<n>-<region>.pooler.supabase.com:5432/postgres
```

Fill in the form from it:

* **Hostname**: the host from the string. Copy it rather than building it from your region, because the number after `aws-` varies.
* **Port**: `5432`.
* **Username**: `postgres` for a direct connection, or `postgres.<project_ref>` for the session pooler.
* **Password**: the database password you set when you created the project.
* **Connection database**: leave it empty to use `postgres`.

To verify the server, download the CA certificate from **Database settings** > **SSL Configuration** with **Download Certificate**. Set **TLS mode** to **TLS**, turn on **Verify server certificate**, and paste the certificate with **CA certificate source** set to **Paste PEM**. **System trust** doesn't work here, because Supabase signs its certificates with its own CA.

## Neon

In the Neon Console, open your project and click **Connect**. In **Connect to your branch**, choose the branch, database, and role, then turn off **Connection pooling** to get the direct connection string. Neon recommends direct connections for schema migrations, and its pooler doesn't keep session state between transactions.

```text theme={null}
postgresql://<role>:<password>@ep-<endpoint>.<region>.aws.neon.tech/<database>?sslmode=require
```

Fill in the form from it:

* **Hostname**: the host from the string, without `-pooler` in it.
* **Port**: `5432`.
* **Username**: the role. Create it in the Neon Console so that it has `neon_superuser`.
* **Password**: the role's password.
* **Connection database**: the database from the string, such as `neondb`.

Neon rejects unencrypted connections. Set **TLS mode** to **TLS**, turn on **Verify server certificate**, and keep **CA certificate source** at **System trust**. Neon's certificates chain to Let's Encrypt's ISRG Root X1, which the system already trusts.

## Troubleshooting

**Test Connection** shows the error from the server or the driver:

| Error | Cause | Fix |
| - | - | - |
| `SSL cert failed to verify: x509: certificate signed by unknown authority` | Verification is on, and the CA from **CA certificate source** didn't sign the server's certificate. | Paste the CA that signed the server's certificate, or point to it. |
| `SSL cert failed to verify: x509: certificate is valid for …, not …` | **Hostname** isn't one of the names in the server's certificate. | Use a name from the certificate, or have the certificate reissued. |
| `tls error: server refused TLS connection` | **TLS mode** is **TLS** or **Mutual TLS**, and TLS is off on the server. | Turn on TLS on the server with `ssl = on`, or set **TLS mode** to **Disabled**. |
| `no pg_hba.conf entry for host "…", user "…", database "…", no encryption` or `pg_hba.conf rejects connection for host "…" … no encryption` | The server accepts only encrypted connections, and this one wasn't encrypted, usually because `sslmode` is `disable`. | Set **TLS mode** to **TLS**, or remove `sslmode` from **Extra Parameters**. |
| `connection requires a valid client certificate` | The server requires a client certificate through `clientcert` in `pg_hba.conf`. | Set **TLS mode** to **Mutual TLS**, and provide the certificate and its key. |
| `ssl_cert and ssl_key must be both set or unset` | Only one of the client certificate and its private key is set. | Provide both. |
| `failed to read CA certificate file` | **File path** points to a file the Bytebase server can't read. | Check the path on the Bytebase server. |
| `password authentication failed for user "…"` | The password is wrong. With `clientcert=verify-full`, this also means the client certificate's Common Name doesn't match **Username**. | Check the password, or use a certificate issued for this user. |
| `permission denied for database "postgres"` | The role can't connect to `postgres`, the default connection database. | Set **Connection database** to a database the role can connect to. |
| `database "…" does not exist` | **Connection database** names a database that doesn't exist. | Correct the name, or leave the field empty to use `postgres`. |

## Read-only connection

A [read-only connection](/get-started/connect/overview#read-only-connections) has its own TLS settings and **Extra Parameters**. Set them the same way as for the admin connection.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.