Using Machine ID with GitLab CI
Machine ID for GitLab is available starting from Teleport
In this guide, you will use Teleport Machine ID to allow a GitLab pipeline to securely connect to a Teleport SSH node without the need for long-lived secrets.
Machine ID for GitLab works with GitLab's cloud-hosted option and with self-hosted GitLab installations. The minimum supported GitLab version is 15.7.
This mitigates the risk of long-lived secrets such as passwords or SSH private keys being exfiltrated from your GitLab organization and provides many of the other benefits of Teleport such as auditing and finely-grained access control.
A running Teleport cluster. For details on how to set this up, see one of our Getting Started guides.
tctladmin tool and
tshclient tool version >= 13.0.3.tctl version
Teleport v13.0.3 go1.20tsh version
Teleport v13.0.3 go1.20
See Installation for details.
A running Teleport Enterprise cluster. For details on how to set this up, see our Enterprise Getting Started guide.
tctladmin tool and
tshclient tool version >= 13.0.3, which you can download by visiting your Teleport account.tctl version
Teleport Enterprise v13.0.3 go1.20tsh version
Teleport v13.0.3 go1.20
Please use the latest version of Teleport Enterprise documentation.
- Make sure you can connect to Teleport. Log in to your cluster using
tsh, then use
tctlremotely:tsh login --proxy=teleport.example.com [email protected]tctl status
CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
You can run subsequent
tctlcommands in this guide on your local machine.
For full privileges, you can also run
tctlcommands on your Auth Service host.
- A running instance of the Teleport SSH Service registered with your Teleport
cluster. For instructions on setting this up, see the Getting Started
Guide. The SSH node must include a user
you want to grant access to. In this guide, we will call the SSH node
my-nodeand the user
ci-user. Replace these with values appropriate to your setup.
- A GitLab project to connect to Teleport. This can either be on GitLab's cloud-hosted offering (gitlab.com) or on a self-hosted GitLab instance. When using a self-hosted GitLab instance, your Teleport Auth Server must be able to connect to your GitLab instance and your GitLab instance must be configured with a valid TLS certificate.
Step 1/3. Create a join token
To allow GitLab CI to authenticate to your Teleport cluster, you'll first need to create a join token. A GitLab join token contains allow rules that describe which pipelines can use that token in order to join the Teleport cluster. A rule can contain multiple fields, and any pipeline that matches all of the fields within a single rule is granted access.
In this example, you will create a token with a rule that grants access to any
GitLab CI job within a specific GitLab project. Determine the fully qualified
path of your GitLab project. This will include your username (or group) and the
name of your project, e.g
Create a file named
gitlab-token.yaml. Ensure you substitute any values as
suggested by the comments in this example:
kind: token version: v2 metadata: name: gitlab-demo spec: # The Bot role indicates that this token grants access to a bot user, rather # than allowing a node to join. This role is built in to Teleport. roles: [Bot] join_method: gitlab # The bot_name indicates which bot user this token grants access to. This # should match the name of the bot that you create in step 2. bot_name: gitlab-demo gitlab: # domain should be the domain of your GitLab instance. If you are using # GitLab's cloud hosted offering, omit this field entirely. domain: gitlab.example.com # allow specifies rules that control which GitLab tokens will be accepted # by Teleport. Tokens not matching any allow rule will be denied. allow: # project_path should be the fully qualified path of your GitLab # project that you determined earlier. This will grant access to any # GitLab CI run in that project. - project_path: my-user/my-project
You can find a full list of the token configuration options for GitLab joining on the GitLab CI reference page.
Apply this to your Teleport cluster using
tctl create -f gitlab-token.yaml
Step 2/3. Create a Machine ID bot
With the join token created, the next step is to create the Machine ID bot that the token will grant access to.
In this example, the bot is given the preset
access role. In a production
environment, the principle of least privilege should be applied and you should
create a role that grants the bot access to the precise resources that will be
needed in your CI/CD pipeline.
From your workstation enter the following command, replacing the
value with a Linux user on the host that you want your GitHub Actions flow to
be able to connect to:
tctl bots add gitlab-demo --roles=access --token=gitlab-demo --logins=ci-user
Step 3/3. Configure a GitLab Pipeline
With the bot and join token created, you can now create a GitLab pipeline that uses these to access a node in your cluster.
Create a file called
.gitlab-ci.yml in the root of your repository. Replace:
teleport.example.comwith the name of your Teleport cluster
teleport.example.com:443with the public address and port of your Teleport Proxy
ci-userwith the user and host you wish to connect to
stages: - deploy deploy-job: stage: deploy id_tokens: # See https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html # for further explanation of the id_tokens configuration. TBOT_GITLAB_JWT: # An environment variable named TBOT_GITLAB_JWT must exist and contain # an ID token with an audience that matches your Teleport cluster's name. aud: teleport.example.com script: - cd /tmp - 'curl -O https://cdn.teleport.dev/teleport-v13.0.3-linux-amd64-bin.tar.gz' - tar -xvf teleport-v13.0.3-linux-amd64-bin.tar.gz - sudo ./teleport/install - 'tbot start --token=gitlab-demo --destination-dir=/tmp/tbot-user --data-dir=/tmp/tbot-data --auth-server=teleport.example.com:443 --join-method=gitlab --oneshot' - 'tsh -i /tmp/tbot-user/identity --proxy teleport.example.com:443 ssh [email protected] "echo $CI_JOB_ID >> ~/gitlab_run_log"'
Commit and push this to the repository. Check your GitLab CI status, and examine
the log results from the commit for failure. If the job has succeeded, you
should see a file in the home directory of
that includes the ID of the CI run.
For more information about GitLab itself, read their documentation.
For more information about GitLab joining, read the GitLab CI reference page.