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