# Deploying tbot on Linux (TPM)

This page explains how to deploy Machine & Workload Identity's agent, `tbot`, on a Linux host, and use the secure identity of the onboard TPM 2.0 chip for authenticating with the Teleport cluster.

The `tpm` join method requires a valid Teleport Enterprise license to be installed on the cluster's Auth Service.

## How it works

The `tpm` join method is a secure way for Bots and Agents to authenticate with the Teleport Auth Service without using any shared secrets. Instead of using a shared secret, the unique identity of the host's Trusted Platform Module (TPM) and public key cryptography is used to authenticate the host.

In environments where there is no other form of identity available to machines, e.g. on-prem, this is the most secure method for joining. It avoids the need to distribute a shared secret as is needed for the `token` join method.

A Trusted Platform Module (TPM) is a secure, physical cryptoprocessor that is installed on a host. TPMs can store cryptographic material and perform a number of cryptographic operations, without exposing the cryptographic material to the operating system. Each TPM has a unique key pair burned-in known as the Endorsement Key (EK). This key does not change, even if the host operating system is reinstalled.

Some TPMs also contain an X.509 certificate for this key pair that is signed by the manufacturer's CA. This is known as the EK Certificate (EKCert). This certificate can be used by the TPM to prove to a third-party (who trusts the manufacturer's CA) that the TPM is genuine and abides by the TPM specification.

When using the `tpm` join method, you must first query the TPM's public key and then create a join token that explicitly allows this public key. To list information about the detected TPM, run the `teleport tpm identify` command.

If you have a large number of hosts, it may make sense to use automation tooling such as Ansible to query the TPMs across your fleet and then generate join tokens.

---

WARNING

The `tpm` join method is currently not compatible with FIPS.

---

## 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
     ```

* 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  19.0.0-dev
  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.
* A Linux host that you wish to install `tbot` onto with a TPM2.0 installed.
* A Linux user on that host that you wish `tbot` to run as. In the guide, we will use `teleport` for this.

## Step 1/5. Install `tbot`

**This step is completed on the Linux host.**

First, `tbot` needs to be installed on the VM that you wish to use Machine & Workload Identity on.

Download the appropriate Teleport package for your platform:

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
   ```

### Granting `tbot` access to the TPM device

If the user that will run `tbot` is not `root`, you will also need to configure Linux to allow the user to access the TPM device.

