Access a PostgreSQL database

Last validated:
Tailscale PAM is currently in beta.

Tailscale PAM lets users connect to PostgreSQL using their Tailscale identity instead of sharing database credentials.

You can control who has access to the database, apply fine-grained permissions, and keep an audit trail of database sessions. Users can connect from the browser or continue using their preferred PostgreSQL client.

This guide walks you through creating a PostgreSQL PAM service, connecting to it, and reviewing the resulting session activity.

Prerequisites

Before you begin, confirm you have the following:

  • A Tailscale PAM connector that is installed, online, and able to reach the PostgreSQL server.
  • Tailscale installed and signed in on the device you'll use to connect, if you plan to use a native database client.
  • A PostgreSQL server that the connector can reach.
  • Permission to update your tailnet policy file.

You can use your own PostgreSQL server, the Tailscale PAM sandbox server, or a local Docker container.

If you're using your own PostgreSQL server, you'll need its hostname or IP address, port, username, and password.

If you just want to try Tailscale PAM, you can use the public PostgreSQL sandbox:

SettingValue
Hostnamepsql.playground.border0.io
Port5432
Usernameborder0
PasswordBorder0<3Psql

For information about the other sandbox servers available for testing, refer to Tailscale PAM FAQ.

Run a local PostgreSQL server with Docker

If you're using your own PostgreSQL server or the Tailscale PAM sandbox, skip to the next step.

For a quick local test, start a PostgreSQL server with Docker:

docker run --name tailscale-pam-postgres --rm \
  -e POSTGRES_PASSWORD=<your-database-password> \
  -d -p 5432:5432 postgres

Replace <your-database-password> with a password of your choice. This starts a PostgreSQL server on port 5432 with the postgres user and the password that you specified.

Before continuing, verify that you can connect to it:

psql -h 127.0.0.1 -U postgres -d postgres

When prompted, enter the password that you specified.

After you connect, run a basic query:

SELECT VERSION();

If the query succeeds, your PostgreSQL server is ready.

If the Tailscale PAM connector runs on the same device as Docker, you can use localhost and port 5432 when you configure the PAM service. If the connector runs somewhere else, use an IP address or hostname that the connector can reach.

Create a PostgreSQL PAM service

Create a database service and link it to your connector.

  1. Open the Services page of the Tailscale admin console.

  2. Select Add service.

  3. Select PAM service.

  4. Select PostgreSQL.

  5. Select Continue.

  6. Provide a name for your service.

    Use a name that will make the database suitable for users to recognize when they browse the services they can access.

  7. (Optional) Provide a description for the service.

  8. Choose whether the Session Recording option is enabled or disabled.

  9. Select the Tailscale PAM connector that can reach your PostgreSQL server.

  10. Select Continue.

  11. For Upstream hostname, enter hostname or IP address of the PostgreSQL server.

  12. For Port, enter the PostgreSQL port. The default is 5432.

  13. For Authentication Type, select Username and Password.

  14. For Username, enter the username Tailscale PAM should use to connect to PostgreSQL.

  15. For Password, enter the password for that user.

    If you used the local Docker example and the connector runs on the same device, use localhost, port 5432, username postgres, and the password that you used for the <your-database-password> placeholder.

    If you're using the Tailscale PAM sandbox, use the sandbox connection details from the prerequisites above. If you're using your own PostgreSQL server, enter the connection details for that server.

  16. Select Save.

Your database service should be created. You can access it in the Services page.

Grant access to the PostgreSQL service

Before users can connect, make sure a Tailscale PAM grant gives them access to the service. For example, the following grant permits any source to connect to PAM database services:

"grants": [
  {
    "src": ["*"],
    "dst": ["*"],
    "ip": ["*"],

    "app": {
      "tailscale.com/cap/pam": [
        {
          "version": "bv1",

          "permissions": {
            "database": {}
          }
        }
      ]
    }
  }
]

This is a broad grant that's useful for getting started. In a production environment, you can restrict the src and dst fields to control which users, groups, devices, or tags can access specific services.

