Fork me on GitHub

Teleport

Using Machine ID With GitHub Actions

Improve

Machine ID for GitHub Actions is available starting from Teleport v11.0.

GitHub Actions is a popular CI/CD platform that works as a part of the larger GitHub ecosystem. Teleport, with the help of Machine ID, allows for GitHub Actions to securely interact with Teleport protected resources without the need for long lived credentials. By ensuring that rotated Machine ID credentials are additionally limited by RBAC, GitHub Actions with Teleport can be applied as both a viable and secure solution whenever a CI/CD platform is needed.

Teleport supports secure joining on both GitHub-hosted and self-hosted GitHub Actions runners as well as GitHub Enterprise Server.

Prerequisites

  • A running Teleport cluster. For details on how to set this up, see one of our Getting Started guides.

  • The tctl admin tool and tsh client tool version >= 12.1.1.

    tctl version

    Teleport v12.1.1 go1.19

    tsh version

    Teleport v12.1.1 go1.19

    See Installation for details.

  • A running Teleport Enterprise cluster. For details on how to set this up, see our Enterprise Getting Started guide.

  • The Enterprise tctl admin tool and tsh client tool version >= 12.1.1, which you can download by visiting the customer portal.

    tctl version

    Teleport Enterprise v12.1.1 go1.19

    tsh version

    Teleport v12.1.1 go1.19

Cloud is not available for Teleport v.
Please use the latest version of Teleport Enterprise documentation.

To connect to Teleport, log in to your cluster using tsh, then use tctl remotely:

tsh login --proxy=teleport.example.com [email protected]
tctl status

Cluster teleport.example.com

Version 12.1.1

CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

You can run subsequent tctl commands in this guide on your local machine.

For full privileges, you can also run tctl commands on your Auth Service host.

To connect to Teleport, log in to your cluster using tsh, then use tctl remotely:

tsh login --proxy=myinstance.teleport.sh [email protected]
tctl status

Cluster myinstance.teleport.sh

Version 12.1.2

CA pin sha256:sha-hash-here

You must run subsequent tctl commands in this guide on your local machine.

  • A node that is a part of the Teleport cluster with Server Access.
  • Your user should have the privileges to create token resources.
  • A GitHub repository with GitHub Actions enabled. This guide uses the example gravitational/example repo, however this value should be replaced with your own unique repo.

Step 1/3. Create a join token for GitHub Actions

In order to allow your GitHub Actions 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 Server decides whether or not to allow a bot or node to join.

To create a token, we can write the resource's YAML to a file on disk, and then use tctl to apply it.

Create a file named tokenconfig.yaml and insert the following contents:

kind: token
version: v2
metadata:
  name: github-token
  expires: "2100-01-01T00:00:00Z"
spec:
  roles: [Bot]
  join_method: github
  bot_name: github-demo
  github:
    allow:
      - repository: gravitational/example

From Teleport 11.1.4, users with Teleport Enterprise are able to permit workflows within GitHub Enterprise Server instances to authenticate using the GitHub join method.

This is configured by an additional enterprise_server_host field in the Token resource. This should be set to the host of your GHES instance.

kind: token
version: v2
metadata:
  name: github-token
  expires: "2100-01-01T00:00:00Z"
spec:
  roles: [Bot]
  join_method: github
  bot_name: github-demo
  github:
    enterprise_server_host: your.ghes.instance.example.com
    allow:
      - repository: gravitational/example

Let's go over the token resource YAML'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.
  • metadata.expires defines the date that the join token will expire. This example is set to the year 2100.
  • 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 ID bot.
  • spec.join_method defines the join method the token is applicable for. Since this guide only focuses on GitHub Actions, we will set this to to github.
  • spec.github.allow is used to set rules for what GitHub Actions will be able to authenticate by using the token. In this example, the gravitational/example repository is used, and this example repository should be replaced with your own repo.

You can find a full list of the token configuration options for GitHub Actions joining on the GitHub Actions reference page.

Once the resource file has been written, create the token with tctl:

tctl create -f tokenconfig.yaml

Check that token github-token has been created with the following command:

tctl tokens ls

Token Type Labels Expiry Time (UTC)

----------- ---- ------ ----------------------------------------------

