# Database Access with Azure PostgreSQL and MySQL

Teleport can provide secure access to Azure PostgreSQL or MySQL via the [Teleport Database Service](https://goteleport.com/docs/enroll-resources/database-access.md). This allows for fine-grained access control through [Teleport's RBAC](https://goteleport.com/docs/enroll-resources/database-access/rbac.md).

In this guide, you will:

1. Configure your Azure PostgreSQL or MySQL database with Microsoft Entra ID-based authentication.
2. Add the database to your Teleport cluster.
3. Connect to the database via Teleport.

## How it works

The Teleport Database Service proxies traffic between Teleport users and Azure PostgreSQL and MySQL. When a user connects to the database via Teleport, the Database Service obtains an access token from Microsoft Entra ID (formerly Azure AD) and authenticates to Azure as a principal with permissions to manage the database.

**Self-Hosted**

![Enrolling Azure PostgreSQL/MySQL with a self-hosted Teleport cluster](/docs/assets/images/azure_selfhosted-eb643e7ab0f22065e6f58c4c46289741.png)

**Teleport Enterprise Cloud**

![Enrolling Azure PostgreSQL/MySQL with a cloud-hosted Teleport cluster](/docs/assets/images/azure_cloud-0f2b032d1b58f06c9e36bb2b9ccdfa1c.png)

## Prerequisites

- A running Teleport cluster. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/get-started/deploy-community.md).

- The `tctl` and `tsh` clients.

  Installing `tctl` and `tsh` clients

  1. Determine the version of your Teleport cluster. The `tctl` and `tsh` clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at `/v1/webapi/find` and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
     ```

  2. Follow the instructions for your platform to install `tctl` and `tsh` clients:

     **Mac**

     Download the signed macOS .pkg installer for Teleport, which includes the `tctl` and `tsh` clients:

     ```
     $ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
     ```

     In Finder double-click the `pkg` file to begin installation.

     ---

     DANGER

     Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/installation.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

* Deployed Azure Database for PostgreSQL or MySQL server.
* Microsoft Entra ID administrative privileges.
* A host, e.g., an Azure VM instance, where you will run the Teleport Database Service.
* To check that you can connect to your Teleport cluster, sign in with `tsh login`, then verify that you can run `tctl` commands using your current credentials. For example, run the following command, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and email\@example.com to your Teleport username:
  ```
  $ tsh login --proxy=teleport.example.com --user=email@example.com
  $ tctl status
  Cluster  teleport.example.com
  Version  18.7.3
  CA pin   sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
  ```
  If you can connect to the cluster and run the `tctl status` command, you can use your current credentials to run subsequent `tctl` commands from your workstation. If you host your own Teleport cluster, you can also run `tctl` commands on the computer that hosts the Teleport Auth Service for full permissions.

## Step 1/5. Configure Azure service principal

To authenticate with PostgreSQL or MySQL databases, Teleport Database Service needs to obtain access tokens from Microsoft Entra ID.

There are a couple of ways for the Teleport Database Service to access Azure resources:

- The Database Service can run on an Azure VM with attached managed identity. This is the recommended way of deploying the Database Service in production since it eliminates the need to manage Azure credentials.
- The Database Service can be registered as a Microsoft Entra ID application (via "App registrations") and configured with its credentials. This is only recommended for development and testing purposes since it requires Azure credentials to be present in the Database Service's environment.

**Using managed identity**

Go to the [Managed Identities](https://portal.azure.com/#browse/microsoft.managedidentity%2fuserassignedidentities) page in your Azure portal and click *Create* to create a new user-assigned managed identity:

![Managed identities](/docs/assets/images/managed-identities@2x-db5917e6ecdac0bed024d29bb9aa963d.png)

Pick a name and resource group for the new identity and create it:

![New identity](/docs/assets/images/new-identity-174be1add2247ac946b5d4961e3aa597.png)

Take note of the created identity's *Client ID*:

![Created identity](/docs/assets/images/created-identity-c26a469f21613027ef899b1b6674e74b.png)

Next, navigate to the Azure VM that will run your Database Service instance and add the identity you've just created to it:

![VM identity](/docs/assets/images/vm-identity-8438ee8159c2272640d9c5ec50706653.png)

Attach this identity to all Azure VMs that will be running the Database Service.

**Using app registrations**

---

NOTE

Registering the Database Service as a Microsoft Entra ID application is suitable for test and development scenarios, or if your Database Service does not run on an Azure VM. For production scenarios prefer to use the managed identity approach.

---

Go to the [App registrations](https://portal.azure.com/#blade/microsoft_aad_iam/activedirectorymenublade/registeredapps) page of Microsoft Entra ID and click on *New registration*:

![App registrations](/docs/assets/images/app-registrations@2x-a69dc84c4caccb1152df850ea6590a1e.png)

Pick a name (e.g. *DatabaseService*) and register a new application. Once the app has been created, take note of its *Application (client) ID* and click on *Add a certificate or secret*:

![Registered app](/docs/assets/images/registered-app@2x-17343162e785824c8c15205d6cf97b6f.png)

Create a new client secret that the Database Service agent will use to authenticate with the Azure API:

![Registered app secrets](/docs/assets/images/registered-app-secrets@2x-3e754c49f06eeaf6c14af3b9d5067e67.png)

The Teleport Database Service uses Azure SDK's default credential provider chain to look for credentials. Refer to [Azure SDK Authorization](https://docs.microsoft.com/en-us/azure/developer/go/azure-sdk-authorization) to pick a method suitable for your use-case. For example, to use environment-based authentication with a client secret, the Database Service should have the following environment variables set:

```
export AZURE_TENANT_ID=
export AZURE_CLIENT_ID=
export AZURE_CLIENT_SECRET=
```

## Step 2/5. Configure IAM permissions for Teleport

### Create a custom role

Teleport needs Azure IAM permissions to discover and register MySQL and PostgreSQL databases. Create a role with assignable scope(s) that include all databases that Teleport should discover. For example:

```
{
    "properties": {
        "roleName": "TeleportDiscovery",
        "description": "Allows Teleport to discover MySQL and PostgreSQL databases",
        "assignableScopes": [
            "/subscriptions/11111111-2222-3333-4444-555555555555"
        ],
        "permissions": [
            {
                "actions": [
                    "Microsoft.DBforMySQL/servers/read",
                    "Microsoft.DBforPostgreSQL/servers/read",
                    "Microsoft.DBforMySQL/flexibleServers/read",
                    "Microsoft.DBforPostgreSQL/flexibleServers/read"
                ],
                "notActions": [],
                "dataActions": [],
                "notDataActions": []
            }
        ]
    }
}

