In Red Hat OpenShift Service on AWS clusters that use the AWS Security Token Service (STS), the OpenShift API server can be enabled to project signed service account tokens that can be used to assume an AWS Identity and Access Management (IAM) role in a pod. If the assumed IAM role has the required AWS permissions, the pods can authenticate against the AWS API using temporary STS credentials to perform AWS operations.
You can use the pod identity webhook to project service account tokens to assume an AWS Identity and Access Management (IAM) role for your own workloads. If the assumed IAM role has the required AWS permissions, the pods can run AWS SDK operations by using temporary STS credentials.
When you install a Red Hat OpenShift Service on AWS cluster, cluster-specific Operator AWS Identity and Access Management (IAM) roles are created. These IAM roles permit the ROSA cluster Operators to run core OpenShift functionality.
Cluster Operators use service accounts to assume IAM roles. When a service account assumes an IAM role, temporary AWS STS credentials are provided for the service account to use in the cluster Operator’s pod. If the assumed role has the necessary AWS privileges, the service account can run AWS SDK operations in the pod.
The following diagram illustrates the workflow for assuming AWS IAM roles in SRE owned projects:
Figure 9.1. Workflow for assuming AWS IAM roles in SRE owned projects

The workflow has the following stages:
Within each project that a cluster Operator runs, the Operator’s deployment spec has a volume mount for the projected service account token, and a secret containing AWS credential configuration for the pod. The token is audience-bound and time-bound. Every hour, ROSA generates a new token, and the AWS SDK reads the mounted secret containing the AWS credential configuration. This configuration has a path to the mounted token and the AWS IAM Role ARN. The secret’s credential configuration includes the following:
$AWS_ARN_ROLE variable that has the ARN for the IAM role that has the permissions required to run AWS SDK operations.
$AWS_WEB_IDENTITY_TOKEN_FILE variable that has the full path in the pod to the OpenID Connect (OIDC) token for the service account. The full path is /var/run/secrets/openshift/serviceaccount/token.
AssumeRoleWithWebIdentity API call.
The OIDC token is passed from the pod to the OIDC provider. The provider authenticates the service account identity if the following requirements are met:
The sts.amazonaws.com audience is listed in the OIDC token and matches the audience configured in the OIDC provider.
In ROSA with STS clusters, the OIDC provider is created during install and set as the service account issuer by default. The sts.amazonaws.com audience is set by default in the OIDC provider.
When you install a Red Hat OpenShift Service on AWS cluster , pod identity webhook resources are included by default.
You can use the pod identity webhook to enable a service account in a user-defined project to assume an AWS Identity and Access Management (IAM) role in a pod in the same project. When the IAM role is assumed, temporary STS credentials are provided for use by the service account in the pod. If the assumed role has the necessary AWS privileges, the service account can run AWS SDK operations in the pod.
To enable the pod identity webhook for a pod, you must create a service account with an eks.amazonaws.com/role-arn annotation in your project. The annotation must reference the Amazon Resource Name (ARN) of the AWS IAM role that you want the service account to assume. You must also reference the service account in your Pod specification and deploy the pod in the same project as the service account.
The following diagram illustrates the pod identity webhook workflow in user-defined projects:
Figure 9.2. Pod identity webhook workflow in user-defined projects

