Upbound AWS Provider Authentication with EKS Pod Identity¶
Authenticate Crossplane's Upbound AWS provider pods against AWS using EKS Pod Identity Agent — no static credentials required.
Prerequisites¶
- EKS cluster with the Pod Identity Agent addon installed
- Crossplane installed in the cluster
- Upbound AWS provider family packages to install
IAM Role¶
Create an IAM role (e.g. crossplane-provider-aws) with the following trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEksAuthToAssumeRoleForPodIdentity",
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
Attach a permission policy scoped to the AWS actions your provider family packages require. Example for S3 and EC2:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
"ec2:*"
],
"Resource": "*"
}
]
}
Scope permissions to only the actions and resources your providers actually manage.
EKS Pod Identity Association¶
In the EKS cluster's Access tab, create a Pod Identity association:
- IAM role:
crossplane-provider-aws - Namespace:
crossplane-system - Service account:
provider-aws(must matchserviceAccountTemplate.metadata.namebelow)
Crossplane Configuration¶
Apply the following three resources:
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
name: provider-aws-runtime-config
spec:
serviceAccountTemplate:
metadata:
name: provider-aws
---
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-aws-s3
spec:
package: xpkg.upbound.io/upbound/provider-aws-s3:v2.4.0
runtimeConfigRef:
name: provider-aws-runtime-config
---
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: PodIdentity
For multiple provider family packages (e.g.
provider-aws-ec2,provider-aws-rds), eachProviderresource must reference the sameruntimeConfigRef.
Verification¶
Check provider health with kubectl get providers && kubectl get providerconfig.
Verify end-to-end by creating a managed resource and confirming it reconciles
in AWS — no static credentials should be present in the cluster.
Managed Resources in Other Namespaces¶
In Crossplane v2, managed resources and ProviderConfig are namespace-scoped
(they were cluster-scoped in v1.x). For the full v1-to-v2 migration context, see
Upgrading Crossplane from v1 to v2.
How Authentication Works¶
EKS Pod Identity operates at the pod level, not the namespace level. The Pod
Identity Agent injects short-lived AWS credentials into the provider pod via
environment variables (AWS_CONTAINER_CREDENTIALS_FULL_URI,
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE). The provider pod holds a ClusterRole
allowing it to reconcile managed resources across all namespaces — AWS auth is
entirely a concern of the pod in crossplane-system.
ProviderConfig with source: PodIdentity is a configuration pointer, not a
credential store. In Crossplane v2, the controller looks up the ProviderConfig
in the same namespace as the managed resource — a ProviderConfig in
crossplane-system is invisible to resources in other namespaces, hence the need
to copy it.
Deploying to Another Namespace¶
Copy the ProviderConfig into every namespace that will contain managed resources.
No additional IAM roles, Pod Identity Associations, ServiceAccounts, or RBAC are
required — the actual credential exchange still happens entirely within the provider
pod in crossplane-system:
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
namespace: my-namespace
spec:
credentials:
source: PodIdentity