Access a MySQL database

Last validated:
Tailscale PAM is currently in beta.

Tailscale PAM lets users connect to MySQL 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 MySQL client.

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

Prerequisites

Before you begin, make sure you have the following:

  • A connector that is installed, online, and able to reach the MySQL server.
  • Tailscale installed and signed in on the device you'll use to connect, if you plan to use a native database client.
  • A MySQL server that the connector can reach.

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

If you're using your own MySQL 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 MySQL sandbox:

SettingValue
Hostnamemysql.playground.border0.io
Port3306
Usernameborder0
PasswordBorder0<3MySql

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

Run a local MySQL server with Docker

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

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

At a command line on your tailnet device that will host the database, run

docker run --name tailscale-pam-mysql --rm \
 -e MYSQL_ROOT_PASSWORD=<your-database-password> \
 -d -p 3306:3306 mysql

Replace <your-database-password> with a password of your choice. This starts a MySQL server on port 3306 with the root user and the password that you specified.

Before continuing, verify that you can connect to it:

mysql -u root -p -h 127.0.0.1 --protocol TCP

When prompted, enter your password.

After you connect, run a basic query:

SELECT VERSION();

If the query succeeds, your MySQL server is ready.

If the Tailscale PAM connector runs on the same device as Docker, you can use localhost and port 3306 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 database service

Now that you have a MySQL server, create a PAM service for it.

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

  2. Select Add service.

  3. Select PAM service.

  4. Select MySQL.

  5. Select Continue.

  6. Enter a name for the service.

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

  8. Choose whether to enable session recording.

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

  10. Select Continue.

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

  12. For Port, enter the MySQL port. The default is 3306.

  13. For Authentication type, select Username and Password.

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

  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 3306, username root, and your-database-password.

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

  16. Select Save.

Your MySQL PAM service has been created. You can access it in the Services page.

Grant access to the MySQL 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": "v1",

          "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.

Connect to the MySQL database

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

Connect with your preferred MySQL client

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

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

The Tailscale client scans your device for well-known MySQL-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 connect using:

  • Hostname: The name of the Tailscale PAM service.
  • Port: 3306.
  • Username: Leave empty.
  • Password: Leave empty.

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 MySQL credentials.

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

mysql -h <service-name> -P 3306 --protocol TCP

Replace <service-name> with the name of your MySQL PAM service.

Connect from the browser

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

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

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

The web client appears as a Tailscale 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 MySQL 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 MySQL server using TLS. If the MySQL 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 MySQL service.

Open the Sessions page in the admin console, then select a session for your MySQL 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 MySQL 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 MySQL 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.

Next, 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.