# Deploying tbot on CircleCI

In this guide, you will configure Machine & Workload Identity's agent, `tbot`, to run within a CircleCI workflow. The bot will be configured to use the `circleci` delegated joining method to eliminate the need for long-lived secrets.

## 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 CircleCI project connected to a Git repository you can push to.

## Step 1/5. Configure CircleCI

In order to configure the rules for which CircleCI workflows will be allowed to connect to your Teleport cluster, you must determine the ID of your CircleCI organization and create a CircleCI context.

### Find your organization ID

Open CircleCI and navigate to "Organization settings" from the navbar. You should be presented with an interface titled "Overview" with a section called "Organization ID". Note this value down and substitute organization-id in configuration examples with this.

### Create a context

CircleCI has an organization-level concept called **contexts**, which allow you to configure a series of secrets that should be exposed to a workflow job. You can configure CircleCI to control which actors are allowed to trigger jobs associated with a context.

The contexts that a workflow job has been assigned are also encoded in the identity token that CircleCI creates for the job. This makes them an ideal way for Teleport to determine which CircleCI jobs should be granted access to the Teleport cluster.

In this example, you will create a CircleCI context named `teleport-access`. You will then grant this context access to your Teleport cluster.

To create the CircleCI context, open up "Organization settings" in CircleCI and navigate to "Contexts". Click "Create Context" and provide teleport-access as the name of the context you wish to create. You may substitute this value for a string that makes more sense to your organization, but ensure in future steps of this guide that you replace teleport-access with your value.

Select the context you have just created. You will now be on a page that allows you to configure the context. To determine the ID of the context to use when configuring Teleport, locate the URL of the context settings page, which should have a format similar to the following:

```
https://app.circleci.com/settings/organization/github/gravitational/contexts/00000000-0000-0000-0000-000000000000

```

In this case, the context ID is: `00000000-0000-0000-0000-000000000000`.

Note this value down and substitute context-id in configuration examples with it.

## 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 the join token for CircleCI

In order to allow your CircleCI workflow to authenticate with your Teleport cluster, you'll first need to create a join token. These tokens set out criteria by which the Auth Service decides whether or not to allow a bot or node to join.

Create a file named `bot-token.yaml`, ensuring that you replace organization-id and context-id with the values from Step 1.

```
kind: token
version: v2
metadata:
  name: example-bot
spec:
  roles: [Bot]
  join_method: circleci
  bot_name: example
  circleci:
    organization_id: organization-id
    # allow specifies the rules by which the Auth Service determines if `tbot`
    # should be allowed to join.
    allow:
    - context_id: context-id

```

Let's go over the token resource's fields in more detail:

- `metadata.name` defines the name of the token. Note that this value will need to be used in other parts of the configuration later.
- `spec.bot_name` is the name of the Machine ID bot that this token will grant access to. Note that this value will need to be used in other parts of the configuration later.
- `spec.roles` defines which roles that this token will grant access to. The value of `[Bot]` states that this token grants access to a Machine & Workload Identity bot.
- `spec.join_method` defines the join method the token is applicable for. Since this guide only focuses on CircleCI, you will set this to `circleci`.
- `spec.circleci.allow` is used to set rules for what CircleCI runs will be able to authenticate by using the token.

Apply this to your Teleport cluster using `tctl`:

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

## Step 4/5. Configure a CircleCI workflow

With the bot and join token created, you can now configure a CircleCI workflow that can connect to your Teleport cluster.

To configure `tbot`, a YAML file will be used. In this example we'll store this within the repository itself, but this could be generated or created by the CI pipeline itself.

Create `tbot.yaml` within your repository:

```
version: v2
proxy_server: example.teleport.sh:443
onboarding:
  join_method: circleci
  token: example-bot
oneshot: true
storage:
  type: memory
# services will be filled in during the completion of an access guide.
services: []

```

Replace:

- example.teleport.sh with the address of your Teleport Proxy or Auth Service. Prefer using the address of a Teleport Proxy.
- `example-bot` with the name of the token you created in the third step.

Now, the CircleCI pipeline can be defined. Before the pipeline can use `tbot`, it must be available within the environment. For this example, we'll show downloading `tbot` as part of the CI step, but in a production implementation you may wish to build a docker image that contains this binary to avoid depending on the Teleport CDN.

Open your Git repository and create a directory called `.circleci`. Then open a file called `config.yml` and insert the following configuration:

```
# See: https://circleci.com/docs/configuration-reference
version: 2.1
jobs:
  write-run-log:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      - run:
          name: "Install Teleport"
          command: |
            curl "https://example.teleport.sh:443/scripts/install.sh" | sudo bash
      - run:
          name: "Run Machine & Workload Identity"
          command: |
            export TELEPORT_ANONYMOUS_TELEMETRY=1
            tbot start -c tbot.yaml
workflows:
  write-run-log:
    jobs:
      - write-run-log:
          context:
            - teleport-access

```

Replace example.teleport.sh with the address of your Teleport Proxy Service.

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

Add, commit, and push these two configuration files to your repository.

Open CircleCI and check the status of the job, wait for it to complete and ensure that no errors are emitted.

### A note on security implications and risk

Once `tbot start` has been used in a job, all successive steps in that job will have access to the credentials that have been produced by `tbot`. Break your workflow down into multiple jobs to reduce the amount of steps that have access to these credentials.

Ensure that the role you assign to your CircleCI bot has access to only the resources in your Teleport cluster that your CI/CD needs to interact with.

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

## Further steps

- Follow the [access guides](https://goteleport.com/docs/machine-workload-identity/access-guides.md) to finish configuring `tbot` for your environment.
- Read the [configuration reference](https://goteleport.com/docs/reference/machine-workload-identity/configuration.md) to explore all the available configuration options.
- For more information about CircleCI itself, read [their documentation](https://circleci.com/docs/).
- [More information about `TELEPORT_ANONYMOUS_TELEMETRY`.](https://goteleport.com/docs/reference/machine-workload-identity/telemetry.md)
