diff --git a/docs/config.json b/docs/config.json index 5e66d51461f06..9a8cc5fd985b6 100644 --- a/docs/config.json +++ b/docs/config.json @@ -1120,6 +1120,10 @@ "title": "GitHub Actions & Kubernetes", "slug": "/machine-id/guides/github-actions-kubernetes/" }, + { + "title": "GitLab CI", + "slug": "/machine-id/guides/gitlab/" + }, { "title": "Jenkins", "slug": "/machine-id/guides/jenkins/" diff --git a/docs/pages/includes/machine-id/guides.mdx b/docs/pages/includes/machine-id/guides.mdx index 494bd86247d08..933d1c85f4eb6 100644 --- a/docs/pages/includes/machine-id/guides.mdx +++ b/docs/pages/includes/machine-id/guides.mdx @@ -6,3 +6,4 @@ - [Using Machine ID with CircleCI](../../machine-id/guides/circleci.mdx): How to use Machine ID to to access Teleport resources from CircleCI. - [Using Machine ID with Jenkins](../../machine-id/guides/jenkins.mdx): How to integrate Machine ID with Jenkins. - [Using Machine ID with Kubernetes](../../machine-id/guides/kubernetes.mdx): How to use Machine ID to connect automated services to Kubernetes clusters. +- [Using Machine ID with GitLab CI](../../machine-id/guides/gitlab.mdx): How to use Machine ID to SSH into Teleport nodes from GitLab CI. diff --git a/docs/pages/machine-id/guides/github-actions.mdx b/docs/pages/machine-id/guides/github-actions.mdx index 2449e2a9bed50..cb6dcd353b61f 100644 --- a/docs/pages/machine-id/guides/github-actions.mdx +++ b/docs/pages/machine-id/guides/github-actions.mdx @@ -40,17 +40,17 @@ repo, however this value should be replaced with your own unique repo. ## 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. +With the join token created, the next step is to create the Machine ID bot that +the token will grant access to. -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. +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 workflow. -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: +From your workstation enter the following command, replacing the`username` +value with a Linux user on the host that you want your GitHub Actions flow to +be able to connect to: ```code $ tctl bots add github-demo --roles=access --token=github-token --logins=username diff --git a/docs/pages/machine-id/guides/gitlab.mdx b/docs/pages/machine-id/guides/gitlab.mdx new file mode 100644 index 0000000000000..3042ae2608bba --- /dev/null +++ b/docs/pages/machine-id/guides/gitlab.mdx @@ -0,0 +1,161 @@ +--- +title: Using Machine ID with GitLab CI +description: How to use Machine ID to SSH into Teleport nodes from GitLab CI +--- + +
+ Machine ID for GitLab is available starting from Teleport `v12.2`. +
+ +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. + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx!) + +(!docs/pages/includes/tctl.mdx!) + +- A running instance of the Teleport SSH Service registered with your Teleport +cluster. For instructions on setting this up, see the [Getting Started +Guide](../../server-access/introduction.mdx). The SSH node must include a user +you want to grant access to. In this guide, we will call the SSH node `my-node` +and 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 `my-user/my-project`. + +Create a file named `gitlab-token.yaml`. Ensure you substitute any values as +suggested by the comments in this example: + +```yaml +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.](../reference/gitlab.mdx#gitlab-join-token) + +Apply this to your Teleport cluster using `tctl`: + +```code +$ 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`ci-user` +value with a Linux user on the host that you want your GitHub Actions flow to +be able to connect to: + +```code +$ 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.com` with the name of your Teleport cluster +- `teleport.example.com:443` with the public address and port of your Teleport + Proxy +- `my-node` and `ci-user` with the user and host you wish to connect to + +```yaml +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-v(=teleport.version=)-linux-amd64-bin.tar.gz' + - tar -xvf teleport-v(=teleport.version=)-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 ci-user@my-node "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 `ci-user` called `gitlab_run_log` +that includes the ID of the CI run. + +## Further steps + +For more information about GitLab itself, read +[their documentation](https://docs.gitlab.com/ee/ci/). + +For more information about GitLab joining, read the +[GitLab CI reference page.](../reference/gitlab.mdx#gitlab-join-token) + +[More information about `TELEPORT_ANONYMOUS_TELEMETRY`.](../reference/telemetry.mdx) diff --git a/docs/pages/machine-id/reference.mdx b/docs/pages/machine-id/reference.mdx index 82d56d25af241..bd98d518e01d6 100644 --- a/docs/pages/machine-id/reference.mdx +++ b/docs/pages/machine-id/reference.mdx @@ -6,5 +6,6 @@ description: Configuration and CLI reference for Teleport Machine ID. - [Configuration](./reference/configuration.mdx) - [GitHub Actions](./reference/github-actions.mdx) +- [GitLab CI](./reference/gitlab.mdx) - [CLI](../reference/cli.mdx#tbot) - [Telemetry](./reference/telemetry.mdx) diff --git a/docs/pages/machine-id/reference/gitlab.mdx b/docs/pages/machine-id/reference/gitlab.mdx new file mode 100644 index 0000000000000..fef1cec223f37 --- /dev/null +++ b/docs/pages/machine-id/reference/gitlab.mdx @@ -0,0 +1,91 @@ +--- +title: GitLab CI +description: Reference for GitLab joining +--- + +This document acts a reference for GitLab CI and Machine ID. You will find +links to in-depth guides as well as a full description of the configuration +options available when using the GitLab join method. + +## Guides + +You can read step-by-step guides on using Machine ID and GitHub Actions: + +- [Using Machine ID with GitLab](../guides/gitlab.mdx): How to + use Machine ID to SSH into Teleport nodes from GitLab CI. + +## GitLab 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. + +The following constraints exist: +- `sub`: a string uniquely identifying the CI run's source. It follows the + following format: + + +```yaml +kind: token +version: v2 +metadata: + # name identifies the token. When configuring a bot or node to join using this + # token, this name should be specified. + name: gitlab-demo +spec: + # The Bot role indicates that this token grants access to a bot user, rather + # than allowing a node to join. + roles: [Bot] + # join_method for GitLab joining will always be "gitlab". + join_method: gitlab + + # bot_name specifies the name of the bot that this token will grant access to + # when it is used. + 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 is an array of rule configurations for what GitLab CI jobs should be + # allowed to join. All options configured within one allow entry + # must be satisfied for the GitLab CI run to be allowed to join. Where + # multiple allow entries are specified, any job which satisfies all of the + # options within a single entry will be allowed to join. + # + # An allow entry must include at least one of: + # - project_path + # - namespace_path + # - sub + # This ensures that GitLab CI runs in other GitLab user's projects are not + # able to access your Teleport cluster. + allow: + # project_path restricts joins to jobs that originate within the + # specified project. + - project_path: my-user/my-project + # namespace_path restricts joins to any run within project that exists + # within the specified namespace. A namespace will either be a username + # or the name of a group. + namespace_path: my-user + # pipeline_source restricts joins to jobs triggered by certain criteria, + # e.g triggered through the web interface. + pipeline_source: web + # environment restricts joins to jobs that are associated with the + # specified environment + environment: production + # ref_type restricts joins to jobs that were triggered by a specific + # type of git reference. Either `branch` or `tag`. + ref_type: branch + # ref restricts joins to jobs that were triggered by a specific git + # reference. Combine this with `ref_type` to create allow rules that + # can only be triggered by a specific branch or tag. + ref: main + # sub is a single string that concatenates the project_path, ref_type + # and ref. This can be used to restrict joins using a single string, + # whilst also describing a specific project and git ref. + # + # It is better to use the individual fields, as it is easy to mis-format + # the sub string. + sub: project_path:my-user/my-project:ref_type:branch:ref:main +``` \ No newline at end of file diff --git a/lib/gitlab/gitlab.go b/lib/gitlab/gitlab.go index 4434bced22db9..0e50be59a7bab 100644 --- a/lib/gitlab/gitlab.go +++ b/lib/gitlab/gitlab.go @@ -45,6 +45,9 @@ import ( // https://gitlab.com/.well-known/openid-configuration // For GitLab self-hosted servers, this will be at // https://$HOSTNAME/.well-known/openid-configuration +// +// The minimum supported GitLab version is 15.7, as this is when ID token +// support was introduced. // IDTokenClaims is the structure of claims contained within a GitLab issued // ID token.