You can also define more advanced database permissions, such as read-only access.

For more PAM grant examples and information about fine-grained access controls, refer to Control access to Tailscale PAM services.

For information about editing grants, refer to Edit access control policies in your tailnet policy file.

Connect to the PostgreSQL database

The primary way to connect is through the Tailscale client, which can launch your preferred PostgreSQL client. You can also connect entirely from your browser using the Tailscale web client.

Connect with your preferred PostgreSQL client

Use the Tailscale client to quickly open the database with a PostgreSQL client already installed on your device.

  1. Open the Tailscale client.
  2. Open Services.
  3. Select your PostgreSQL service.
  4. Choose the database client you want to use.

The Tailscale client scans your device for well-known PostgreSQL-compatible database clients and shows the ones it can find. Selecting one establishes the PAM session and launches that client for you.

You aren't limited to the clients shown in the Tailscale client. If your preferred database client isn't listed, open it directly and use the name of the Tailscale PAM service as the hostname and 5432 as the port. You don't need to know or manage the upstream PostgreSQL credentials.

Tailscale PAM uses your Tailscale identity to authorize the connection and manages the upstream database connection on your behalf. This means you can continue using your familiar database tools without needing the PostgreSQL credentials.

For example, you can connect with the standard psql command-line client:

psql -h <service-name> -p 5432 -d <database-name>

Replace <service-name> with the name of your PostgreSQL PAM service and <database-name> with the database you want to access. If you're using the local Docker example, the default database is postgres:

psql -h <service-name> -p 5432 -d postgres

Connect from the browser

Alternatively, you can connect with the web-based PostgreSQL client. The web client runs a Tailscale client directly in your browser using WebAssembly (Wasm), so there's nothing else to install.

  1. Open the Services page in the Tailscale admin console.
  2. Select the PostgreSQL service you want to access.
  3. Select Connect in the upper-right corner, and the Tailscale PostgreSQL web client opens.
  4. If prompted, authenticate with your Tailscale identity.

You can now run queries against the PostgreSQL database directly from your browser.

The web client appears as an ephemeral device in your tailnet. If device approval is enabled for the tailnet, an admin must approve the browser device before it can connect.

Secure the upstream credentials

In the example above, the upstream PostgreSQL username and password are stored as part of the PAM service configuration. Tailscale stores these credentials in encrypted form, but for production environments we recommend keeping upstream credentials local to the connector whenever possible.

You can configure the connector to load credentials dynamically from a supported secret source instead of storing the credentials directly in the service configuration. For example, you can load credentials from an environment variable, a local file, or a secrets management system.

For more information, refer to Manage secrets and credentials.

By default, Tailscale PAM attempts to establish the connection between the connector and the upstream PostgreSQL server using TLS. If the PostgreSQL server doesn't support TLS, the connection falls back to a non-TLS connection.

Review session details and recordings

Tailscale PAM gives you visibility into connections to your PostgreSQL service.

Open the Sessions page in the admin console, then select a session for your PostgreSQL service. You can review information such as:

  • The Tailscale identity that connected.
  • The originating device.
  • The connection time.
  • The service that was accessed.

When session recording is enabled, you can also review the SQL queries for the session.

This gives you a direct answer to two useful questions: who accessed the database, and what did they do while they were there?

Troubleshooting

If you can't connect to your PostgreSQL service, the most common issue is that the connector can't connect to the upstream database.

First, confirm that the connector is online and can reach the PostgreSQL hostname and port. Also verify that the username and password in the service configuration are valid.

If you're using the Docker example, remember that localhost refers to the device running the connector. If your connector runs on a different device, use a hostname or IP address that is reachable from that device.

If none of the troubleshooting steps mentioned above resolve your issue, review the connector logs and the details for the failed session in the PAM session logs. Failed sessions often include information about why the connection couldn't be established, which can help narrow down whether the problem is network connectivity, authentication, or the upstream database itself.