The simplest way to solve this is to check if your distro ships with the `tss` group and assign it the user. If that is not possible, or you are looking for a different solution, we recommend creating udev rules similar to the ones shipped by the [TPM2 Software Stack](https://github.com/tpm2-software/tpm2-tss/blob/ede63dd1ac1f0a46029d457304edcac2162bfab8/dist/tpm-udev.rules#l4).

## Step 2/5. Create a Bot

Next, you need to create a Bot. A Bot is a Teleport identity for a machine or group of machines. Like users, bots have a set of roles and traits which define what they can access.

Create `bot.yaml`:

```
kind: bot
version: v1
metadata:
  # name is a unique identifier for the Bot in the cluster.
  name: example
spec:
  # roles is a list of roles to grant to the Bot. Don't worry if you don't know
  # what roles you need to specify here, the Access Guides will walk you through
  # creating and assigning roles to the already created Bot.
  roles: []

```

Make sure you replace `example` with a unique, descriptive name for your Bot.

Use `tctl` to apply this file:

```
$ tctl create bot.yaml
```

## Step 3/5. Create a `tpm` join token

With the Bot created, we now need to create a token. The token will be used by `tbot` to authenticate as the Bot to the Teleport cluster.

### Determining the EKPub Hash or EKCert Serial for your TPM

First, you need to determine the characteristics of the TPM on the host that you wish to install `tbot` on. These characteristics will then be used within the allow rules of the join token to grant access to this specific host.

On the machine, run `tbot tpm identify`:

```
$ tbot tpm identify
TPM Information
EKPub Hash: 6c5aada1c5abee6d869369a0example2fd2beb41c850d3f0227f029c4fffc4ba
EKCert Detected: true
EKCert Serial: 5e:cd:5f:8e
```

Take the long hexadecimal string after `EKPub Hash` and assign it to ek-public-hash. This uniquely identifies this TPM and will be used in the join token.

### Obtaining the manufacturer CA

If in the previous step, `EKCert Detected` was `false`, then you can disregard this section.

If in the previous step, `EKCert Detected` was `true`, then it is recommended to obtain the manufacturer's CA certificate. This will allow the TPM to be validated as legitimately manufactured as part of the join process.

Instructions for obtaining the EKCert CA will vary from TPM to TPM. Consult your TPM's documentation for more information or contact your supplier.

### Creating the join token

Create a file named `bot-token.yaml`:

```
kind: token
version: v2
metadata:
  # name identifies the token. Try to ensure that this is descriptive.
  name: my-bot-token
spec:
  # For MWI joining via TPM, roles will always be "Bot" and join_method will
  # always be "tpm".
  roles: [Bot]
  join_method: tpm

  # bot_name specifies the name of the bot that this token will grant access to
  # when it is used.
  bot_name: example

  # tpm specifies the TPM join method specific configuration for this token.
  tpm:
    # ekcert_allowed_cas is a list of CA certificates that will be used to
    # validate TPM EKCerts. These should be PEM wrapped.
    #
    # When specified, joining TPMs must present an EKCert signed by one of the
    # specified CAs. TPMs that do not present an EKCert will be not permitted to
    # join.
    ekcert_allowed_cas:
      - |
        -----BEGIN CERTIFICATE-----
        ... CA Certificate Data ...
        -----END CERTIFICATE-----
    # allow is a list of Rules, the presented TPM must match one allow rule to
    # be permitted to join using this token.
    allow:
        # description is a human-readable description of the rule. It has no
        # bearing on whether a TPM is allowed to join, but can be used to
        # associate a rule with a specific host (e.g. the asset tag of the server
        # in which the TPM resides).
      - description: "example-server-100"
        # ek_public_hash is the SHA256 hash of the EKPub marshaled in PKIX format
        # and encoded in hexadecimal. This value will also be checked when a TPM
        # has submitted an EKCert, and the public key in the EKCert will be used
        # for this check.
        ek_public_hash: ek-public-hash

```

If your TPM includes an EKCert and you have obtained the manufacturer's CA, replace the `ekcert_allowed_cas` section with the PEM wrapped CA certificate. Otherwise, remove this section.

If you have multiple hosts that you wish to authenticate as the same Bot, you can add additional rules to the `allow` list, one for each host.

Apply this to your Teleport cluster using `tctl`:

```
$ tctl create -f bot-token.yaml
```

## Step 4/5. Configure `tbot`

Create `/etc/tbot.yaml`:

```
version: v2
proxy_server: example.teleport.sh:443
onboarding:
  join_method: tpm
  token: my-bot-token
storage:
  type: directory
  path: /var/lib/teleport/bot
# services will be filled in during the completion of an access guide.
services: []

```

Replace:

- `example.teleport.sh:443` with the address of your Teleport Proxy.

### Prepare the storage directory

The `tbot` service requires a way to store its state, such as internal credentials, across restarts. This is known as the storage destination.

For this example, we will use the directory `/var/lib/teleport/bot`.

As this directory will store the bots sensitive credentials, it is important to protect it. To do this, you will configure the directory to only be accessible to the Linux user which `tbot` will run as.

Execute the following, replacing `teleport` with the Linux user that you will run `tbot` as:

```
Make the bot directory and assign ownership to teleport user
$ sudo mkdir -p /var/lib/teleport/bot
$ sudo chown teleport:teleport /var/lib/teleport/bot
```

### Create a systemd service

By default, `tbot` will run in daemon mode. However, this must then be configured as a service within the service manager on the Linux host. The service manager will start `tbot` on boot and ensure it is restarted if it fails.

**If tbot was installed using the Teleport install script or `teleport-update` command, the `tbot` systemd service is automatically created for you.**

After `tbot.yaml` is created, enable and start the service:

```
$ sudo systemctl enable tbot --now
```

Check the service has started successfully:

```
$ sudo systemctl status tbot
```

Service properties like `User` and `Group` may be configured using `systemctl edit tbot`.

**If tbot was installed manually, service configuration will need to be performed manually as well.**

For this guide, systemd will be demonstrated but `tbot` should be compatible with all common alternatives.

Use `tbot install systemd` to generate a systemd service file:

```
$ sudo tbot install systemd \
   --write \
   --config /etc/tbot.yaml \
   --user teleport \
   --group teleport \
   --pid-file /run/tbot.pid \
   --anonymous-telemetry
```

Ensure that you replace:

- `teleport` with the name of Linux user you wish to run `tbot` as.
- `/etc/tbot.yaml` with the path to the configuration file you have created.
- `/run/tbot.pid` with a path that the user configured for `tbot` has write access to. By default, `tbot` writes its PID file to `/run/tbot.pid`.

You can omit `--write` to print the systemd service file to the console instead of writing it to disk.

`--anonymous-telemetry` enables the submission of anonymous usage telemetry. This helps us shape the future development of `tbot`. You can disable this by omitting this.

Next, enable the service so that it will start on boot and then start the service:

```
$ sudo systemctl daemon-reload
$ sudo systemctl enable tbot --now
```

Check the service has started successfully:

```
$ sudo systemctl status tbot
```

## Step 5/5. Configure services

You have now prepared the base configuration for `tbot`. At this point, it identifies itself to the Teleport cluster and renews its own credentials but does not output any credentials for other applications to use.

Follow one of the [access guides](https://goteleport.com/docs/machine-workload-identity/access-guides.md) to configure a service that meets your access needs.

## Next steps

- Follow the [access guides](https://goteleport.com/docs/machine-workload-identity/access-guides.md) to finish configuring `tbot` for your environment.
- Read the [TPM joining reference](https://goteleport.com/docs/reference/deployment/join-methods.md#trusted-platform-module-tpm) to learn more about `tpm` joining.
- Read the [configuration reference](https://goteleport.com/docs/reference/machine-workload-identity/configuration.md) to explore all the available configuration options.
- [More information about `TELEPORT_ANONYMOUS_TELEMETRY`.](https://goteleport.com/docs/reference/machine-workload-identity/telemetry.md)
