All Products
Search
Document Center

Container Service for Kubernetes:Use RRSA to authorize different pods to access different cloud services

Last Updated:Mar 26, 2026

RAM Roles for Service Accounts (RRSA) lets each pod in a Container Service for Kubernetes (ACK) cluster assume a dedicated Resource Access Management (RAM) role and obtain short-lived Security Token Service (STS) tokens for cloud service access.

RRSA provides two key security properties:

  • Least privilege: You can scope RAM permissions to a specific service account, so only pods using that account can access those resources. This eliminates the need for static AccessKey pairs.

  • Credential isolation: Pods cannot access credentials used by other pods on the same node. Without RRSA, all pods on a node share the permissions of the underlying Elastic Compute Service (ECS) instance role.

How it works

Without RRSA, applications running in ACK pods use the ECS instance metadata to obtain STS tokens tied to the instance role. Every pod on that node shares the same permissions — a significant security risk.

RRSA solves this by binding a specific RAM role to a specific Kubernetes service account. When a pod starts, it receives an OpenID Connect (OIDC) token scoped to its service account. The pod uses that token to call the AssumeRoleWithOIDC API and receive a role-scoped STS token, which it then uses to call cloud service APIs.

The flow, step by step:

  1. The pod starts with service account token volume projection enabled.

  2. ACK mounts an OIDC token file into the pod, scoped to the pod's service account.

  3. The application calls AssumeRoleWithOIDC with the OIDC token and receives an STS token for the specified RAM role.

  4. The application uses the STS token to call the target cloud service API.

The OIDC token is short-lived. Configure your application to read the token from the OIDC token file each time it needs to authenticate — do not cache it. ACK automatically renews the token before it expires.

When RRSA is enabled, ACK performs the following setup automatically:

  • Creates a dedicated OIDC issuer for the cluster, managed by ACK.

  • Enables service account token volume projection for the cluster.

  • Creates a RAM identity provider (IdP) in your account, named ack-rrsa-<cluster_id>, configured for single sign-on (SSO) with the cluster's OIDC issuer.

Limitations

RRSA is supported on ACK clusters running Kubernetes 1.22 and later. Supported cluster types:

  • ACK Basic cluster

  • ACK Pro cluster

  • ACK Serverless Basic cluster

  • ACK Serverless Pro cluster

  • ACK Edge Pro cluster

Important

After RRSA is enabled, the maximum validity period for all newly created ServiceAccount tokens is capped at 12 hours.

Prerequisites

Before you begin, ensure that you have:

  • An ACK cluster running Kubernetes 1.22 or later

  • Permissions to manage RAM roles and policies in the RAM console

  • Permissions to manage add-ons and cluster settings in the ACK console

Enable RRSA

You can enable RRSA during cluster creation or after the cluster is running. For ACK Serverless clusters, enable RRSA after cluster creation from the cluster details page.

Enable during cluster creation

When creating an ACK managed cluster or ACK Edge cluster, go to the Cluster Configurations step, expand Advanced Options (Optional), and click Enable next to RRSA OIDC.

image

Enable after cluster creation

  1. Log on to the ACK console. In the left navigation pane, click Clusters.

  2. Click the name of your cluster. In the left navigation pane, click Cluster Information.

  3. On the Basic Information tab, scroll to the Security and Auditing section and click Enable next to RRSA OIDC.

    image

  4. In the Enable RRSA dialog box, click Confirm. Wait for the cluster status to change from Updating to Running. RRSA is now enabled.

Get the OIDC provider URL and ARN

After RRSA is enabled, hover over the Enabled label next to RRSA OIDC in the Security and Auditing section. The URL and Alibaba Cloud Resource Name (ARN) of the OIDC provider are displayed.

image

You need both values when configuring RAM roles and application templates.

Set up RRSA for an application

This section walks through the full setup for a sample application. The setup has two parts:

  • Cluster-level setup (do once per cluster): Enable RRSA and install ack-pod-identity-webhook.

  • Per-application setup (repeat for each app): Create a RAM role, grant permissions, deploy the application.

Sample configuration:

Item Value
Namespace rrsa-demo
Service account demo-sa
RAM role demo-role-for-rrsa
使用示例流程

Step 1: Install ack-pod-identity-webhook

ack-pod-identity-webhook automatically injects the OIDC token file path and RAM role ARN into pods as environment variables. Skip this step if you prefer to configure the pod template manually — see Configure the pod template manually.

  1. In the ACK console, click the name of your cluster. In the left navigation pane, choose Operations > Add-ons.

  2. On the Add-ons page, click the Security tab.

  3. Find ack-pod-identity-webhook and click Install on the card.

  4. Confirm the information and click OK.