```

This role definition allows Teleport to discover MySQL and PostgreSQL databases, but Teleport only needs permissions for the database types you have. The assignable scopes include a subscription, so the role can be assigned at any resource scope within that subscription, or assigned using the subscription scope itself.

---

CUSTOM ROLE ASSIGNABLE SCOPE

Custom roles, unlike [Azure built-in roles](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles), can not have a root assignable scope. The highest assignable scope that can be used in a custom role is subscription scope. Using a management group scope is currently an Azure preview feature, and only allows for a single management group in the "assignableScopes" of a role definition. See [Azure RBAC custom roles](https://docs.microsoft.com/en-us/azure/role-based-access-control/custom-roles) for more information.

---

Go to the [Subscriptions](https://portal.azure.com/#view/microsoft_azure_billing/subscriptionsblade) page and select a subscription.

Click on *Access control (IAM)* in the subscription and select *Add > Add custom role*: ![IAM custom role](/docs/assets/images/add-custom-role@2x-9b486170e269494f0a84ad7af362a346.png)

In the custom role creation page, click the *JSON* tab and click *Edit*, then paste the JSON example and replace the subscription in "assignableScopes" with your own subscription id: ![Create JSON role](/docs/assets/images/create-role-from-json@2x-14e385e4f480520f3ee32046795f221f.png)

### Create a role assignment for the Teleport Database Service principal

To grant Teleport permissions, the custom role you created must be assigned to the Teleport service principal - either the managed identity or the app registration you created earlier.

Navigate to the resource scope where you want to make the role assignment. Click *Access control (IAM)* and select *Add > Add role assignment*. Choose the custom role you created as the role and the Teleport service principal as a member.

![Assign role](/docs/assets/images/create-role-assignment@2x-4d66bbc72319151aed2fa0e7cbd4bf2d.png)

---

AZURE ROLE ASSIGNMENTS

The role assignment should be at a high enough scope to allow the Teleport Database Service to discover all matching databases. See [Identify the needed scope](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-steps#step-3-identify-the-needed-scope) for more information about Azure scopes and creating role assignments.

---

## Step 3/5. Create Azure database users

To let Teleport connect to your Azure database authenticating as a service principal, you need to create Entra ID users authenticated by that principal in the database.

### Assign Entra ID administrator

Only the Entra ID administrator for the database can connect to it and create Entra ID users.

**MySQL Flexible**

Go to your database's **Authentication** page and set the AD admin using the edit button:

![Set AD admin](/docs/assets/images/set-ad-admin-b23037b9f6e511174a697efa85163e7f.png)

**PostgreSQL Flexible**

Go to your database's **Authentication** page and set the AD admin by selecting **+ Add Entra ID Admins**:

![Set AD admin](/docs/assets/images/set-ad-admin-postgres-d829bfe2fa7d4ee5d50ac0953cf31c74.png)

**Single server**

Go to your database's *Active Directory admin* page and set the AD admin using the *Set admin* button:

![Set AD admin](/docs/assets/images/set-ad-admin@2x-d5b9560971c6439a00bbf7807cb50646.png)

---

ENTRA ID ADMIN

Only one Azure user (or group) can be set as an Entra ID admin for the database. If the Entra ID admin is removed from the server, all Entra ID logins will be disabled for the server. Adding a new Entra ID admin from the same tenant will re-enable Entra ID logins. Refer to [Use Microsoft Entra ID for authenticating with PostgreSQL](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/security-entra-concepts) for more information.

---

### Connect to the database as an AD admin

Next, you need to connect to your database as the AD admin user.

Use the Azure `az` CLI utility to log in as the user that you set as the AD admin, fetch the access token and use it as a password when connecting to the database:

**PostgreSQL Flexible**

```
$ az login -u ad@example.com
$ TOKEN=`az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken`
$ PGPASSWORD=$TOKEN psql "host=example.postgres.database.azure.com user=ad@example.com sslmode=require dbname=postgres"
```

**PostgreSQL**

```
$ az login -u ad@example.com
$ TOKEN=`az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken`
$ PGPASSWORD=$TOKEN psql "host=example.postgres.database.azure.com user=ad@example.com@instance-name sslmode=require dbname=postgres"
```

**MySQL Flexible**

```
$ az login -u ad-admin@example.com
$ TOKEN=`az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken`
$ mysql -h example.mysql.database.azure.com -P 3306 -u ad@example.com --enable-cleartext-plugin --password=$TOKEN
```

**MySQL**

```
$ az login -u ad-admin@example.com
$ TOKEN=`az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken`
$ mysql -h example.mysql.database.azure.com -P 3306 -u ad@example.com@instance-name --enable-cleartext-plugin --password=$TOKEN
```

Note that the database username must include `@instance-name` suffix with the name of the Azure database instance you're connecting to.

### Create AD users

Once connected to the database as AD admin, create database users for the service principal that Teleport Database Service will be using. Use `Client ID` when using managed identities and `Application (client) ID` when using app registrations:

**PostgreSQL**

```
postgres=> SET aad_validate_oids_in_tenant = off;
SET
postgres=> CREATE ROLE teleport WITH LOGIN PASSWORD '11111111-2222-3333-4444-555555555555' IN ROLE azure_ad_user;
CREATE ROLE

