Deploying Machine ID with Bound Keypair Joining
In this guide, you will install Machine & Workload Identity's agent, tbot
, on
an arbitrary host using Bound Keypair Joining. This host could be a bare-metal
machine, a VM, a container, or any other host - the only requirement is that the
host has persistent storage.
Bound Keypair Joining is an improved alternative to secret-based join methods and can function as a drop-in replacement. It is more secure than static token joining, and is more flexible than ephemeral token joining with renewable certificates: when its certificates expire, it can perform an automated recovery to ensure the bot can rejoin even after an extended outage.
Note that platform-specific join methods may be available that are better suited to your environment; refer to the deployment guides for a full list of options.
How it works
With Bound Keypair Joining, Machine & Workload Identity bots generate a unique keypair which is persistently stored in their internal data directory. Teleport is then configured to trust this public key for future joining attempts.
Later, when the bot attempts to join the cluster, Teleport issues it a challenge that can only be completed using its private key. The bot returns the solved challenge, attesting to its own identity, and is conditionally allowed to join the cluster. This process is repeated for every join attempt, but if the bot has been offline long enough for its certificates to expire, it is additionally forced to perform an automatic recovery to join again.
As self attestation is inherently less secure than the external verification that would be provided by a cloud provider like AWS or a dedicated TPM, Bound Keypair Joining enforces a number of additional checks to prevent abuse, including:
- Join state verification to ensure the keypair cannot be usefully shared or duplicated
- Certificate generation counter checks to ensure regular bot certificates cannot be usefully shared or duplicated
- Configurable limits on how often - if at all - bots may be allowed to automatically recover using this keypair
An important benefit to Bound Keypair Joining is that all joining restrictions can be reconfigured at any time, and bots that expire or go offline can be recovered by making a server-side exemption without any client-side intervention.
Refer to the admin guide for further details on how this join method works.
Prerequisites
- A running Teleport cluster version 18.1.0 or above.
- The
tsh
andtctl
clients. - To check that you can connect to your Teleport cluster, sign in with
tsh login
, then verify that you can runtctl
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 protected] to your Teleport username:If you can connect to the cluster and run thetsh login --proxy=teleport.example.com --user=[email protected]tctl statusCluster teleport.example.com
Version 18.0.2
CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
tctl status
command, you can use your current credentials to run subsequenttctl
commands from your workstation. If you host your own Teleport cluster, you can also runtctl
commands on the computer that hosts the Teleport Auth Service for full permissions. - This guide assumes the bot host has mutable persistent storage for internal bot data. While it is possible to use Bound Keypair Joining can on immutable hosts (like CI runs), doing so will reduce security guarantees; see the admin guide for further information.
Step 1/5. Install tbot
This step is completed on the bot host.
First, tbot
needs to be installed on the host that you wish to use Machine ID
on.
Download and install the appropriate Teleport package for your platform:
To install a Teleport Agent on your Linux server:
The easiest installation method, for Teleport versions 17.3 and above, is the cluster install script. It will use the best version, edition, and installation mode for your cluster.
-
Assign teleport.example.com:443 to your Teleport cluster hostname and port, but not the scheme (https://).
-
Run your cluster's install script:
curl "https://teleport.example.com:443/scripts/install.sh" | sudo bash
On older Teleport versions:
-
Assign edition to one of the following, depending on your Teleport edition:
Edition Value Teleport Enterprise Cloud cloud
Teleport Enterprise (Self-Hosted) enterprise
Teleport Community Edition oss
-
Get the version of Teleport to install. If you have automatic agent updates enabled in your cluster, query the latest Teleport version that is compatible with the updater:
TELEPORT_DOMAIN=example.teleport.com:443TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/default/version | sed 's/v//')"Otherwise, get the version of your Teleport cluster:
TELEPORT_DOMAIN=example.teleport.com:443TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/ping | jq -r '.server_version')" -
Install Teleport on your Linux server:
curl https://cdn.teleport.dev/install.sh | bash -s ${TELEPORT_VERSION} editionThe installation script detects the package manager on your Linux server and uses it to install Teleport binaries. To customize your installation, learn about the Teleport package repositories in the installation guide.
Step 2/5. Create a Bot
This step is completed on your local machine.
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 join token
This step is completed on your local machine.
In this guide, we'll demonstrate joining a bot using a registration secret: this is a one-time use secret the bot can provide to Teleport to authenticate its first join. Once authenticated, the bot automatically generates a keypair and registers its public key with Teleport for use in all future join attempts.
Create token-example.yaml
:
kind: token
version: v2
metadata:
# This name will be used in tbot's `onboarding.token` field.
name: example
spec:
roles: [Bot]
# bot_name should match the name of the bot created earlier in this guide.
bot_name: example
join_method: bound_keypair
bound_keypair:
recovery:
mode: standard
limit: 1
Replace example
in spec.bot_name
with the name of the bot you created in the
second step.
For this example, we don't need to set any additional options for the bound keypair token. We've allowed a single recovery attempt, which will be used to allow the bot's initial join, and Teleport will generate a registration secret automatically when the token is created as we have not preregistered a public key to use.
This example makes use of registration secrets to authenticate the initial join. If desired, it is also possible to generate a key on the bot host first and register it with Teleport out-of-band, avoiding the need to copy secrets between hosts.
To learn more about preregistering public keys and Bound Keypair Joining's other onboarding and recovery options, refer to the Reference and Admin Guide.
Use tctl
to apply this file:
tctl create -f token-example.yaml
Next, retrieve the generated registration secret, which will be needed for the next step:
tctl get token/example --format=json | jq -r '.[0].status.bound_keypair.registration_secret'
This assumes jq
is installed. If not, run tctl get token/example
and inspect
the .status.bound_keypair.registration_secret
field.
Step 4/5. Configure tbot
This step is completed on the bot host.
Create /etc/tbot.yaml
:
version: v2
proxy_server: example.teleport.sh:443
onboarding:
join_method: bound_keypair
token: example
bound_keypair:
registration_secret: SECRET
storage:
type: directory
path: /var/lib/teleport/bot
# outputs will be filled in during the completion of an access guide.
outputs: []
Replace the following:
example.teleport.sh:443
with the address of your Teleport Proxy.example
with the name of the token created in the previous step, if you changed it fromexample
.SECRET
with the registration secret retrieved in the previous step.
Now, you must decide if you want to run tbot
as a daemon or in one-shot mode.
In daemon mode, tbot
runs continually, renewing the short-lived credentials
for the configured outputs on a fixed interval. This is often combined with a
service manager (such as systemd) in order to run tbot
in the background.
This is the default behaviour of tbot
.
In one-shot mode, tbot
generates short-lived credentials and then exits. This
is useful when combining tbot
with scripting (such as in CI/CD) as it allows
further steps to be dependent on tbot
having succeeded. It is important to
note that the credentials will expire if not renewed and to ensure that the
TTL for the certificates is long enough to cover the length of the CI/CD job.
Configuring tbot
as a daemon
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. 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 \ --anonymous-telemetry
Ensure that you replace:
teleport
with the name of Linux user you wish to runtbot
as./etc/tbot.yaml
with the path to the configuration file you have created.
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-reloadsudo systemctl enable tbotsudo systemctl start tbot
Check the service has started successfully:
sudo systemctl status tbot
Configuring tbot
for one-shot mode
To use tbot
in one-shot mode, modify /etc/tbot.yaml
to add oneshot: true
:
version: v2
oneshot: true
auth_server: ...
Now, you should test your tbot
configuration. When started, several log
messages will be emitted before it exits with status 0:
export TELEPORT_ANONYMOUS_TELEMETRY=1tbot start -c /etc/tbot.yaml
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.
Step 5/5. Configure outputs
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 to configure an output that meets your access needs.
Next steps
- Read the Bound Keypair Joining Reference and Admin Guide for more details about the join method and the available configuration options.
- Follow the access guides to finish configuring
tbot
for your environment. - Read the configuration reference to explore all the available configuration options.
- More information about
TELEPORT_ANONYMOUS_TELEMETRY
.