Step 2: Create a RAM role for the OIDC identity provider

Create a RAM role named demo-role-for-rrsa that trusts the cluster's OIDC identity provider (IdP). For full instructions, see Create a RAM role for an OIDC IdP.

Use the following parameter values:

Parameter Value
Identity Provider Type Select OIDC
Identity Provider Select the IdP named ack-rrsa-<cluster_id>
oidc:iss Use the default value
oidc:aud Use the default value
oidc:sub Add this condition manually: Key = oidc:sub, Operator = StringEquals, Value = system:serviceaccount:rrsa-demo:demo-sa
RAM Role Name demo-role-for-rrsa
The oidc:sub condition scopes the trust to a specific service account in a specific namespace. Replace rrsa-demo and demo-sa with your actual namespace and service account name.

Step 3: Grant permissions to the RAM role

Attach the AliyunCSReadOnlyAccess policy to demo-role-for-rrsa. For instructions, see Grant permissions to a RAM role.

This grants the application read-only access to ACK cluster information.

Step 4: Deploy the application

Create a file named demo.yaml with the following content. The namespace label pod-identity.alibabacloud.com/injection: 'on' and the service account annotation pod-identity.alibabacloud.com/role-name: demo-role-for-rrsa enable automatic injection by ack-pod-identity-webhook. For configuration details, see ack-pod-identity-webhook.

---
apiVersion: v1
kind: Namespace
metadata:
  name: rrsa-demo
  labels:
    pod-identity.alibabacloud.com/injection: 'on'

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: demo-sa
  namespace: rrsa-demo
  annotations:
    pod-identity.alibabacloud.com/role-name: demo-role-for-rrsa

---
apiVersion: v1
kind: Pod
metadata:
  name: demo
  namespace: rrsa-demo
spec:
  serviceAccountName: demo-sa
  containers:
    - image: registry.cn-hangzhou.aliyuncs.com/acs/ack-ram-tool:1.2.0
      imagePullPolicy: "Always"
      args:
        - rrsa
        - demo
        - --region=cn-hangzhou
      name: demo
  restartPolicy: OnFailure

Deploy the application:

kubectl apply -f demo.yaml

Step 5: Verify the injected configuration

Run the following command to confirm that ack-pod-identity-webhook injected the required environment variables and volume mounts into the pod:

kubectl -n rrsa-demo get pod demo -o yaml

The expected output includes the following injected items:

Category Item Description
Environment variable ALIBABA_CLOUD_ROLE_ARN ARN of the RAM role to assume
Environment variable ALIBABA_CLOUD_OIDC_PROVIDER_ARN ARN of the OIDC identity provider
Environment variable ALIBABA_CLOUD_OIDC_TOKEN_FILE Path to the OIDC token file
VolumeMount rrsa-oidc-token Mounts the OIDC token into the container
Volume rrsa-oidc-token Projected volume source for the OIDC token

A correctly injected pod spec looks like this:

apiVersion: v1
kind: Pod
metadata:
  name: demo
  namespace: rrsa-demo
spec:
  containers:
  - args:
    - rrsa
    - demo
    env:
    - name: ALIBABA_CLOUD_ROLE_ARN
      value: acs:ram::1***:role/demo-role-for-rrsa
    - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN
      value: acs:ram::1***:oidc-provider/ack-rrsa-c***
    - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE
      value: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens/token
    image: registry.cn-hangzhou.aliyuncs.com/acs/ack-ram-tool:1.0.0
    imagePullPolicy: Always
    name: demo
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-4bwdg
      readOnly: true
    - mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens
      name: rrsa-oidc-token
      readOnly: true
  restartPolicy: OnFailure
  serviceAccount: demo-sa
  serviceAccountName: demo-sa
  volumes:
  - name: kube-api-access-4bwdg
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
  - name: rrsa-oidc-token
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          audience: sts.aliyuncs.com
          expirationSeconds: 3600
          path: token

Step 6: Check application logs

Run the following command to print the application log:

kubectl -n rrsa-demo logs demo

A successful run lists the clusters in your Alibaba Cloud account:

cluster id: cf***, cluster name: foo*
cluster id: c8***, cluster name: bar*
cluster id: c4***, cluster name: foob*