```

**PostgreSQL Flexible**

```
postgres=> SELECT * FROM pgaadauth_create_principal_with_oid('teleport', '11111111-2222-3333-4444-555555555555', 'service', false, false);
-------------------------------------
 Created role for teleport
(1 row)

```

**MySQL**

```
mysql> SET aad_auth_validate_oids_in_tenant = OFF;
mysql> CREATE AADUSER 'teleport' IDENTIFIED BY '11111111-2222-3333-4444-555555555555';
Query OK, 0 rows affected (0.92 sec)

```

The created user may not have access to anything by default so let's grant it some permissions:

```
GRANT ALL ON `%`.* TO 'teleport'@'%';

```

You can create multiple database users identified by the same service principal.

## Step 4/5. Install the Teleport Database Service

The Database Service requires a valid join token to join your Teleport cluster. Run the following `tctl` command and save the token output in `/tmp/token` on the server that will run the Database Service:

```
$ tctl tokens add --type=db --format=text
abcd123-insecure-do-not-use-this
```

Install Teleport on the host where you will run the Teleport Database Service:

To install a Teleport Agent on your Linux server:

The recommended installation method is the cluster install script. It will select the correct version, edition, and installation mode for your cluster.

1. Assign teleport.example.com:443 to your Teleport cluster hostname and port, but not the scheme (https\://).

2. Run your cluster's install script:

   ```
   $ curl "https://teleport.example.com:443/scripts/install.sh" | sudo bash
   ```

Create the Database Service configuration.

**PostgreSQL**

- Specify the region for your database(s) in `--azure-postgres-discovery`.

- Replace the `--proxy` value with your Teleport Proxy Service address or Teleport Enterprise (Cloud) URI (e.g. `example.teleport.sh:443`):

  ```
  $ sudo teleport db configure create \
    -o file \
    --proxy=teleport.example.com:443 \
    --token=/tmp/token \
    --azure-postgres-discovery=eastus
  ```

**MySQL**

- Specify the region for your database(s) in `--azure-mysql-discovery`.

- Replace the `--proxy` value with your Teleport Proxy Service address or Teleport Enterprise (Cloud) URI (e.g. `example.teleport.sh:443`):

  ```
  $ sudo teleport db configure create \
    -o file \
    --proxy=teleport.example.com:443 \
    --token=/tmp/token \
    --azure-mysql-discovery=eastus
  ```

**PostgreSQL and MySQL**

Run the following command on your Database Service host:

```
$ sudo teleport db configure create \
  -o file \
  --proxy=teleport.example.com:443 \
  --token=/tmp/token \
  --azure-mysql-discovery=eastus \
  --azure-postgres-discovery=eastus