github-token Bot 01 Jan 00 00:00 UTC (2562047h47m16.854775807s)

Step 2/3. Create your Machine ID bot

With the join token for GitHub Actions created, the next step is to create the Machine ID bot, and ensure that it is configured to use the newly created token.

The Machine ID bot created in this example will be used to access a specific node on the cluster via tsh ssh, and will therefore require a role that can access the cluster as needed. This example configuration will apply the access role, however care should be taken to either create or apply a role according to the principle of least privilege in production environments. Additionally, it should have explicit access to the cluster using a username created specifically for the bot user alone.

Enter the following command from your workstation with tsh access, replacing the username value with a Linux user on the host that you want your GitHub Actions flow to be able to connect to:

tctl bots add github-demo --roles=access --token=github-token --logins=username

Step 3/3. Configure GitHub Actions

Now that the bot has been successfully created, GitHub Actions can authenticate with the Teleport cluster using their GitHub-provided identity.

In the GitHub workflows directory of your repo (.github/workflows/) create a new workflow YAML file, in this case actionstest.yml, that will reflect the action you'd like to configure. This guide will create an action that will both list nodes within the cluster using tsh ls, as well as write the commit SHA that triggered the workflow to a file on a node. To create this configuration, use the following YAML file:

# This is a basic workflow to help you get started.
# It will take the following action whenever a push is made to the "main" branch.
on:
  push:
    branches:
      - main
jobs:
  demo:
    permissions:
      # The "id-token: write" permission is required or Machine ID will not be able to authenticate with the cluster.
      id-token: write
      contents: read
    # The name of the workflow, and the Linux distro to be used to perform the required steps.
    name: guide-demo
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/[email protected]
      - name: Fetch Teleport binaries
        uses: teleport-actions/[email protected]
        with:
          version: 12.1.1
      - name: Fetch credentials using Machine ID
        id: auth
        uses: teleport-actions/[email protected]
        with:
          # Use the address of the auth/proxy server for your own cluster.
          proxy: example.domain:443
          # Use the name of the join token resource you created in step 1.
          token: github-token
          # Specify the length of time that the generated credentials should be
          # valid for. This is optional and defaults to "1h"
          certificate-ttl: 1h
          # Enable the submission of anonymous usage telemetry.
          anonymous-telemetry: 1
      - name: List nodes
        # Enters a command from the cluster, in this case "tsh ls" using Machine ID credentials to list remote SSH nodes.
        run: tsh -i ${{ steps.auth.outputs.identity-file }} ls
      - name: Write file to remote
        # Enters a command from the cluster, in this case "tsh ssh" using Machine ID credentials to gain SSH access to an SSH node, and then write the commit hash to the "github_run_log" file.
        # Ensure that that `username` matches the username of a remote SSH username, and that hostname matches an SSH host name that is a part of the Teleport cluster configured for access.
        run: tsh -i ${{ steps.auth.outputs.identity-file }} ssh [email protected] "echo $GITHUB_SHA >> ~/github_run_log"

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.

From Teleport 11.1.0, the -i parameter for configuring the identity file of tsh is not necessary and -i ${{ steps.auth.outputs.identity-file }} can be omitted.

Add, commit, and push your changes to the main branch of the repository.

Navigate to the Actions tab of your GitHub repository in your web browser. Select the Workflow that has now been created and triggered by the change, and select the guide-demo job. The GitHub Actions workflow may take some time to complete, and will resemble the following once successful.

GitHub Actions

Expand the List nodes step of the action, and the output will list all nodes in the cluster, from the perspective of the Machine ID bot using the command tsh ls.

A note on security implications and risk

Once teleport-actions/auth has been used in a workflow job, all successive steps in that job will have access to the credentials which grant access to your Teleport cluster as the bot. Where possible, run as few steps as necessary after this action has been used. It may be a good idea to break your workflow up into multiple jobs in order to segregate these credentials from other code running in your CI/CD pipeline.

Most importantly, ensure that the role you assign to your GitHub Actions bot has access to only the resources in your Teleport cluster that your CI/CD needs to interact with.

Next steps

You can find out more about the teleport-action/setup and teleport-actions/auth actions on their GitHub repositories:

For more information about GitHub Actions itself, read their documentation.

More information about anonymous-telemetry.