Optional: To verify that RRSA correctly enforces least-privilege access, detach the AliyunCSReadOnlyAccess policy from the RAM role (see Remove permissions from a RAM role). Wait 30 seconds, then run the log command again. The application returns a 403 error similar to:

   StatusCode: 403
   Code: StatusForbidden
   Message: code: 403, STSToken policy Forbidden for action cs:DescribeClustersForRegion request id: E78A2E2D-***
   Data: {"accessDeniedDetail":{"AuthAction":"cs:DescribeClustersForRegion","AuthPrincipalDisplayName":"demo-role-for-rrsa:ack-ram-tool","AuthPrincipalOwnerId":"11***","AuthPrincipalType":"AssumedRoleUser","NoPermissionType":"ImplicitDeny","PolicyType":"ResourceGroupLevelIdentityBasedPolicy"},"code":"StatusForbidden","message":"STSToken policy Forbidden for action cs:DescribeClustersForRegion","requestId":"E78A2E2D-***","status":403,"statusCode":403}

This confirms that RRSA is enforcing permissions at the pod level.

Configure the pod template manually

If you do not want to install ack-pod-identity-webhook, manually add the required environment variables and projected volume to the pod spec:

apiVersion: v1
kind: Pod
metadata:
  name: demo
  namespace: rrsa-demo
spec:
  containers:
  - args:
    - rrsa
    - demo
    env:
    - name: ALIBABA_CLOUD_ROLE_ARN
      value: <role_arn>
    - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN
      value: <oidc_provider_arn>
    - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE
      value: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens/token
    image: registry.cn-hangzhou.aliyuncs.com/acs/ack-ram-tool:1.0.0
    imagePullPolicy: Always
    name: demo
    volumeMounts:
    - mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens
      name: rrsa-oidc-token
      readOnly: true
  restartPolicy: OnFailure
  serviceAccount: demo-sa
  serviceAccountName: demo-sa
  volumes:
  - name: rrsa-oidc-token
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          audience: sts.aliyuncs.com
          expirationSeconds: 3600
          path: token

Replace the placeholder values:

Placeholder Value Where to find it
<role_arn> ARN of the RAM role Roles page in the RAM console
<oidc_provider_arn> ARN of the OIDC provider Security and Auditing section in the cluster details page — see Get the OIDC provider URL and ARN
Important

Set audience to sts.aliyuncs.com. This is the client ID configured in the OIDC identity provider, not the STS endpoint domain used by the SDK.

Set expirationSeconds to a value between 600 and 43200 (seconds). Values above 43200 are capped at 43,200 seconds (12 hours).

After redeploying the application, it reads the OIDC token from the file path in ALIBABA_CLOUD_OIDC_TOKEN_FILE, exchanges it for an STS token using AssumeRoleWithOIDC, and uses the STS token to call cloud service APIs. For the full API reference, see AssumeRoleWithOIDC.

Use an existing RAM role

To use an existing RAM role instead of creating a new one, update the role's trust policy to allow the service account to assume it. For instructions, see Edit the trust policy of a RAM role.

Add a Statement entry with the following structure:

{
  "Action": "sts:AssumeRole",
  "Condition": {
    "StringEquals": {
      "oidc:aud": "sts.aliyuncs.com",
      "oidc:iss": "<oidc_issuer_url>",
      "oidc:sub": "system:serviceaccount:<namespace>:<service_account>"
    }
  },
  "Effect": "Allow",
  "Principal": {
    "Federated": [
      "<oidc_provider_arn>"
    ]
  }
}

Replace the placeholders:

Placeholder Value
<oidc_issuer_url> URL of the cluster's OIDC provider — see Get the OIDC provider URL and ARN
<oidc_provider_arn> ARN of the cluster's OIDC provider — see Get the OIDC provider URL and ARN
<namespace> Namespace of the application
<service_account> Service account used by the application

To automate trust policy updates, use ack-ram-tool:

ack-ram-tool rrsa associate-role --cluster-id <cluster_id> \
    --namespace <namespace> --service-account <service_account> \
    --role-name <role_name> --create-role-if-not-exist

SDK support

Alibaba Cloud SDK V2.0 supports RRSA OIDC token authentication. All cloud service SDKs that support STS token authentication and are built on Alibaba Cloud SDK V2.0 support RRSA automatically.

Supported SDK versions and demos

Language Minimum version Demo
Go Alibaba Cloud Credentials for Go 1.2.6 Go SDK demo
Java Alibaba Cloud Credentials for Java 0.2.10 Java SDK demo
Python 3 Alibaba Cloud Credentials for Python 0.3.1 Python SDK demo
Node.js / TypeScript Alibaba Cloud Credentials for TypeScript/Node.js 2.2.6 Node.js SDK demo

For the authentication method reference ("Method 6: Use the RAM role of an OIDC IdP"), see the credentials documentation for each language.

