From 039e7628333cabf096d36337719ccbbce89d9659 Mon Sep 17 00:00:00 2001
From: Tim Buckley <tim@goteleport.com>
Date: Mon, 2 Dec 2024 13:59:31 -0700
Subject: [PATCH] [v16] Machine ID: Documentation for Bitbucket Pipelines
 joining (#49386)

* Machine ID: Documentation for Bitbucket Pipelines joining

This adds guides and other documentation for the `bitbucket` join
method, which allows Machine ID bots to join from Bitbucket Pipelines
runs without shared secrets.

Follow up to #48724

* Linter appeasement (round 1)

* Add note about braces in UUIDs

* Adjust steps for v16 without new CLI features

* Linter appeasement

* Remove reference to a specific identity output type
---
 .../machine-id/deployment/bitbucket.mdx       | 187 ++++++++++++++++++
 .../machine-id/deployment/deployment.mdx      |   3 +-
 .../provision-token/bitbucket-spec.mdx        |  47 +++++
 docs/pages/reference/join-methods.mdx         |  15 +-
 4 files changed, 250 insertions(+), 2 deletions(-)
 create mode 100644 docs/pages/enroll-resources/machine-id/deployment/bitbucket.mdx
 create mode 100644 docs/pages/includes/provision-token/bitbucket-spec.mdx

diff --git a/docs/pages/enroll-resources/machine-id/deployment/bitbucket.mdx b/docs/pages/enroll-resources/machine-id/deployment/bitbucket.mdx
new file mode 100644
index 0000000000000..be3052f27727b
--- /dev/null
+++ b/docs/pages/enroll-resources/machine-id/deployment/bitbucket.mdx
@@ -0,0 +1,187 @@
+---
+title: Deploying Machine ID on Bitbucket Pipelines
+description: How to install and configure Machine ID on Bitbucket Pipelines
+---
+
+In this guide, you will configure Machine ID's agent, `tbot`, to run within a
+Bitbucket Pipelines workflow. The bot will be configured to use the `bitbucket`
+delegated joining method to eliminate the need for long-lived secrets.
+
+## How it works
+
+The `bitbucket` join method is a secure way for Machine ID bots to authenticate
+with the Teleport Auth Service without using any shared secrets. Instead, it
+makes use of an OpenID Connect token that Bitbucket Pipelines injects into the
+job environment.
+
+This token is sent to the Teleport Auth Service, and assuming it has been
+configured to trust Bitbucket's identity provider and all identity assertions
+match, the authentication attempt will succeed.
+
+## Prerequisites
+
+(!docs/pages/includes/edition-prereqs-tabs.mdx!)
+
+- (!docs/pages/includes/tctl.mdx!)
+- A Bitbucket repository you can push to.
+
+## Step 1/5. Determine Bitbucket configuration
+
+Bitbucket joining requires a number of configuration parameters that can be
+found in your repository settings. From the Bitbucket repository, navigate to
+"Repository settings", then in the sidebar under "Pipelines" select "OpenID
+Connect".
+
+From this page, note the following values:
+- Identity provider URL (<Var name="identity-provider-url" />)
+- Audience (<Var name="audience" />)
+- Workspace UUID, including the braces (<Var name="workspace-uuid" />)
+- Repository UUID, including the braces (<Var name="repository-uuid" />)
+
+## Step 2/5. Create the Machine ID bot
+
+(!docs/pages/includes/machine-id/create-a-bot.mdx!)
+
+## Step 3/5. Create the join token for Bitbucket Pipelines
+
+In order to allow your Pipelines 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 the
+`identity_provider_url`, `audience`, `workspace_uuid`, and `repository_uuid`
+with the values from Step 1.
+
+```yaml
+kind: token
+version: v2
+metadata:
+  name: example-bot
+spec:
+  roles: [Bot]
+  join_method: bitbucket
+  bot_name: example
+  bitbucket:
+    identity_provider_url: <Var name="identity-provider-url" />
+    audience: <Var name="audience" />
+    # allow specifies the rules by which the Auth Service determines if `tbot`
+    # should be allowed to join.
+    allow:
+    - workspace_uuid: <Var name="workspace-uuid" />
+      repository_uuid: <Var name="repository-uuid" />
+```
+
+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 ID bot.
+- `spec.join_method` defines the join method the token is applicable for. Since
+  this guide only focuses on Bitbucket Pipelines, you will set this to to
+  `bitbucket`.
+- `spec.bitbucket.identity_provider_url` is the identity provider URL shown in
+  the Bitbucket repository settings, under Pipelines and OpenID Connect.
+- `spec.bitbucket.audience` is the audience value shown in the Bitbucket
+  repository settings, under Pipelines and OpenID connect.
+- `spec.bitbucket.allow` is used to set rules for what Bitbucket Pipelines runs
+   will be able to authenticate by using the token.
+
+Refer to the [token reference](../../../reference/join-methods.mdx#bitbucket-pipelines-bitbucket)
+for a full list of valid fields.
+
+Apply this to your Teleport cluster using `tctl`:
+
+```code
+$ tctl create -f bot-token.yaml
+```
+
+## Step 4/5. Configure a Bitbucket Pipelines workflow
+
+With the bot and join token created, you can now configure a workflow that can
+authenticate to Teleport.
+
+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:
+
+```yaml
+version: v2
+proxy_server: example.teleport.sh:443
+onboarding:
+  join_method: bitbucket
+  token: example-bot
+oneshot: true
+storage:
+  type: memory
+# outputs will be filled in during the completion of an access guide.
+outputs: []
+```
+
+Replace:
+
+- `example.teleport.sh:443` with the address of your Teleport Proxy. If
+  connecting directly to an Auth Service, replace `proxy_server:` with
+  `auth_server:`.
+- `example-bot` with the name of the token you created in the second step
+
+Next, define a Pipelines workflow that downloads the `tbot` binary and starts
+it using the `tbot.yaml` configured above. This example workflow defines
+a "custom" pipeline that can be triggered manually from "Pipelines" or
+"Branches" views, but any type of workflow may be used:
+
+```yaml
+image: atlassian/default-image:3
+
+pipelines:
+  custom:
+    run-tbot:
+      - step:
+          oidc: true
+          script:
+            # Download and extract Teleport
+            - wget https://cdn.teleport.dev/teleport-v(=teleport.version=)-linux-amd64-bin.tar.gz
+            - tar -xvf teleport-v(=teleport.version=)-linux-amd64-bin.tar.gz
+
+            # Run `tbot` in identity mode for SSH access
+            - ./teleport/tbot start -c tbot.yaml
+```
+
+Once run, tbot will start and authenticate to Teleport. Note that at this point,
+no outputs will have been configured so it will not yet have credentials to
+connect to any resources.
+
+If you're adapting an existing workflow, note these steps:
+1. Set `oidc: true` on the step properties so that step will be issued a token
+1. Download and extract a `.tar.gz` Teleport build
+1. Run `tbot start -c tbot.yaml` with the configuration file defined above
+
+<Admonition type="warning" title="Sharing credentials between steps">
+Note that in Bitbucket Pipelines, outputs cannot be securely shared between
+steps as anything stored using `artifacts` will remain downloadable once the CI
+run has completed.
+
+Due to this limitation, all operations making use of Teleport credentials should
+be performed as part of the same step. If necessary, you can duplicate the
+script shown here to download and run `tbot` multiple times in a given run if
+credentials are needed in multiple steps.
+</Admonition>
+
+## Step 5/5. Configure outputs
+
+(!docs/pages/includes/machine-id/configure-outputs.mdx!)
+
+## Further steps
+
+- Follow the [access guides](../access-guides/access-guides.mdx) to finish configuring `tbot` for
+  your environment.
+- Read the [configuration reference](../../../reference/machine-id/configuration.mdx) to explore
+  all the available configuration options.
+- For more information about Bitbucket Pipelines itself, read
+  [their documentation](https://support.atlassian.com/bitbucket-cloud/docs/get-started-with-bitbucket-pipelines/).
+
diff --git a/docs/pages/enroll-resources/machine-id/deployment/deployment.mdx b/docs/pages/enroll-resources/machine-id/deployment/deployment.mdx
index 808fdf221f274..82880a240447a 100644
--- a/docs/pages/enroll-resources/machine-id/deployment/deployment.mdx
+++ b/docs/pages/enroll-resources/machine-id/deployment/deployment.mdx
@@ -68,9 +68,10 @@ integration and continuous deployment platform
 
 | Platform                                                                                            | Installation method                                           | Join method                        |
 |-----------------------------------------------------------------------------------------------------|---------------------------------------------------------------|------------------------------------|
+| [Bitbucket Pipelines](bitbucket.mdx)                                                   | TAR archive                                                   | Bitbucket-signed identity document |
 | [CircleCI](circleci.mdx)                                                               | TAR archive                                                   | CircleCI-signed identity document  |
 | [GitLab](gitlab.mdx)                                                                   | TAR archive                                                   | GitLab-signed identity document    |
 | [GitHub Actions](github-actions.mdx)                                                   | Teleport job available through the GitHub Actions marketplace | GitHub-signed identity document.   |
 | [Jenkins](jenkins.mdx)                                                                 | Package manager or TAR archive                                | Static join token                  |
 | [Spacelift](../../../admin-guides/infrastructure-as-code/terraform-provider/spacelift.mdx)             | Docker Image                                                  | Spacelift-signed identity document |
-| [Terraform Cloud](../../../admin-guides/infrastructure-as-code/terraform-provider/terraform-cloud.mdx) | Teleport Terraform Provider via Teleport's Terraform Registry | Terraform Cloud-signed identity document |
\ No newline at end of file
+| [Terraform Cloud](../../../admin-guides/infrastructure-as-code/terraform-provider/terraform-cloud.mdx) | Teleport Terraform Provider via Teleport's Terraform Registry | Terraform Cloud-signed identity document |
diff --git a/docs/pages/includes/provision-token/bitbucket-spec.mdx b/docs/pages/includes/provision-token/bitbucket-spec.mdx
new file mode 100644
index 0000000000000..778b72b42796c
--- /dev/null
+++ b/docs/pages/includes/provision-token/bitbucket-spec.mdx
@@ -0,0 +1,47 @@
+```yaml
+kind: token
+version: v2
+metadata:
+  name: example-bot
+spec:
+  roles: [Bot]
+  join_method: bitbucket
+  bot_name: example
+  bitbucket:
+    # The URL of the workspace-specific OIDC identity provider. This can be
+    # found in the repository settings under "Pipelines" and "OpenID Connect".
+    identity_provider_url: $IDENTITY_PROVIDER_URL
+
+    # The audience of the OIDC tokens issued by Bitbucket. This can be found in
+    # the repository settings under "Pipelines" and "OpenID Connect".
+    audience: $AUDIENCE
+
+    # allow specifies the rules by which the Auth Server determines if `tbot`
+    # should be allowed to join. All parameters in a given allow entry must
+    # match for the join attempt to succeed, but many allow rules may be
+    # provided. One or both of `workspace_uuid` and `repository_uuid` are
+    # required; all other fields are optional.
+    allow:
+      - # The UUID of a workspace whose runs should be allowed to connect. This
+        # value can be found in the repository settings under "Pipelines" and
+        # "OpenID Connect". It must be enclosed in braces, i.e. `{...}`. At
+        # least `workspace_uuid` or `repository_uuid` must be provided.
+        workspace_uuid: '{WORKSPACE_UUID}'
+
+        # The UUID of a repository whose runs should be allowed to connect. This
+        # value can be found in the repository settings under "Pipelines" and
+        # "OpenID Connect". It must be enclosed in braces, i.e. `{...}`. At
+        # least `workspace_uuid` or `repository_uuid` must be provided.
+        repository_uuid: '{REPOSITORY_UUID}'
+
+        # If set, only steps tagged with the deployment environment linked to
+        # this UUID will be allowed to connect. This value can be found in the
+        # repository settings under "Pipelines" and "OpenID Connect" when a
+        # deployment environment is selected from the drop-down menu. It must be
+        # enclosed in braces, i.e. `{...}`. Optional.
+        deployment_environment_uuid: '{DEPLOYMENT_ENVIRONMENT_UUID}'
+
+        # If set, only workflows running on the named branch will be allowed to
+        # connect. Optional.
+        branch_name: "main"
+```
diff --git a/docs/pages/reference/join-methods.mdx b/docs/pages/reference/join-methods.mdx
index 455fcec66de53..75e0323337473 100644
--- a/docs/pages/reference/join-methods.mdx
+++ b/docs/pages/reference/join-methods.mdx
@@ -300,7 +300,7 @@ method](#aws-iam-role-iam) or [ephemeral secret tokens](#ephemeral-tokens).
 
 ### Azure managed identity: `azure`
 
-The Azure join method is available to any Teleport process running in an 
+The Azure join method is available to any Teleport process running in an
 Azure Virtual Machine. Support for joining a cluster with the Proxy Service
 behind a layer 7 load balancer or reverse proxy is available in Teleport 13.0+.
 
@@ -439,3 +439,16 @@ Support for self-hosted Terraform Enterprise requires Teleport Enterprise.
 <Admonition type="note" title="See Also">
 - [Run the Teleport Terraform Provider on Terraform Cloud](../admin-guides/infrastructure-as-code/terraform-provider/terraform-cloud.mdx)
 </Admonition>
+
+### Bitbucket Pipelines: `bitbucket`
+
+This join method is used to authenticate using Bitbucket's support for OpenID
+Connect, and is typically used to allow either Machine ID's `tbot` or the
+Teleport Terraform provider to authenticate to Teleport without use of shared
+secrets.
+
+(!docs/pages/includes/provision-token/bitbucket-spec.mdx!)
+
+<Admonition type="note" title="See Also">
+- [Deploying Machine ID on Bitbucket Pipelines](../enroll-resources/machine-id/deployment/bitbucket.mdx)
+</Admonition>