The workflow has the following stages:
eks.amazonaws.com/role-arn annotation. The annotation points to the ARN of the AWS IAM role that you want your service account to assume.
When a pod is deployed in the same project using a configuration that references the annotated service account, the pod identity webhook mutates the pod. The mutation injects the following components into the pod without the need to specify them in your Pod or Deployment resource configurations:
$AWS_ARN_ROLE environment variable that contains the ARN for the IAM role that has the permissions required to run AWS SDK operations.
$AWS_WEB_IDENTITY_TOKEN_FILE environment variable that contains the full path in the pod to the OpenID Connect (OIDC) token for the service account. The full path is /var/run/secrets/eks.amazonaws.com/serviceaccount/token.
aws-iam-token volume mounted on the mount point /var/run/secrets/eks.amazonaws.com/serviceaccount. An OIDC token file named token is contained in the volume.
The OIDC token is passed from the pod to the OIDC provider. The provider authenticates the service account identity if the following requirements are met:
The sts.amazonaws.com audience is listed in the OIDC token and matches the audience configured in the OIDC provider.
The pod identity webhook applies the sts.amazonaws.com audience to the OIDC token by default.
Follow the procedures in this section to enable a service account to assume an AWS Identity and Access Management (IAM) role in a pod deployed in a user-defined project.
You can create the required resources, including an AWS IAM role, a service account, a container image that includes an AWS SDK, and a pod deployed by using the image. In the example, the AWS Boto3 SDK for Python is used. You can also verify that the pod identity webhook mutates the AWS environment variables, the volume mount, and the token volume into your pod. Additionally, you can check that the service account assumes the AWS IAM role in your pod and can successfully run AWS SDK operations.
Create an AWS Identity and Access Management (IAM) role to be assumed by a service account in your Red Hat OpenShift Service on AWS cluster. Attach the permissions that are required by your service account to run AWS SDK operations in a pod.
Prerequisites
You have the Amazon Resource Name (ARN) for the OpenID Connect (OIDC) provider that is configured as the service account issuer in your Red Hat OpenShift Service on AWS with STS cluster.
In Red Hat OpenShift Service on AWS with STS clusters, the OIDC provider is created during install and set as the service account issuer by default. If you do not know the OIDC provider ARN, contact your cluster administrator.
aws).
Procedure
Create a file named trust-policy.json with the following JSON configuration:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "<oidc_provider_arn>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"<oidc_provider_name>:sub": "system:serviceaccount:<project_name>:<service_account_name>"
}
}
}
]
}<oidc_provider_arn><oidc_provider_arn> with the ARN of your OIDC provider, for example, arn:aws:iam::<aws_account_id>:oidc-provider/rh-oidc.s3.us-east-1.amazonaws.com/1v3r0n44npxu4g58so46aeohduomfres. You can retrieve the ARN by using the rosa describe cluster CLI command.
<oidc_provider_name><oidc_provider_name> with the name of your OIDC provider, for example rh-oidc.s3.us-east-1.amazonaws.com/1v3r0n44npxu4g58so46aeohduomfres.
<project_name>:<service_account_name><project_name>:<service_account_name> with your project name and service account name, for example my-project:test-service-account. This action limits the role to the specified project and service account.
Alternatively, you can limit the role to any service account within the specified project by using "<oidc_provider_name>:sub": "system:serviceaccount:<project_name>:*". If you supply the * wildcard, you must replace StringEquals with StringLike in the preceding line.
Create an AWS IAM role that uses the trust policy that is defined in the trust-policy.json file:
$ aws iam create-role \
--role-name <aws_iam_role_name> \
--assume-role-policy-document file://trust-policy.json
Replace <aws_iam_role_name> with the name of your IAM role, for example pod-identity-test-role and use the trust-policy.json file that you created in the preceding step.
Example output
ROLE arn:aws:iam::<aws_account_id>:role/<aws_iam_role_name> 2022-09-28T12:03:17+00:00 / AQWMS3TB4Z2N3SH7675JK <aws_iam_role_name> ASSUMEROLEPOLICYDOCUMENT 2012-10-17 STATEMENT sts:AssumeRoleWithWebIdentity Allow STRINGEQUALS system:serviceaccount:<project_name>:<service_account_name> PRINCIPAL <oidc_provider_arn>
Retain the ARN for the role in the output. The format of the role ARN is arn:aws:iam::<aws_account_id>:role/<aws_iam_role_name>.
Attach any managed AWS permissions that are required when the service account runs AWS SDK operations in your pod. The policy in this example adds read-only access permissions to the IAM role.
$ aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess \
--role-name <aws_iam_role_name> 1
Replace <aws_iam_role_name> with the name of the IAM role that you created in the preceding step.
Add a service account in your user-defined project. Include an eks.amazonaws.com/role-arn annotation in the service account configuration that references the Amazon Resource Name (ARN) for the AWS Identity and Access Management (IAM) role that you want the service account to assume.
Prerequisites
oc).
Procedure
In your Red Hat OpenShift Service on AWS cluster, create a project:
$ oc new-project <project_name>
Replace <project_name> with the name of your project. The name must match the project name that you specified in your AWS IAM role configuration.
You are automatically switched to the project when it is created.
Create a file named test-service-account.yaml with the following service account configuration:
apiVersion: v1
kind: ServiceAccount
metadata:
name: <service_account_name>
namespace: <project_name>
annotations:
eks.amazonaws.com/role-arn: "<aws_iam_role_arn>"<service_account_name><service_account_name> with the name of your service account. The name must match the service account name that you specified in your AWS IAM role configuration.
<project_name><project_name> with the name of your project. The name must match the project name that you specified in your AWS IAM role configuration.
<aws_iam_role_arn><aws_iam_role_arn> with the ARN for the AWS IAM role that you created for your service account. The format of the role ARN is arn:aws:iam::<aws_account_id>:role/<aws_iam_role_name>.
Create the service account in your project:
$ oc create -f test-service-account.yaml
Example output
serviceaccount/<service_account_name> created
Review the details of the service account:
$ oc describe serviceaccount <service_account_name>
Replace <service_account_name> with the name of your service account.
Example output
Name: <service_account_name> Namespace: <project_name> 1 Labels: <none> Annotations: eks.amazonaws.com/role-arn: <aws_iam_role_arn> 2 Image pull secrets: <service_account_name>-dockercfg-rnjkq Mountable secrets: <service_account_name>-dockercfg-rnjkq Tokens: <service_account_name>-token-4gbjp Events: <none>
<service_account_name><project_name><aws_iam_role_arn>The steps in this procedure provide an example method to create a container image that includes an AWS SDK.
The example steps use Podman to create the container image and Quay.io to host the image. For more information about Quay.io, see Getting Started with Quay.io. The container image can be used to deploy pods that can run AWS SDK operations.
In this example procedure, the AWS Boto3 SDK for Python is installed into a container image. For more information about installing and using the AWS Boto3 SDK, see the AWS Boto3 documentation. For details about other AWS SDKs, see AWS SDKs and Tools Reference Guide in the AWS documentation.
Prerequisites
Procedure
Add the following configuration to a file named Containerfile:
FROM ubi9/ubi RUN dnf makecache && dnf install -y python3-pip && dnf clean all && pip3 install boto3>=1.15.0
FROM ubi9/ubiRUN dnf makecache && dnf install -y python3-pip && dnf clean all && pip3 install boto3>=1.15.0pip package management system. In this example, AWS Boto3 SDK version 1.15.0 or later is installed.
From the directory that contains the file, build a container image named awsboto3sdk:
$ podman build -t awsboto3sdk .
Log in to Quay.io:
$ podman login quay.io
Tag the image in preparation for the upload to Quay.io:
$ podman tag localhost/awsboto3sdk quay.io/<quay_username>/awsboto3sdk:latest
Replace <quay_username> with your Quay.io username.
Push the tagged container image to Quay.io:
$ podman push quay.io/<quay_username>/awsboto3sdk:latest
Replace <quay_username> with your Quay.io username.
Make the Quay.io repository that contains the image public. This publishes the image so that it can be used to deploy a pod in your Red Hat OpenShift Service on AWS cluster:
Deploy a pod in a user-defined project from a container image that includes an AWS SDK. In your pod configuration, specify the service account that includes the eks.amazonaws.com/role-arn annotation.
With the service account reference in place for your pod, the pod identity webhook injects the AWS environment variables, the volume mount, and the token volume into your pod. The pod mutation enables the service account to automatically assume the AWS IAM role in the pod.
Prerequisites
oc).
eks.amazonaws.com/role-arn annotation that references the Amazon Resource Name (ARN) for the IAM role that you want the service account to assume.
You have a container image that includes an AWS SDK and the image is available to your cluster. For detailed steps, see Creating an example AWS SDK container image.
In this example procedure, the AWS Boto3 SDK for Python is used. For more information about installing and using the AWS Boto3 SDK, see the AWS Boto3 documentation. For details about other AWS SDKs, see AWS SDKs and Tools Reference Guide in the AWS documentation.
Procedure
Create a file named awsboto3sdk-pod.yaml with the following pod configuration. In this example pod configuration, the sleep 100000 line keeps the pod running for 100000 seconds to enable verification testing in the pod directly. For detailed verification steps, see Verifying the assumed IAM role in your pod.
apiVersion: v1
kind: Pod
metadata:
namespace: <project_name>
name: awsboto3sdk
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccountName: <service_account_name>
containers:
- name: awsboto3sdk
image: quay.io/<quay_username>/awsboto3sdk:latest
command:
- /bin/bash
- "-c"
- "sleep 100000"
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
terminationGracePeriodSeconds: 0
restartPolicy: Never<project_name><project_name> with the name of your project. The name must match the project name that you specified in your AWS IAM role configuration.
<service_account_name><service_account_name> with the name of the service account that is configured to assume the AWS IAM role. The name must match the service account name that you specified in your AWS IAM role configuration.
<quay_username><quay_username> with your Quay.io username to specify the location of your awsboto3sdk container image.
Deploy an awsboto3sdk pod:
$ oc create -f awsboto3sdk-pod.yaml
Example output
pod/awsboto3sdk created
After deploying an awsboto3sdk pod in your project, verify that the pod identity webhook has mutated the pod. Check that the required AWS environment variables, volume mount, and OIDC token volume are present within the pod.
You can also verify that the service account assumes the AWS Identity and Access Management (IAM) role for your AWS account when you run AWS SDK operations in the pod.
Prerequisites
oc).
eks.amazonaws.com/role-arn annotation that references the Amazon Resource Name (ARN) for the IAM role that you want the service account to assume.
You have deployed a pod in your user-defined project that includes an AWS SDK. The pod references the service account that uses the pod identity webhook to assume the AWS IAM role required to run the AWS SDK operations. For detailed steps, see Deploying a pod that includes an AWS SDK.
In this example procedure, a pod that includes the AWS Boto3 SDK for Python is used. For more information about installing and using the AWS Boto3 SDK, see the AWS Boto3 documentation. For details about other AWS SDKs, see AWS SDKs and Tools Reference Guide in the AWS documentation.
Procedure
Verify that the AWS environment variables, the volume mount, and the OIDC token volume are listed in the description of the deployed awsboto3sdk pod:
$ oc describe pod awsboto3sdk
Example output
Name: awsboto3sdk
Namespace: <project_name>
...
Containers:
awsboto3sdk:
...
Environment:
AWS_ROLE_ARN: <aws_iam_role_arn> 1
AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token 2
Mounts:
/var/run/secrets/eks.amazonaws.com/serviceaccount from aws-iam-token (ro) 3
...
Volumes:
aws-iam-token: 4
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 86400
...
<project_name><aws_iam_role_arn>AWS_ROLE_ARN environment variable that was injected into the pod by the pod identity webhook. The variable contains the ARN of the AWS IAM role to be assumed by the service account.
<aws_web_identity_token_file>AWS_WEB_IDENTITY_TOKEN_FILE environment variable that was injected into the pod by the pod identity webhook. The variable contains the full path of the OIDC token that is used to verify the service account identity.
Mountsaws-iam-token volume mount that was injected into the pod by the pod identity webhook is listed here.
<aws-iam-token>aws-iam-token volume that is mounted onto the /var/run/secrets/eks.amazonaws.com/serviceaccount mount point. The volume contains the OIDC token that is used to authenticate the service account to assume the AWS IAM role.
Start an interactive terminal in the awsboto3sdk pod:
$ oc exec -ti awsboto3sdk -- /bin/sh
In the interactive terminal for the pod, verify that the $AWS_ROLE_ARN environment variable was mutated into the pod by the pod identity webhook:
$ echo $AWS_ROLE_ARN
Example output
arn:aws:iam::<aws_account_id>:role/<aws_iam_role_name>
The output must specify the ARN for the AWS IAM role that has the permissions required to run AWS SDK operations.
In the interactive terminal for the pod, verify that the $AWS_WEB_IDENTITY_TOKEN_FILE environment variable was mutated into the pod by the pod identity webhook:
$ echo $AWS_WEB_IDENTITY_TOKEN_FILE
Example output
/var/run/secrets/eks.amazonaws.com/serviceaccount/token
The output must specify the full path in the pod to the OIDC token for the service account.
In the interactive terminal for the pod, verify that the aws-iam-token volume mount containing the OIDC token file was mounted by the pod identity webhook:
$ mount | grep -is 'eks.amazonaws.com'
Example output
tmpfs on /run/secrets/eks.amazonaws.com/serviceaccount type tmpfs (ro,relatime,seclabel,size=13376888k)
In the interactive terminal for the pod, verify that an OIDC token file named token is present on the /var/run/secrets/eks.amazonaws.com/serviceaccount/ mount point:
$ ls /var/run/secrets/eks.amazonaws.com/serviceaccount/token
Example output
/var/run/secrets/eks.amazonaws.com/serviceaccount/token 1
The OIDC token file in the aws-iam-token volume that was mounted in the pod by the pod identity webhook. The token is used to authenticate the identity of the service account in AWS.
In the pod, verify that AWS Boto3 SDK operations run successfully:
In the interactive terminal for the pod, start a Python 3 shell:
$ python3
In the Python 3 shell, import the boto3 module:
>>> import boto3
Create a variable that includes the Boto3 s3 service resource:
>>> s3 = boto3.resource('s3')Print the names of all of the S3 buckets in your AWS account:
>>> for bucket in s3.buckets.all(): ... print(bucket.name) ...
Example output
<bucket_name> <bucket_name> <bucket_name> ...
If the service account successfully assumed the AWS IAM role, the output lists all of the S3 buckets that are available in your AWS account.