```

This will create two `types` entities in `teleport.yaml`, one for each database type. This is useful if you want different regions, tags, or labels for each database type.

Alternatively, you can edit `teleport.yaml` to include both database types in a single entry:

```
db_service:
  azure:
  - types: ["mysql", "postgres"]
  ...

```

This command will generate a Database Service configuration with Azure MySQL/Postgres database auto-discovery enabled in the `eastus` region and place it at the `/etc/teleport.yaml` location.

### Create a Teleport role

On your workstation logged in to your Teleport cluster with `tsh`, define a new role to provide access to your Azure database. Create a file called `azure-database-role.yaml` with the following content:

```
version: v7
kind: role
metadata:
  name: azure-database-access
spec:
  allow:
    db_labels:
      'engine':
        - "Microsoft.DBforMySQL/servers"
        - "Microsoft.DBforMySQL/flexibleServers"
        - "Microsoft.DBforPostgreSQL/servers"
        - "Microsoft.DBforPostgreSQL/flexibleServers"
    db_names:
    - '*'
    db_users:
    - teleport

```

| Flag          | Description                                                                                                                              |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `--db-users`  | List of database usernames the user will be allowed to use when connecting to the databases. A wildcard allows any user.                 |
| `--db-names`  | List of logical databases (aka schemas) the user will be allowed to connect to within a database server. A wildcard allows any database. |
| `--db-labels` | List of labels assigned to the database the user will be able to access. A wildcard entry allows any database.                           |

Save this file and apply it to your Teleport cluster:

```
$ tctl create -f azure-database-role.yaml
role 'azure-database-access' has been created
```

---

TIP

You can also create and edit roles using the Web UI. Go to **Access -> Roles** and click **Create New Role** or pick an existing role to edit.

---

Assign the `azure-database-access` role to your Teleport user by running the appropriate commands for your authentication provider:

**Local User**

1. Retrieve your local user's roles as a comma-separated list:

   ```
   $ ROLES=$(tsh status -f json | jq -r '.active.roles | join(",")')
   ```

2. Edit your local user to add the new role:

   ```
   $ tctl users update $(tsh status -f json | jq -r '.active.username') \
     --set-roles "${ROLES?},azure-database-access"
   ```

3. Sign out of the Teleport cluster and sign in again to assume the new role.

**GitHub**

1. Open your `github` authentication connector in a text editor:

   ```
   $ tctl edit github/github
   ```

2. Edit the `github` connector, adding `azure-database-access` to the `teams_to_roles` section.

   The team you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the team must include your user account and should be the smallest team possible within your organization.

   Here is an example:

   ```
     teams_to_roles:
       - organization: octocats
         team: admins
         roles:
           - access
   +       - azure-database-access

   ```

3. Apply your changes by saving and closing the file in your editor.

4. Sign out of the Teleport cluster and sign in again to assume the new role.

**SAML**

1. Retrieve your `saml` configuration resource:

   ```
   $ tctl get --with-secrets saml/mysaml > saml.yaml
   ```

   Note that the `--with-secrets` flag adds the value of `spec.signing_key_pair.private_key` to the `saml.yaml` file. Because this key contains a sensitive value, you should remove the saml.yaml file immediately after updating the resource.

2. Edit `saml.yaml`, adding `azure-database-access` to the `attributes_to_roles` section.

   The attribute you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the group must include your user account and should be the smallest group possible within your organization.

   Here is an example:

   ```
     attributes_to_roles:
       - name: "groups"
         value: "my-group"
         roles:
           - access
   +       - azure-database-access

   ```

3. Apply your changes:

   ```
   $ tctl create -f saml.yaml
   ```

4. Sign out of the Teleport cluster and sign in again to assume the new role.

**OIDC**

1. Retrieve your `oidc` configuration resource:

   ```
   $ tctl get oidc/myoidc --with-secrets > oidc.yaml
   ```

   Note that the `--with-secrets` flag adds the value of `spec.signing_key_pair.private_key` to the `oidc.yaml` file. Because this key contains a sensitive value, you should remove the oidc.yaml file immediately after updating the resource.

2. Edit `oidc.yaml`, adding `azure-database-access` to the `claims_to_roles` section.

   The claim you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the group must include your user account and should be the smallest group possible within your organization.

   Here is an example:

   ```
     claims_to_roles:
       - name: "groups"
         value: "my-group"
         roles:
           - access
   +       - azure-database-access

   ```

3. Apply your changes:

   ```
   $ tctl create -f oidc.yaml
   ```

4. Sign out of the Teleport cluster and sign in again to assume the new role.

### Start Teleport Database Service

Configure the Teleport Database Service to start automatically when the host boots up by creating a systemd service for it. The instructions depend on how you installed the Teleport Database Service.

**Package Manager**

On the host where you will run the Teleport Database Service, enable and start Teleport:

```
$ sudo systemctl enable teleport
$ sudo systemctl start teleport
```

**TAR Archive**

On the host where you will run the Teleport Database Service, create a systemd service configuration for Teleport, enable the Teleport service, and start Teleport:

```
$ sudo teleport install systemd -o /etc/systemd/system/teleport.service
$ sudo systemctl enable teleport
$ sudo systemctl start teleport
```

You can check the status of the Teleport Database Service with `systemctl status teleport` and view its logs with `journalctl -fu teleport`.

---

TIP

A single Teleport process can run multiple different services, for example multiple Database Service agents as well as the SSH Service or Application Service.

---

## Step 5/5. Connect

Log in to your Teleport cluster. Your Azure database should appear in the list of available databases:

**Self-Hosted**

```
$ tsh login --proxy=teleport.example.com --user=alice
$ tsh db ls
Name     Description         Labels
-------- ------------------- -------
azure-db                     env=dev
```

**Teleport Enterprise Cloud**

```
$ tsh login --proxy=mytenant.teleport.sh --user=alice
$ tsh db ls
Name     Description         Labels
-------- ------------------- -------
azure-db                     env=dev
```

**MySQL/MariaDB**

Retrieve credentials for the database and connect to it as the `teleport` user:

```
$ tsh db connect --db-user=teleport --db-name=mysql azure-db
```

---

NOTE

Either the `mysql` or the `mariadb` client must be available on `PATH` to connect.

---

---

TIP

You can also [access your MySQL or MariaDB databases using the Web UI.](https://goteleport.com/docs/connect-your-client/teleport-clients/web-ui.md#starting-a-database-session)

---

**PostgreSQL**

Retrieve credentials for the database and connect to it as the `teleport` user:

```
$ tsh db connect --db-user=teleport --db-name=postgres azure-db
```

---

NOTE

The `psql` client must be available on `PATH` to connect.

---

---

TIP

You can also [access your PostgreSQL databases using the Web UI.](https://goteleport.com/docs/connect-your-client/teleport-clients/web-ui.md#starting-a-database-session)

---

To log out of the database and remove credentials:

```
$ tsh db logout azure-db
```

## Troubleshooting

### No credential providers error

If you see the error `DefaultAzureCredential: failed to acquire a token.` in Database Service logs then Teleport is not detecting the required credentials to connect to the Azure SDK. Check whether the credentials have been applied in the machine running the Teleport Database Service and restart the Teleport Database Service. Refer to [Azure SDK Authorization](https://docs.microsoft.com/en-us/azure/developer/go/azure-sdk-authorization) for more information.

### Timeout errors

The Teleport Database Service needs connectivity to your database endpoints. That may require enabling inbound traffic on the database from the Database Service on the same VPC or routing rules from another VPC. Using the `nc` program you can verify connections to databases:

```
$ nc -zv server-name.postgres.database.azure.com 5432
Connection to server-name.postgres.database.azure.com 5432 port [tcp/postgresql] succeeded!
```

### Unable to cancel a query

If you use a PostgreSQL cli client like `psql`, and you try to cancel a query with `Ctrl+C`, but it doesn't cancel the query, then you need to connect using a tsh local proxy instead. When `psql` cancels a query, it establishes a new connection without TLS certificates, however Teleport requires TLS certificates not only for authentication, but also to route database connections.

If you [enable TLS Routing in Teleport](https://goteleport.com/docs/zero-trust-access/deploy-a-cluster/tls-routing.md) then `tsh db connect` will automatically start a local proxy for every connection. Alternatively, you can connect via [Teleport Connect](https://goteleport.com/docs/connect-your-client/teleport-clients/teleport-connect.md) which also uses a local proxy. Otherwise, you need to start a tsh local proxy manually using `tsh proxy db` and connect via the local proxy.

If you have already started a long-running query in a `psql` session that you cannot cancel with `Ctrl+C`, you can start a new client session to cancel that query manually:

First, find the query's process identifier (PID):

```
SELECT pid,usename,backend_start,query FROM pg_stat_activity WHERE state = 'active';