Cloud-service-specific SDK demos

Some cloud service SDKs have their own OIDC token support. The following demos show how to use RRSA with those SDKs:

Cloud service SDK Demo
Object Storage Service (OSS) OSS Go SDK — Method 5: Use OIDCRoleARN Go demo
OSS OSS Java SDK — Configure access credentials Java demo
OSS OSS Python SDK — Use the role of an OIDC IdP Python demo
Simple Log Service Simple Log Service SDK for Java Java demo

Enable RRSA authentication for CLIs

Use ack-ram-tool to configure commonly used CLIs so they can authenticate using RRSA OIDC tokens from within a pod.

Alibaba Cloud CLI

Alibaba Cloud CLI v3.0.206 and later support RRSA. Set region_id to your target region.

Option A: Configuration file. Set mode to OIDC in ~/.aliyun/config.json:

{
  "current": "rrsa",
  "profiles": [
    {
      "name": "rrsa",
      "mode": "OIDC",
      "region_id": "cn-hangzhou",
      "ram_session_name": "test-rrsa"
    }
  ],
  "meta_path": ""
}

Option B: Direct command (no configuration file required):

aliyun sts GetCallerIdentity --region cn-hangzhou --role-session-name=test-rrsa

Expected output:

{
  "AccountId": "11380***",
  "Arn": "acs:ram::1138***:assumed-role/test-rrsa-***/test-rrsa",
  "IdentityType": "AssumedRoleUser",
  "PrincipalId": "33300***:test-rrsa",
  "RequestId": "20F78881-F47E-5771-90D6-***",
  "RoleId": "33300***"
}

For credential type details, see Credential types.

ossutil 2.0

ossutil V2.1.0 and later support RRSA. Replace region with your actual region.

Set mode to oidcRoleArn in ~/.ossutilconfig:

cat <<EOF > ~/.ossutilconfig
[default]
mode = oidcRoleArn
OIDCProviderArn = "${ALIBABA_CLOUD_OIDC_PROVIDER_ARN}"
OIDCTokenFilePath = "${ALIBABA_CLOUD_OIDC_TOKEN_FILE}"
roleArn = "${ALIBABA_CLOUD_ROLE_ARN}"
roleSessionName = test-rrsa
region = cn-hangzhou
EOF

For configuration examples, see Examples in the ossutil 2.0 documentation.

Simple Log Service CLI

Simple Log Service CLI does not support OIDC configuration files. Use ack-ram-tool to inject credentials at runtime:

ack-ram-tool export-credentials -f environment-variables -- aliyunlog log list_project --region-endpoint=cn-hangzhou.log.aliyuncs.com

Terraform

Alibaba Cloud Provider V1.222.0 and later support assume_role_with_oidc. Set region to your target region.

Add assume_role_with_oidc to your provider configuration:

provider "alicloud" {
  assume_role_with_oidc {
    role_session_name = "terraform-with-rrsa-auth-example"
  }
  region = "cn-hangzhou"
}

For complete examples, see Terraform RRSA demo.

Troubleshooting

SDK errors

Error Cause Fix
AuthenticationFail.OIDCToken.Expired — "This JsonWebToken is expired." The application cached the OIDC token and is using an expired copy. Read the token from the file (ALIBABA_CLOUD_OIDC_TOKEN_FILE) each time you authenticate. Use an Alibaba Cloud SDK to handle this automatically — see SDK support.
Throttling.User — "Request was denied due to user flow control." The application is calling AssumeRoleWithOIDC too frequently. Reuse the STS token until it expires. Do not re-fetch a token before the current one expires. Use an Alibaba Cloud SDK to manage token lifecycle automatically — see SDK support.
AuthenticationFail.OIDCToken.AudienceNotMatch — "Invalid audience." The audience parameter in the pod spec is not set to sts.aliyuncs.com. Set audience: sts.aliyuncs.com in the projected volume source of the pod spec.
AuthenticationFail.OIDCToken.IssuerConfigurationBroken / IssuerNotMatch / AuthenticationFail.NoPermission — "No such OIDC Provider registered." RRSA is not enabled for the cluster. Enable RRSA for the cluster — see Enable RRSA. After enabling, recreate any pods that use RRSA.
EntityNotExist.Role — "The role not exists: acs:ram::..." The RAM role assumed by the application does not exist. Create the RAM role — see Create a RAM role for an OIDC IdP and Step 2: Create a RAM role for the OIDC identity provider.
AuthenticationFail.NoPermission — "There is no permission" The RAM role does not have a trust policy that allows the service account to assume it. Update the trust policy — see Use an existing RAM role.

Next steps