# Using the tsh Command Line Tool

This guide shows you how to use the Teleport client tool `tsh` to connect to infrastructure resources in your cluster.

You will learn how to:

- List, access, and interact with Teleport-connected resources.
- Share interactive shell sessions with colleagues or join someone else's session.
- List and replay recorded interactive sessions.

In addition to this document, you can type `tsh` into your terminal for the CLI reference, or explore the [`tsh` CLI Reference](https://goteleport.com/docs/reference/cli/tsh.md#tsh-login) in the documentation.

You can also use `tsh` to manage Access Requests. For instructions, see [Request Access to Roles and Resources](https://goteleport.com/docs/connect-your-client/teleport-clients/request-access.md).

## Installing tsh

Follow the instructions below to install the `tsh` binary.

1. Determine the version of `tsh` to install. We recommend installing the same major version as the version used in your Teleport cluster. Either:

   - In the Web UI, select your username in the upper right, then click **Help & Support**. You will see the version of your Teleport cluster under **Cluster Information**.

   - Use `curl` and `jq`. Replace teleport.example.com with your Proxy Service address (e.g. `mytenant.teleport.sh` for Teleport Enterprise Cloud):

     ```
     $ curl https://teleport.example.com/webapi/find | jq '.server_version'
     "19.0.0-dev"
     ```

2. Install a package that includes `tsh`:

   **Mac**

   Download the signed macOS .pkg installer for Teleport, which includes `tsh`. In Finder double-click the `pkg` file to begin installation:

   ```
   $ curl -O https://cdn.teleport.dev/teleport-19.0.0-dev.pkg
   ```

   ---

   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-v19.0.0-dev-windows-amd64-bin.zip
   Unzip the archive and move tsh.exe to your %PATH%
   NOTE: Do not place tsh.exe 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 `tsh`. 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-v19.0.0-dev-linux-amd64-bin.tar.gz
   $ tar -xzf teleport-v19.0.0-dev-linux-amd64-bin.tar.gz
   $ cd teleport
   $ sudo ./install
   Teleport binaries have been copied to /usr/local/bin
   ```

## Basic usage

`tsh` allows you to view infrastructure resources that you can access in Teleport and connect to those resources. This section shows you the main workflow for using `tsh` to access an infrastructure resource.

### Log in to Teleport

Log in to your Teleport cluster, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and myuser to your Teleport username:

```
$ tsh login --proxy=teleport.example.com --user=myuser
```

This command retrieves the user's certificates and saves them into `~/.tsh/teleport.example.com`.

### List resources that you can access

In a Teleport cluster, all Teleport Agents periodically ping the cluster's Auth Service and update their status. This allows Teleport users to see which Teleport-protected resources are online.

This command lists all connected servers in the cluster that you have permission to access:

```
$ tsh ls

Node Name     Address            Labels
---------     -------            ------
turing        ⟵ Tunnel          os=linux
graviton      10.1.0.7:3022      os=osx
```

You can use `tsh` commands to list other kinds of resources. For more information, see the `tsh` reference entries for the following resource types:

| Resource                                                                                             | Command       |
| ---------------------------------------------------------------------------------------------------- | ------------- |
| [Applications](https://goteleport.com/docs/reference/cli/tsh.md#tsh-apps-ls)                         | `tsh apps ls` |
| [Databases](https://goteleport.com/docs/enroll-resources/database-access/reference/cli.md#tsh-db-ls) | `tsh db ls`   |
| [Kubernetes clusters](https://goteleport.com/docs/reference/cli/tsh.md#tsh-kube-ls)                  | `tsh kube ls` |
| [Servers](https://goteleport.com/docs/reference/cli/tsh.md#tsh-ls)                                   | `tsh ls`      |

Windows desktops are available to list in Teleport Connect and the Teleport Web UI.

`tsh <resource> ls` commands can apply a filter based on the resource's labels. For example, to only show servers with the `os` label set to `osx`, you can run the following command:

```
$ tsh ls os=osx

Nodename      Address            Labels
---------     -------            ------
graviton      10.1.0.7:3022      os=osx
```

Not seeing resources?

When the Teleport Auth Service receives a request to list Teleport-connected resources (e.g., to display resources in the Web UI or via `tsh ls`), it only returns the resources that the current user is authorized to view.

For each resource in the user's Teleport cluster, the Auth Service applies the following checks in order and, if one check fails, hides the resource from the user:

- None of the user's roles contain a `deny` rule that matches the resource's labels.
- At least one of the user's roles contains an `allow` rule that matches the resource's labels.

If you are not seeing resources when expected, make sure that your user's roles include the appropriate `allow` and `deny` rules as documented in the [Access Controls Reference](https://goteleport.com/docs/reference/access-controls/roles.md).

### Connect to a resource

Once you have determined a resource to connect to, the next step is to access the resource with `tsh`, which handles authentication to your Teleport cluster and routing traffic to and from local clients.

You can only connect to a Windows desktop using the Teleport Web UI or Teleport Connect.

Select a resource type for instructions on connecting to the resource with `tsh`:

**Servers**

Run the `tsh ssh` command to connect to a server, specifying the login to assume on the server you are connecting to. The following command connects to the server `mynode` as user `root`:

```
$ tsh ssh root@mynode
```

`tsh ssh` takes the same arguments and flags as the OpenSSH client. For more information on connecting to servers, see [Connecting to SSH servers](#connecting-to-ssh-servers).

**Applications**

You can access web applications registered with Teleport through Teleport Connect and the Teleport Web UI.

You can also use `tsh` to start a local proxy server and connect to your application with your client of choice. The local proxy manages Teleport-issued certificates automatically. This example connects to the app `myapp`:

```
$ tsh proxy app myapp
```

You can avoid the need to manually start the local proxy for application clients by using VNet. See [Using VNet](https://goteleport.com/docs/connect-your-client/teleport-clients/vnet.md) for instructions.

For APIs protected with Teleport, use `tsh apps login` to receive a certificate authorized to access the application, which in this example, is `grafana`:

```
$ tsh apps login grafana
```

You can then access the application with a command like the following:

```
$ curl \
  --cert /Users/alice/.tsh/keys/teleport.example.com/alice-app/cluster-name/grafana-x509.pem \
  --key /Users/alice/.tsh/keys/teleport.example.com/alice \
  https://grafana.teleport.example.com:3080
```

Since the local proxy manages Teleport-issued application certificates automatically, we recommend that you use it instead of `tsh apps login` unless it is necessary to manually reference TLS credentials.

For cloud APIs protected by Teleport, you can use the following `tsh` commands to execute a single API client command or start a local proxy that API client applications can proxy traffic through:

| Cloud API    | Single command                                                                                | Local proxy                                                                           |
| ------------ | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| AWS          | `tsh aws`                                                                                     | [tsh proxy aws](https://goteleport.com/docs/reference/cli/tsh.md#tsh-proxy-aws)       |
| Azure        | [tsh az](https://goteleport.com/docs/enroll-resources/application-access/reference.md#tsh-az) | [tsh proxy azure](https://goteleport.com/docs/reference/cli/tsh.md#tsh-proxy-azure)   |
| Google-Cloud | [tsh gcloud](https://goteleport.com/docs/reference/cli/tsh.md#tsh-gcloud)                     | [tsh proxy gcloud](https://goteleport.com/docs/reference/cli/tsh.md#tsh-proxy-gcloud) |

**Databases**

To receive a certificate from Teleport signed for your database user and connect to the database, run the following command, assuming `mydb` is the name of the database registered with Teleport and `my-database-user` is the name of your database user:

```
$ tsh db connect --db-user=my-database-user mydb
```

Once you have finished your database session, you can remove the certificate for the database by running the following command:

```
$ tsh db logout
```

Some databases require `tsh` to start a local proxy server to forward traffic from your workstation. `tsh db connect` starts the local proxy if it needs to, but you can also start the proxy yourself. This is useful for running graphical database clients. For example, you can start a local proxy with an authenticated tunnel using the following command:

```
$ tsh proxy db --tunnel mydb
```

For more information, see [GUI Clients](https://goteleport.com/docs/connect-your-client/third-party/gui-clients.md).

**Kubernetes clusters**

To access a Teleport-connected Kubernetes cluster, run the following command to update your kubeconfig with a certificate signed by Teleport. The following command logs in to the cluster mycluster:

```
$ tsh kube login mycluster
```

Once you have logged into the cluster, run `tsh kubectl` to execute `kubectl` commands. Teleport can allow or deny access to specific Kubernetes cluster resources. `tsh kubectl` detects whether the command has failed due to insufficient permissions and, if so, submits an Access Request for the target Kubernetes resource.

For example, the following command executes the `date` command in pod `my-pod` and submits an Access Request if the user does not have permissions to access that pod:

```
$ tsh kubectl exec my-pod -- date
```

## Logging in

To retrieve a user's certificate, execute:

**Self-Hosted**

```
Full form:
$ tsh login --proxy=proxy_host:<https_proxy_port>

Using default ports:
$ tsh login --proxy=work.example.com

Using custom HTTPS port:
$ tsh login --proxy=work.example.com:5000
```

**Teleport Enterprise Cloud**

```
Full form:
$ tsh login --proxy=proxy_host:<https_proxy_port>

$ tsh login --proxy=mytenant.teleport.sh
```

[CLI Docs - tsh login](https://goteleport.com/docs/reference/cli/tsh.md#tsh-login)

| Port               | Description                                                                   |
| ------------------ | ----------------------------------------------------------------------------- |
| https\_proxy\_port | the HTTPS port the proxy host is listening to (defaults to `443` and `3080`). |

The login command retrieves a user's certificate and stores it in `~/.tsh` directory as well as in the [ssh agent](https://en.wikipedia.org/wiki/Ssh-agent) if there is one running.

This allows you to authenticate just once, maybe at the beginning of the day. Subsequent `tsh ssh` commands will run without asking for credentials until the temporary certificate expires. By default, Teleport issues user certificates with a time to live (TTL) of 12 hours.

---

TIP

It is recommended to always use [`tsh login`](https://goteleport.com/docs/reference/cli/tsh.md#tsh-login) before using any other `tsh` commands. This allows users to omit `--proxy` flag in subsequent tsh commands. For example `tsh ssh user@host` will work.

---

A Teleport cluster can be configured for multiple user identity sources. For example, a cluster may have a local user called `admin` while regular users should [authenticate via GitHub](https://goteleport.com/docs/zero-trust-access/sso/integrate-idp/github-sso.md). In this case, you have to pass `--auth` flag to `tsh login` to specify which identity storage to use:

**Self-Hosted**

```
Log in using the local Teleport 'admin' user:
$ tsh --proxy=proxy.example.com --auth=local --user=admin login

Log in using GitHub as an SSO provider, assuming the GitHub connector is called "github"
$ tsh --proxy=proxy.example.com --auth=github login

Don't open the system default browser when logging in
$ tsh login --proxy=work.example.com --browser=none
```

**Teleport Enterprise Cloud**

```
Log in using the local Teleport 'admin' user:
$ tsh --proxy=mytenant.teleport.sh --auth=local --user=admin login

Log in using GitHub as an SSO provider, assuming the GitHub connector is called "github"
$ tsh --proxy=mytenant.teleport.sh --auth=github login
```

When using an external identity provider to log in, `tsh` will need to open a web browser to complete the authentication flow. By default, `tsh` will use your system's default browser. If you wish to suppress this behavior, you can use the `--browser=none` flag:

**Teleport Enterprise Cloud**

```
Don't open the system default browser when logging in
$ tsh login --proxy=mytenant.teleport.sh --browser=none
```

In this situation, a link will be printed on the screen. You can copy and paste this link into a browser of your choice to continue the login flow.

[CLI Docs - tsh login](https://goteleport.com/docs/reference/cli/tsh.md#tsh-login)

### Inspecting an SSH certificate

To inspect the SSH certificates in `~/.tsh`, a user may execute the following command:

**Self-Hosted**

```
$ tsh status

> Profile URL:  https://proxy.example.com:3080
Logged in as: johndoe
Cluster:      proxy.example.com
Roles:        access, auditor, editor
Logins:       root, admin, guest
Kubernetes:   enabled
Valid until:  2017-04-25 15:02:30 -0700 PDT [valid for 1h0m0s]
Extensions:   permit-agent-forwarding, permit-port-forwarding, permit-pty
```

**Teleport Enterprise Cloud**

```
$ tsh status

> Profile URL:  https://mytenant.teleport.sh:443
Logged in as: johndoe
Cluster:      mytenant.teleport.sh
Roles:        access, editor, auditor
Logins:       root, admin, guest
Kubernetes:   enabled
Valid until:  2017-04-25 15:02:30 -0700 PDT [valid for 1h0m0s]
Extensions:   permit-agent-forwarding, permit-port-forwarding, permit-pty
```

[CLI Docs - tsh status](https://goteleport.com/docs/reference/cli/tsh.md#tsh-status)

### Identity files

[`tsh login`](https://goteleport.com/docs/reference/cli/tsh.md#tsh-login) can also save the user certificate into a file:

**Self-Hosted**

```
Authenticate the user against proxy.example.com and save the user
certificate to joe.pem
$ tsh login --proxy=proxy.example.com --out=joe

Use joe.pem to log in to the server 'db'
$ tsh ssh --proxy=proxy.example.com -i joe joe@db
```

**Teleport Enterprise Cloud**

```
Authenticate the user against mytenant.teleport.sh and save the user
certificate to joe.pem
$ tsh login --proxy=mytenant.teleport.sh --out=joe

Use joe.pem to log in to the server 'db'
$ tsh ssh --proxy=mytenant.teleport.sh -i joe joe@db
```

By default, the `--out` flag will create an identity file suitable for `tsh -i`. If compatibility with OpenSSH is needed, `--format=openssh` must be specified. In this case, the identity will be saved into two files, `joe` and `joe-cert.pub`:

**Self-Hosted**

```
$ tsh login --proxy=proxy.example.com --out=joe --format=openssh
$ ls -lh

total 8.0K
-rw------- 1 joe staff 1.7K Aug 10 16:16 joe
-rw------- 1 joe staff 1.5K Aug 10 16:16 joe-cert.pub
```

**Teleport Enterprise Cloud**

```
$ tsh login --proxy=mytenant.teleport.sh --out=joe --format=openssh
$ ls -lh

total 8.0K
-rw------- 1 joe staff 1.7K Aug 10 16:16 joe
-rw------- 1 joe staff 1.5K Aug 10 16:16 joe-cert.pub
```

### SSH certificates for automation

Regular users of Teleport must request an auto-expiring SSH certificate, usually every day. This doesn't work for non-interactive scripts, like cron jobs or a CI/CD pipeline.

The most secure way to generate certificates for automation purposes is to use [Machine & Workload Identity](https://goteleport.com/docs/machine-workload-identity.md). This ensures that your automation is taking advantage of the security properties of short-lived credentials.

If Machine & Workload Identity does not support your preferred CI/CD platform, you can create a local user for use in automation and request a long-lived certificate for that user.

In this example, we're creating a certificate with a TTL of one hour for the `jenkins` user and storing it in a `jenkins.pem` file, which can be later used with `-i` (identity) flag for `tsh`.

**Self-Hosted**

```
Log in to your cluster with tsh so you can use tctl from your local machine.
You can also run tctl on your Auth Service host without running "tsh login"
first.
$ tsh login --proxy=teleport.example.com --user=myuser
$ tctl auth sign --ttl=1h --user=jenkins --out=jenkins.pem
```

**Teleport Enterprise Cloud**

```
Log in to your Teleport Cloud cluster so you can use tctl locally.
$ tsh login --proxy=myinstance.teleport.sh --user=email@example.com
$ tctl auth sign --ttl=1h --user=jenkins --out=jenkins.pem
```

[CLI Docs - tctl auth sign](https://goteleport.com/docs/reference/cli/tctl.md#tctl-auth-sign)

Now `jenkins.pem` can be copied to the Jenkins server and passed to the `-i` (identity file) flag of `tsh`.

`tctl auth sign` is an admin's equivalent of `tsh login --out` and allows for unrestricted certificate TTL values.

## Connecting to SSH servers

This section provides detailed information about using `tsh` to connect to SSH servers registered with your Teleport cluster.

### User identities

A user identity in Teleport exists in the scope of a cluster. The member nodes of a cluster may have multiple OS users on them. A Teleport administrator assigns allowed logins to every Teleport user account.

When logging into a remote node, you will have to specify both the Teleport login and the OS login. A Teleport identity will have to be passed via the `--user` flag while the OS login will be passed as `login@host` using syntax compatible with the traditional `ssh` command.

The following command authenticates against the teleport.example.com cluster and logs into the server `node` as `root`:

```
$ tsh ssh --proxy=teleport.example.com --user=joe root@node
```

### Proxy ports

By default, the Teleport Proxy Service listens on port `3080`.

If a Teleport Proxy Service instance is configured to listen on non-default ports, they must be specified via `--proxy` flag as shown:

```
$ tsh --proxy=proxy.example.com:5000 <subcommand>
```

This `tsh` command will use port `5000` of the Proxy Service.

### Port forwarding

`tsh ssh` supports the OpenSSH `-L` flag which forwards incoming connections from localhost to the specified remote host:port. The syntax of `-L` flag is as follows, where "bind\_ip" defaults to `127.0.0.1`:

```
$ -L [bind_ip]:listen_port:remote_host:remote_port
```

Example:

```
$ tsh ssh -L 5000:web.remote:80 node
```

This will connect to remote server `node` via the Proxy Service, then open a listening socket on `localhost:5000`. Finally, it will forward all incoming connections to `web.remote:80` via this SSH tunnel.

It is often convenient to establish port forwarding, execute a local command which uses the connection, and then disconnect. You can do this with the `--local` flag.

Example:

```
$ tsh ssh -L 5000:google.com:80 --local node curl http://localhost:5000
```

This command:

- Connects to `node`.
- Binds the local port `5000` to port `80` on `google.com`.
- Executes `curl` command locally, which results in `curl` hitting `google.com:80` via `node`.

### SSH agent support

If there is an [ssh agent](https://en.wikipedia.org/wiki/Ssh-agent) running, `tsh login` will store the user certificate in the agent. This can be verified via:

```
$ ssh-add -L
```

The SSH agent can be used to feed the certificate to other SSH clients, for example to OpenSSH (`ssh`).

If you wish to disable SSH agent integration, pass `--add-keys-to-agent=no` to `tsh`. You can also set the `TELEPORT_ADD_KEYS_TO_AGENT` environment variable to `no` in your shell profile to make this permanent.

For a full reference of `tsh` flags and environment variables, see the [`tsh Reference`](https://goteleport.com/docs/reference/cli/tsh.md).

### SSH jump host

While implementing `ProxyJump` for Teleport, we have extended the feature to `tsh`.

**Self-Hosted**

```
$ tsh ssh -J proxy.example.com telenode
```

**Teleport Enterprise Cloud**

```
$ tsh ssh -J mytenant.teleport.sh telenode
```

Known limitations:

- Only one jump host is supported (`-J` supports chaining that Teleport does not utilize) and `tsh` will return with error in the case of two jump hosts, i.e. `-J proxy-1.example.com,proxy-2.example.com` will not work.
- When `tsh ssh -J user@proxy` is used, it overrides the SSH proxy defined in the tsh profile, and port forwarding is used instead of the existing Teleport proxy subsystem.

### Resolving server names

`tsh` supports multiple methods to resolve remote Node names.

- **Traditional**: by IP address or via DNS.
- **Nodename setting**: the `teleport` daemon supports the` nodename` flag, which allows Teleport administrators to assign alternative Node names.
- **Labels**: you can address a Node by `name=value` pair.

If we have two Nodes, one with `os:linux` label and one Node with `os:osx`, we can log in to the OSX Node with:

```
$ tsh ssh os=osx
```

This only works if there is only one remote node with the `os:osx` label, but you can still execute commands via SSH on multiple Nodes using labels as a selector. This command will update all system packages on machines that run Linux:

```
$ tsh ssh os=ubuntu apt-get update -y
```

### Short-lived sessions

The default TTL of a Teleport user certificate is 12 hours. This can be modified at login with the `--ttl` flag. This command logs you into the cluster with a very short-lived (1 minute) temporary certificate:

```
$ tsh --ttl=1 login
```

You will be logged out after one minute, but if you want to log out immediately, you can always run:

```
$ tsh logout
```

### Connecting to SSH clusters behind firewalls

Teleport supports creating clusters of servers located behind firewalls **without any open listening TCP ports**. This works by creating reverse SSH tunnels from behind-firewall environments into a Teleport Proxy Service you have access to.

To learn more about setting up a trust relationship between clusters behind firewalls, see [Configure Trusted Clusters](https://goteleport.com/docs/zero-trust-access/deploy-a-cluster/trustedclusters.md).

---

NOTE

Trusted clusters are only available for self-hosted Teleport clusters.

---

Assuming the Teleport Proxy Server called `work` is configured with a few trusted clusters, you can use the `tsh clusters` command to see a list of all the trusted clusters on the server:

```
$ tsh --proxy=work clusters

Cluster Name     Status
------------     ------
staging          online
production       offline
```

[CLI Docs - tsh clusters](https://goteleport.com/docs/reference/cli/tsh.md#tsh-clusters)

Now you can use the `--cluster` flag with any `tsh` command. For example, to list SSH nodes that are members of the `production` cluster, simply run:

```
$ tsh --proxy=work ls --cluster=production

Node Name     Node ID       Address            Labels
---------     -------       -------            ------
db-1          xxxxxxxxx     10.0.20.31:3022    kernel:4.4
db-2          xxxxxxxxx     10.0.20.41:3022    kernel:4.2
```

Similarly, if you want to SSH into `db-1` inside the `production` cluster:

```
$ tsh --proxy=work ssh --cluster=production db-1
```

This is possible even if Nodes in the `production` cluster are located behind a firewall without open ports. This works because the `production` cluster establishes a reverse SSH tunnel back into the Proxy Service called `work`, and this tunnel is used to establish inbound SSH connections.

### X11 forwarding

In order to run graphical programs within an SSH session, such as an IDE like Visual Studio Code, you'll need to request X11 forwarding for the session with the `-X` flag.

```
$ tsh ssh -X node01
```

X11 forwarding provides the server with secure access to your local X Server so that it can communicate directly with your local display and I/O devices.

---

NOTE

The `-Y` flag can be used to start Trusted X11 forwarding. This is needed in order to enable more "unsafe" features, such as running clipboard or screenshot utilities like `xclip`. However, it provides the server with unmitigated access to your local X Server and puts your local machine at risk of X11 attacks, so it should only be used with extreme caution.

---

In order to use X11 forwarding, you'll need to enable it on the Teleport Node. You'll also need to ensure that your user has the `permit_x11_forwarding` role option:

```
$ tsh status
> Profile URL:        https://proxy.example.com:3080
  Logged in as:       dev
  ...
  Extensions:         permit-X11-forwarding
```

## Interacting with SSH servers

In this section, you will find details on interacting with SSH servers with `tsh`.

### Interactive shell

To launch an interactive shell on a remote Node or to execute a command, use `tsh ssh`.

`tsh` tries to mimic the `ssh` experience as much as possible, so it supports the most popular `ssh` flags like `-p`, `-l` or `-L`. For example, if you have the following alias defined in your `~/.bashrc`: `alias ssh="tsh ssh"` then you can continue using familiar SSH syntax:

**Self-Hosted**

```
Have this alias configured, perhaps via ~/.bashrc
$ alias ssh="/usr/local/bin/tsh ssh"

Login in to a cluster and retrieve your SSH certificate:
$ tsh --proxy=proxy.example.com login

These commands execute `tsh ssh` under the hood:
$ ssh user@node
$ ssh -p 6122 user@node ls
$ ssh -o ForwardAgent=yes user@node
$ ssh -o AddKeysToAgent=yes user@node
```

**Teleport Enterprise Cloud**

```
Have this alias configured, perhaps via ~/.bashrc
$ alias ssh="/usr/local/bin/tsh ssh"

Login in to a cluster and retrieve your SSH certificate:
$ tsh --proxy=mytenant.teleport.sh login

These commands execute `tsh ssh` under the hood:
$ ssh user@node
$ ssh -p 6122 user@node ls
$ ssh -o ForwardAgent=yes user@node
$ ssh -o AddKeysToAgent=yes user@node
```

### Copying files

To securely copy files to and from cluster Nodes, use the `tsh scp` command. It is designed to mimic OpenSSH's `scp` command as much as possible:

```
$ tsh scp example.txt root@node:/path/to/dest
```

Again, you may want to create a bash alias like `alias scp="tsh --proxy=work scp"` and use the familiar syntax:

```
$ scp -P 61122 -r files root@node:/path/to/dest
```

Teleport supports both the SCP and SFTP protocols. OpenSSH `scp` or `sftp` commands can both be used in place of `tsh scp` if desired.

### Sharing sessions

Suppose you are trying to troubleshoot a problem on a remote server. Sometimes it makes sense to ask another team member for help. Traditionally, this could be done by letting them know which host you're on, having them SSH in, start a terminal multiplexer like `screen`, and join a session there.

Teleport makes this more convenient. Let's log in to a server named `luna` and ask Teleport for our current session status:

```
$ tsh ssh luna
on host luna
$ teleport status

User ID    : joe, logged in as joe from 10.0.10.1 43026 3022
Session ID : 7645d523-60cb-436d-b732-99c5df14b7c4
Session URL: https://work:3080/web/sessions/7645d523-60cb-436d-b732-99c5df14b7c4
```

Now you can invite another user account to the `work` cluster. You can share the URL for access through a web browser, or you can share the session ID, and the other user can join you through their terminal by typing:

```
$ tsh join <session_ID>
```

---

LACKING PERMISSION?

Joining sessions requires special permissions that need to be set up by your cluster administrator. Refer them to the [Moderated Sessions guide](https://goteleport.com/docs/zero-trust-access/authentication/joining-sessions.md) for more information on configuring join permissions.

---

You can also list active sessions with the `tsh sessions ls` command.

---

NOTE

Joining sessions is not supported in recording proxy mode (where `session_recording` is set to `proxy`).

---

## Proxying Git commands

Use `tsh git ls` to view a list of GitHub organizations you have access to:

```
$ tsh git ls
Type   Organization  Username URL
------ ------------- -------- --------------------------------
GitHub my-github-org my-user  https://github.com/my-github-org
```

Teleport requires your GitHub identity to impersonate you. If you haven't provided it yet, run the following command:

```
$ tsh git login --github-org my-github-org
  If browser window does not open automatically, open it by clicking on the link:
   http://127.0.0.1:55555/some-id
  Your GitHub username is my-user.
```

This command opens a browser, prompting you to authenticate with GitHub via the OAuth app: ![GitHub SSO authorization view](/docs/assets/images/github-sso-auth-screen-9201472bb34dbc0ebad02a6dba04f2f5.jpg)

To clone a repository from your GitHub organization, find the SSH clone URL and run:

```
$ tsh git clone git@github.com:my-github-org/my-repo.git
Cloning into 'my-repo'...
```

To configure an existing Git repository with Teleport, go to the repository and run:

```
$ tsh git config update
The current Git directory is configured with Teleport for GitHub organization "my-github-org".
```

Once the repo is cloned or configured, you can use `git` commands as normal:

```
$ cd my-repo
$ git fetch

```

Note that the OAuth app authentication flow and Git repository configuration are one-time setups and don't need to be repeated.

## Debug logs

Adding the `--debug` flag to a command or setting the `TELEPORT_DEBUG` env var to `1` makes tsh print debug logs to standard output.

### Unified logging system on macOS

On macOS, the `--os-log` flag can be used instead of `--debug` to send debug logs to [the unified logging system](https://support.apple.com/en-gb/guide/console/welcome/mac). This behavior can also be controlled through the `TELEPORT_OS_LOG` env var.

To stream logs in a separate shell session:

```
$ log stream --predicate 'subsystem CONTAINS "tsh"' --style syslog --level debug
```

To dump logs captured so far to a file:

```
$ log show --predicate 'subsystem CONTAINS "tsh"' --style syslog --info --debug > tsh.log
```

The logs can also be inspected in [the Console app](https://support.apple.com/en-gb/guide/console/cnsl1012/1.1/mac/15.0). Info and debug logs are not shown by default, so make sure to select "Include Info Messages" and "Include Debug Messages" from the Action menu.

## Examining recorded sessions

You can use `tsh` to examine sessions that users have completed in resources protected by Teleport. This section explains how to list and play Teleport session recordings with `tsh`.

To view the recording, select **Audit** in the Teleport Web UI, then click **Session Recordings** in the menu.

### Listing recordings

Run the following command to review recorded sessions:

```
$ tsh recordings ls
ID                                   Type Participants Hostname Timestamp
------------------------------------ ---- ------------ -------- -------------------
b0a04442-70dc-4be8-9308-7b7901d2d600 ssh  jeff         dev       Nov 26 16:36:16 UTC
c0a02222-70dc-4be8-9308-7b7901d2d600 kube alice                  Nov 26 20:36:16 UTC
d0a04442-70dc-4be8-9308-7b7901d2d600 ssh  navin        test      Nov 26 16:36:16 UTC
```

### Playing recordings

To play a session recording, run the `tsh play` command with the ID of a session as returned by `tsh recordings ls`:

```
$ tsh play c0a02222-70dc-4be8-9308-7b7901d2d600
```

You can also run `tsh play` with the path to a TAR file that contains a session recording:

```
$ tsh play ./my-recording.tar
```

To retrieve a TAR file containing a session recording, you must have access to the session recording backend. This requires either a self-hosted Teleport cluster or [external audit storage](https://goteleport.com/docs/zero-trust-access/management/external-audit-storage.md).

The `tsh play` command can print recordings in several formats, depending on the kind of resource the recorded session interacts with. To choose a format, use the `--format` flag of `tsh play`:

| `--format` value | Supported resources                                   | Description                                                                         |
| ---------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `pty` (default)  | Servers, Kubernetes clusters                          | `tsh` opens a pseudo-terminal to play each command executed in the session.         |
| `text`           | Servers, Kubernetes clusters                          | `tsh` dumps the entire recording directly to standard out. Timing data is ignored.  |
| `json`           | Servers, Kubernetes clusters, applications, databases | `tsh` prints a JSON-serialized list of audit events, separated by newlines.         |
| `yaml`           | Servers, Kubernetes clusters, applications, databases | `tsh` prints a YAML-serialized list of audit events, separated by `---` characters. |

The playback speed can be customized with the `--speed` flag, which must be one of `0.5x`, `1x`, `2x`, `4x`, or `8x`.

```
tsh play --speed=8x UUID
```

Another way to speed up playback is to skip idle time in the recording with the `--skip-idle-time` flag. When enabled, tsh will respect the configured playback speed during active sections of the recording, but it will skip over larger periods of inactivity.

## tsh configuration files

You can use a configuration file to control the behavior of `tsh`. The scope of the configuration file depends on its location:

- `/etc/tsh.yaml` is the default location for global, shared configuration settings. You can override the location with the `TELEPORT_GLOBAL_TSH_CONFIG` environment variable.
- `$TELEPORT_HOME/config/config.yaml` is the default location for user-specific configuration settings. The default location for `TELEPORT_HOME` is `~/.tsh`.

`tsh` merges the settings from both configuration file locations, with the user configuration settings taking precedence.

### Extra proxy headers

The `tsh` configuration file enables you to specify HTTP headers to be included in requests to Teleport Proxy Servers with addresses matching the `proxy` field.

```
add_headers:
  - proxy: "*.example.com" # matching proxies will have headers included
    headers: # headers are pairs to include in the http headers
      foo: bar # Key/Value to be included in the http request

```

For example, adding HTTP headers can be useful if an intermediate HTTP proxy is in place that requires setting an authentication token:

```
add_headers:
  - proxy: "*.infra.corp.xyz"
    headers:
      "Authorization": "Bearer tokentokentoken"

```

### Aliases

You can configure `tsh` to define aliases, custom commands and command-specific flag defaults. Using aliases, you can run frequently used `tsh` commands more easily.

Aliases allow you to define custom commands or change the default flag values for existing commands using the following syntax in `tsh` configuration files:

```
aliases:
    "<alias>": "<command>"

```

The `<alias>` can only be a top-level subcommand. In other words, you can define a `tsh mycommand` alias but not `tsh my command`.

New command `tsh l`:

```
aliases:
    "l": "tsh login --auth=okta"

```

Make `tsh status` use JSON as a default format:

```
aliases:
    "status": "tsh status --format=json"

```

The alias can use an arbitrary number of arguments. If an argument variable `$N` is referenced, `tsh` will check that at least `N+1` arguments were given to the alias invocation. All arguments that were given but not referenced in the alias definition will be appended at the end.

Define a custom command using `bash`. The `$0` and `$1` variables will be substituted with command arguments.

```
aliases:
    "connect": "bash -c 'tsh login $0 && tsh ssh $1'"

```

Define a custom login command where first argument specifies `--auth` option.

```
aliases:
    "ap": "tsh login --auth=$0 --proxy=teleport.example.com"

```

Given the configuration:

```
aliases:
    "example": "bash -c 'echo first=$0 $0-$1 $3'"

```

`tsh example 0 1 unused-2 3 unused-4` will expand to `bash -c 'echo first=0 0-1 3 unused-2 unused-4'`.

An alias definition can also reference the `$TSH` variable. If you use the `$TSH` variable in an alias, `tsh` expands the variable to the absolute path of the current `tsh` executable. This behavior can be useful if there are multiple `tsh` versions installed, or the version you're currently using is not in the `PATH`:

```
aliases:
    "status": "$TSH status --format=json"

```

To troubleshoot aliases, set the `TELEPORT_DEBUG=1` environment variable. This will cause detailed logs to be printed to standard error:

```
$ TELEPORT_DEBUG=1 tsh status
DEBU [TSH]       Self re-exec command: tsh [status --format=json]. tsh/aliases.go:203
...
```

### Proxy templates

With proxy templates, `tsh` dynamically determines the address of the Teleport Proxy Service to connect to based on the address of the destination host in your `tsh ssh` or `tsh proxy ssh` command:

```
proxy_templates:

# Regular expression that the host server address `%h:%p` is matched against.
# The "replace rules" below can reference capturing groups from this regular
# expression (`$1`, `$2`, etc.).
- template: '^(\w+)\.(\w+):([0-9]+)$' # <nodename>.<clustername>:<port>

  # Optional web proxy address to use for proxy jump (`--jumphost`, `-J`).
  #
  # Proxy Jump can be used to reduce latency in regionally distributed trusted
  # clusters by connecting to a leaf node through the leaf proxy instead of the
  # root proxy.
  proxy: "$2.eu.example.com:443"

  # Optional cluster name to connect to (`--cluster`).
  #
  # Cluster can be used to connect to leaf nodes from the root proxy without
  # first logging in to the leaf cluster. This may be useful in cases where
  # proxy jump is not applicable, such as when the leaf clusters do not have
  # their own public proxies.
  cluster: "$2"

  # Optional host server address to connect to (`%h:%p`).
  #
  # Port defaults to 3022 if not explicitly provided with `--port`.
  # If provided, it will take precedence over host resolution via
  # query or search.
  host: "$1:$3"

  # Optional predicate expression to resolve the target host with.
  #
  # Query by predicate expression similar to tsh ls --query.
  # Has priority over search but will be ignored if a host is provided.
  query: "labels.env == $1"

  # Optional fuzzy search terms to resolve the target host with.
  #
  # Search by a list of comma separated keywords similar to tsh ls --search.
  # Only applied if host and search are not provided.
  search: "$1"

# Multiple templates can be provided. They are evaluated in order and the first
# match takes effect.
- template: ...

```

In the configuration above, `query` accepts an predicate expression. This has priority over search but will be ignored if a host is provided. See the [predicate language documentation](https://goteleport.com/docs/reference/access-controls/predicate-language.md#resource-filtering) for predicate expression examples.

`tsh -J {{proxy}} ssh` and `tsh -J {{proxy}} proxy ssh` will attempt to match the host server address `%h:%p` with the configured templates. For each replace rule set, the corresponding cli value will be set.

If leaf certificates are required to connect to the node, `tsh` automatically retrieves leaf certificates from the root cluster:

```
$ tsh ssh -J {{proxy}} node1.leaf1
becomes
$ tsh ssh -J leaf1.eu.example.com:443 --cluster leaf1 node1
```

If there is no template matched, an error is returned.

```
$ tsh ssh -J {{proxy}} node1.none.example.com
ERROR: proxy jump contains {{proxy}} variable but did not match any of the templates in tsh config
```

If you don't explicitly provide the proxy variable `-J {{proxy}}`, `tsh` still attempts to match a template, but won't fail if there isn't a match. Additionally, `tsh` won't replace the `proxy` value if it's explicitly set by the client:

```
$ tsh ssh -J leaf2.us.example.com:443 node1.leaf2
becomes
$ tsh ssh -J leaf2.us.example.com:443 --cluster leaf2 node1
```

Proxy Templates can also be used with OpenSSH by setting the `ProxyCommand` in `~/.ssh/config` to use `tsh proxy ssh`.

```
Host *.example.com
    Port 3022
    ProxyCommand tsh proxy ssh -J {{proxy}} %r@%h:%p

```

As a result, you can use `tsh ssh` and `ssh` interchangeably.

```
$ tsh ssh node1.leaf1
is equivalent to
$ ssh node1.leaf1
```

## Uninstalling tsh

To remove `tsh` and associated user data see [Uninstalling Teleport](https://goteleport.com/docs/installation/uninstall-teleport.md).

## Further reading

Read the [`tsh` CLI Reference](https://goteleport.com/docs/reference/cli/tsh.md) for all `tsh` commands and their options.
