diff --git a/docs/pages/enroll-resources/workload-identity/aws-oidc-federation.mdx b/docs/pages/enroll-resources/workload-identity/aws-oidc-federation.mdx new file mode 100644 index 0000000000000..6febebfaf106b --- /dev/null +++ b/docs/pages/enroll-resources/workload-identity/aws-oidc-federation.mdx @@ -0,0 +1,461 @@ +--- +title: Configuring Workload Identity and AWS OIDC Federation +description: Configuring AWS to accept Workload Identity JWTs as authentication using OIDC Federation +--- + + +Teleport Workload Identity is currently in Preview. This means that some +features may be missing. We're actively looking for design partners to help us +shape the future of Workload Identity and would love to +[hear your feedback](mailto:product@goteleport.com). + + +Teleport Workload Identity issues flexible short-lived identities in JWT format. +AWS OIDC Federation allows you to use these JWTs to authenticate to AWS +services. + +This can be useful in cases where a machine needs to securely authenticate with +AWS services without the use of a long-lived credential. This is because the +machine can authenticate with Teleport without using any shared secrets by +using one of our delegated join methods. + +In this guide, we'll configure Teleport Workload Identity and AWS to allow our +workload to authenticate to the AWS S3 API and upload content to a bucket. + +## How it works + +This implementation differs from using the Teleport Application Service to protect +AWS APIs in a few ways: + +- Requests to AWS are not proxied through the Teleport Proxy Service, meaning + reduced latency but also less visibility, as these requests will not be + recorded in Teleport's audit log. +- Workload Identity works with any AWS client, including the command-line tool + but also their SDKs. +- Using the Teleport Application Service to access AWS does not work with Machine + ID and therefore cannot be used when a machine needs to authenticate with AWS. + +## OIDC Federation vs Roles Anywhere + +The AWS platform offers two routes for workload identity federation: OIDC +Federation and Roles Anywhere. Teleport Workload Identity supports both of these +methods. + +There are a number of differences between the two methods: + +- OIDC Federation exchanges a JWT SVID for an AWS credential, whereas Roles + Anywhere exchanges an X509 SVID for an AWS credential. The use of X509 SVIDs + is generally considered more secure. +- OIDC Federation does not require the additional installation of an AWS + credential helper alongside workloads, whereas Roles Anywhere does. +- OIDC Federation requires that your Teleport Proxy Service is reachable by + AWS, whereas Roles Anywhere does not. + +This guide covers configuring OIDC federation. For Roles Anywhere, see +[Configuring Workload Identity and AWS Roles Anywhere](./aws-roles-anywhere.mdx). + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx!) + +- (!docs/pages/includes/tctl.mdx!) +- `tbot` must already be installed and configured on the host where the +workloads which need to access Teleport Workload Identity will run. For more +information, see the [deployment guides](../machine-id/deployment.mdx). + + +Issuing JWT SVIDs with Teleport Workload Identity requires at least Teleport +version 16.4.3. + + +### Deciding on a SPIFFE ID structure + +Within Teleport Workload Identity, all identities are represented using a +SPIFFE ID. This is a URI that uniquely identifies the entity that the identity +represents. The scheme is always `spiffe://`, and the host will be the name of +your Teleport cluster. The structure of the path of this URI is up to you. + +For the purposes of this guide, we will be granting access to AWS to the +`spiffe://example.teleport.sh/svc/example-service` SPIFFE ID. + +If you have already deployed Teleport Workload Identity, then you will already +have a SPIFFE ID structure in place. If you have not, then you will need to +decide on a structure for your SPIFFE IDs. + +If you are only using Teleport Workload Identity with AWS OIDC Federation, you +may structure your SPIFFE IDs so that they explicitly specify the AWS role they +are allowed to assume. However, it often makes more sense to name the workload +or person that will use the SPIFFE ID. See the +[best practices guide](./best-practices.mdx) for further advice. + +## Step 1/4. Configure AWS + +Configuring AWS OIDC Federation for the first time involves a few steps. Some of +these may not be necessary if you have previously configured AWS OIDC Federation +for your Teleport cluster. + +### Create an OpenID Connect Identity Provider + +First, you'll need to create an OIDC identity provider in AWS. This will define +a trust relationship between AWS and your Teleport cluster's Workload Identity +issuer. You can reuse this OIDC identity provider to grant different workloads +using Teleport Workload Identity access to AWS services. + +When configuring the provider, you need to specify the issuer URI. This will be +the public address of your Teleport Proxy Service with the path +`/workload-identity` appended. Your Teleport Proxy Service must be accessible +by AWS in order for OIDC federation to work. + + + + +Before you can configure the OIDC identity provider, you need to determine the +thumbprint of the TLS certificate used by your Teleport Proxy Service. You can +do this using `curl`: + +```code +$ curl https://example.teleport.sh/webapi/thumbprint +"example589ee4bf31a11b78c72b8d13f0example"% +``` + +Insert the following into a Terraform configuration file which has already +been configured to manage your AWS account: + +```hcl +resource "aws_iam_openid_connect_provider" "example_teleport_sh_workload_identity" { + // Replace "example.teleport.sh" with the hostname used to access your + // Teleport Proxy Service. + url = "https://example.teleport.sh/workload-identity" + + client_id_list = [ + "sts.amazonaws.com", + ] + + thumbprint_list = [ + // Replace with the thumbprint you determined using curl. + "example589ee4bf31a11b78c72b8d13f0example" + ] +} +``` + + + + +1. Browse to IAM +1. Select "Identity Providers" from the sidebar +1. Select "Add provider" +1. Select "OpenID Connect" as the "Provider type". +1. Specify the public hostname of your Teleport Proxy Service, with + "/workload-identity" appended as the "Provider URL", e.g + `https://example.teleport.sh/workload-identity` +1. Specify `sts.amazonaws.com` as the Audience +1. Click "Add Provider". + + + + +### Create an S3 bucket + +For the purposes of this guide, you'll be granting the workload access to an +AWS S3 bucket. Before we can dive into configuring the RBAC, we'll need to +create our bucket. + +You can omit this step if you wish to grant access to a different service +within AWS. + + + +```hcl +// Create an S3 bucket +resource "aws_s3_bucket" "example" { + // Replace "example" with a meaningful, unique name. + bucket = "workload-id-demo" +} +``` + + + +1. Browse to S3 +1. Select "Create bucket" +1. Enter a meaningful, unique name for your bucket, e.g `workload-id-demo` +1. Leave other settings as default +1. Click "Create bucket". + + + + +### Configure RBAC + +#### Create an IAM Policy + +First, create an IAM policy that will grant access to the S3 bucket. Later, +you'll attach this to a role that the workload will assume. + +The examples in this guide will create an IAM policy that will grant full access +to the example bucket. In a production environment, you should modify this to +grant the least privileges necessary. + + + + +Insert the following into your Terraform configuration file: + +```hcl +resource "aws_iam_policy" "example" { + // Choose a unique, meaningful name that describes what the policy grants + // access to. + name = "workload-id-s3-full-access" + path = "/" + + // This example policy grants full access to AWS S3. In production, you + // may wish to grant a less permissive policy. + policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Action = "s3:*" + Effect = "Allow" + Resource = [ + aws_s3_bucket.workload_id_demo.arn, + "${aws_s3_bucket.workload_id_demo.arn}/*" + ] + }] + }) +} +``` + + + + +1. Browse to IAM +1. Select "Policies" from the sidebar +1. Click "Create policy" +1. Choose the "S3" service +1. Under "Actions allowed", choose "All S3 actions" +1. Under "Resources", choose "Specific" + 1. For "bucket" enter the name of the bucket you created earlier. + 1. For "object" enter the name of the bucket you created earlier and select + "All objects" +1. Click "Next" +1. Enter a unique and meaningful name for this policy, in our example, this will + be `workload-id-s3-full-access` +1. Click "Create policy" + + + + +#### Create an IAM Role + +Now, you'll create an IAM role. This role will be assumed by the workload +after it authenticates to AWS using the JWT SVID issued by Teleport Workload +Identity. + +When creating the IAM role, you'll define a trust policy that controls which +workload identities are able to assume the role. This policy will contain +conditions which will be evaluated against the claims within the JWT SVID +issued by Teleport Workload Identity. In our case, the only claim we want to +evaluate is the `sub` claim, which will contain our workload's SPIFFE ID. + +Finally, we'll attach the IAM policy we created earlier to this role to grant it +the privileges specified within the policy. + + + + +Insert the following into your Terraform configuration file: + +```hcl +// Create a role that the workload identity will assume. +resource "aws_iam_role" "example" { + // Choose a unique, meaningful name that describes the role and the workload + // that will assume it. + name = "workload-id-demo" + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Effect = "Allow" + Principal = { + Federated = aws_iam_openid_connect_provider.example.arn + } + Action = "sts:AssumeRoleWithWebIdentity" + Condition = { + StringEquals = { + "${aws_iam_openid_connect_provider.example.url}:aud" = "sts.amazonaws.com" + "${aws_iam_openid_connect_provider.example.url}:sub" = "spiffe://example.teleport.sh/svc/example-service" + } + } + }] + }) +} + +// Attach the policy we created earlier to our role. +resource "aws_iam_role_policy_attachment" "example" { + role = aws_iam_role.example.name + policy_arn = aws_iam_policy.example.arn +} +``` + + + +1. Browse to IAM +1. Select "Roles" from the sidebar +1. Click "Create role" +1. Select "Web identity" for the "Trusted entity type" +1. Select your identity provider +1. Select the `sts.amazonaws.com` audience +1. Click "Add condition" + 1. Select `example.teleport.sh:sub` for the key + 1. Select "StringEquals" for the condition + 1. Enter the SPIFFE ID of your workload for the value. In our example, this + will be `spiffe://example.teleport.sh/svc/example +1. Click "Next" +1. Select the IAM policy you created earlier, and click "Next" +1. Enter a unique and meaningful name for this role, in our example, this will + be `workload-id-demo` +1. Click "Create role" + + + + +## Step 2/4. Configure Teleport RBAC + +Now we need to configure Teleport to allow a JWT to be issued containing the +SPIFFE ID we have chosen. + +Create `role.yaml` with the following content: + +```yaml +kind: role +version: v6 +metadata: + name: my-workload-aws +spec: + allow: + spiffe: + - path: /svc/example-service +``` + +Replace: + +- `my-workload-aws` with a descriptive name for the role. +- `/svc/example-service` with the path part of the SPIFFE ID you have chosen. + +Apply this role to your Teleport cluster using `tctl`: + +```code +$ tctl create -f role.yaml +``` + +You now need to assign this role to the bot: + +```code +$ tctl bots update my-bot --add-roles my-workload-aws +``` + +## Step 3/4. Issue Workload Identity JWTs + +You'll now configure `tbot` to issue and renew the short-lived JWT SVIDs for +your workload. It'll write the JWT as a file on disk, where you can then +configure AWS clients and SDKs to read it. + +Take your already deployed `tbot` service and configure it to issue SPIFFE SVIDs +by adding the following to the `tbot` configuration file: + +```yaml +outputs: + - type: spiffe-svid + destination: + type: directory + path: /opt/workload-identity + svid: + path: /svc/example-service + jwts: + - audience: sts.amazonaws.com + file_name: aws-jwt +``` + +Replace: + +- /opt/workload-identity with the directory where you want the JWT to be + written. +- /svc/example-service with the SPIFFE ID you have chosen. + +Restart your `tbot` service to apply the new configuration. You should see a +file created at `/opt/workload-identity/aws-jwt` containing the JWT. + +## Step 4/4. Configure AWS CLIs and SDKs + +Finally, you need to configure the AWS CLIs and SDKs to use the JWT SVID for +authentication. + +This can be done using the configuration file located at `~/.aws/config` or by +using environment variables. + +To proceed, you'll need to know the ARN of the role you created earlier. + + + + +Add the following to your `~/.aws/config` file: + +```ini +# You can replace "workload-id-demo" with a recognizable name that identifies +# your use-case. +[profile workload-id-demo] +# Replace with the ARN of the role you created earlier. +role_arn=arn:aws:iam:123456789012:role/workload-id-demo +# Replace with the directory and file name you configured `tbot` to write the +# JWT to. +web_identity_token_file=/opt/workload-identity/aws-jwt +``` + + + + +Configure the following environment variables: + +- `AWS_ROLE_ARN`: The ARN of the role you created earlier, e.g + `arn:aws:iam::123456789012:role/workload-id-demo` +- `AWS_WEB_IDENTITY_TOKEN_FILE`: The path to the JWT file that `tbot` is writing, + e.g `/opt/workload-identity/aws-jwt` + + + + +You can now test authenticating to the AWS S3 API. Create a file which you can +upload to your bucket: + +```code +$ echo "Hello, World!" > hello.txt +``` + +Now, use the AWS CLI to upload this file to your bucket: + +```code +$ aws s3 cp hello.txt s3://workload-id-demo +``` + +If everything is configured correctly, you should see this file uploaded to your +bucket: + +```code +$ aws s3 ls s3://workload-id-demo +``` + +Inspecting the audit logs on CloudTrail should indicate that the request +was authenticated using Workload Identity and specify the SPIFFE ID of the +workload that made the request. + +## Next steps + +- [AWS OIDC Federation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc.html): +The official AWS documentation for OIDC federation. +- [AWS CLI documentation](https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-role.html#cli-configure-role-oidc): +The official AWS CLI documentation for configuring a role to be assumed. +- [Workload Identity Overview](./introduction.mdx): Overview of Teleport +Workload Identity. +- [JWT SVID Overview](./jwt-svids.mdx): Overview of the JWT SVIDs issued by +Teleport Workload Identity. +- [Best Practices](./best-practices.mdx): Best practices for using Workload +Identity in Production. +- Read the [configuration reference](../../reference/machine-id/configuration.mdx) to explore +all the available configuration options. diff --git a/docs/pages/enroll-resources/workload-identity/aws-roles-anywhere.mdx b/docs/pages/enroll-resources/workload-identity/aws-roles-anywhere.mdx index 3d3d3e49b4113..bbbe4116ae9d3 100644 --- a/docs/pages/enroll-resources/workload-identity/aws-roles-anywhere.mdx +++ b/docs/pages/enroll-resources/workload-identity/aws-roles-anywhere.mdx @@ -37,6 +37,25 @@ Whilst this guide is primarily aimed at allowing a machine to access AWS, the `tsh svid issue` command can be used in place of Machine ID to allow a human user to authenticate with using AWS Roles Anywhere. +## OIDC Federation vs Roles Anywhere + +The AWS platform offers two routes for workload identity federation: OIDC +Federation and Roles Anywhere. Teleport Workload Identity supports both of these +methods. + +There are a number of differences between the two methods: + +- Roles Anywhere exchanges an X509 SVID for an AWS credential, whereas OIDC + Federation exchanges a JWT SVID for an AWS credential. The use of X509 SVIDs + is generally considered more secure. +- Roles Anywhere requires the installation of an AWS credential helper alongside + the workloads, whereas OIDC Federation does not. +- Roles Anywhere does not require the Teleport Proxy Service to be reachable by + AWS, whereas OIDC Federation does. + +This guide covers configuring Roles Anywhere, for OIDC federation, see +[Configuring Workload Identity and AWS OIDC Federation](./aws-oidc-federation.mdx). + ## Prerequisites (!docs/pages/includes/edition-prereqs-tabs.mdx!) diff --git a/docs/pages/enroll-resources/workload-identity/gcp-workload-identity-federation-jwt.mdx b/docs/pages/enroll-resources/workload-identity/gcp-workload-identity-federation-jwt.mdx index 7feec924773a6..fe0a0c7b876d5 100644 --- a/docs/pages/enroll-resources/workload-identity/gcp-workload-identity-federation-jwt.mdx +++ b/docs/pages/enroll-resources/workload-identity/gcp-workload-identity-federation-jwt.mdx @@ -45,6 +45,11 @@ GCP APIs in a few ways: workloads which need to access Teleport Workload Identity will run. For more information, see the [deployment guides](../machine-id/deployment.mdx). + +Issuing JWT SVIDs with Teleport Workload Identity requires at minimum version +16.4.3. + + ### Deciding on a SPIFFE ID structure Within Teleport Workload Identity, all identities are represented using a diff --git a/docs/pages/enroll-resources/workload-identity/introduction.mdx b/docs/pages/enroll-resources/workload-identity/introduction.mdx index 2c1af78ce8e87..8c50fdcdcf306 100644 --- a/docs/pages/enroll-resources/workload-identity/introduction.mdx +++ b/docs/pages/enroll-resources/workload-identity/introduction.mdx @@ -157,8 +157,9 @@ Learn how to configure Teleport Workload Identity for specific use-cases: - [Getting Started](./getting-started.mdx): How to configure Teleport for Workload Identity. - [TSH Support](./tsh.mdx): How to use `tsh` with Workload Identity to issue SVIDs to users. -- [AWS Roles Anywhere](./aws-roles-anywhere.mdx): Configuring AWS to accept Workload ID certificates as authentication using AWS Roles Anywhere. -- [GCP Workload Identity Federation](./gcp-workload-identity-federation-jwt.mdx): Configuring GCP to accept Workload ID JWTs as authentication using GCP Workload Identity Federation. +- [AWS Roles Anywhere](./aws-roles-anywhere.mdx): Configuring AWS to accept Workload Identity certificates as authentication using AWS Roles Anywhere. +- [AWS OIDC Federation](./aws-oidc-federation.mdx): Configuring AWS to accept Workload Identity JWTs as authentication using AWS OIDC Federation. +- [GCP Workload Identity Federation](./gcp-workload-identity-federation-jwt.mdx): Configuring GCP to accept Workload Identity JWTs as authentication using GCP Workload Identity Federation. ### Other resources diff --git a/docs/pages/enroll-resources/workload-identity/jwt-svids.mdx b/docs/pages/enroll-resources/workload-identity/jwt-svids.mdx index d4d376b89a0a9..ca2e47ec2c5cc 100644 --- a/docs/pages/enroll-resources/workload-identity/jwt-svids.mdx +++ b/docs/pages/enroll-resources/workload-identity/jwt-svids.mdx @@ -14,6 +14,8 @@ One type of credential that can be issued by Teleport Workload Identity is a JWT SVID. This is a short-lived JSON Web Token (JWT) that contains the identity of the workload and is signed by the Teleport Workload Identity CA. +The ability is issue JWT SVIDs has been available since Teleport 16.4.3. + ## Claims The JWT contains the following claims: @@ -59,7 +61,7 @@ Teleport Proxy service as the issuer URL for OIDC configuration. We have tested Teleport Workload Identity issued JWT-SVIDs with the following platforms: -- AWS +- [AWS](./aws-oidc-federation.mdx) - [Google Cloud Platform](./gcp-workload-identity-federation-jwt.mdx) - Azure