```

Next, gracefully cancel the query using its PID. This will send a SIGINT signal to the postgres backend process for that query:

```
SELECT pg_cancel_backend(<PID>);

```

You should always try to gracefully terminate a query first, but if graceful cancellation is taking too long, then you can forcefully terminate the query instead. This will send a SIGTERM signal to the postgres backend process for that query:

```
SELECT pg_terminate_backend(<PID>);

```

See the PostgreSQL documentation on [admin functions](https://www.postgresql.org/docs/current/functions-admin.html#functions-admin-signal) for more information about the `pg_cancel_backend` and `pg_terminate_backend` functions.

### SSL SYSCALL error

You may encounter the following error when your local `psql` is not compatible with newer versions of OpenSSL:

```
$ tsh db connect --db-user postgres --db-name postgres postgres
psql: error: connection to server at "localhost" (::1), port 12345 failed: Connection refused
    Is the server running on that host and accepting TCP/IP connections?
connection to server at "localhost" (127.0.0.1), port 12345 failed: SSL SYSCALL error: Undefined error: 0
```

Please upgrade your local `psql` to the latest version.

## Next steps

- Learn how to [restrict access](https://goteleport.com/docs/enroll-resources/database-access/rbac.md) to certain users and databases.

* View the [High Availability (HA)](https://goteleport.com/docs/enroll-resources/agents/high-availability.md) guide.

- Take a look at the YAML configuration [reference](https://goteleport.com/docs/enroll-resources/database-access/reference/configuration.md).

* See the full CLI [reference](https://goteleport.com/docs/enroll-resources/database-access/reference/cli.md).
