Primary Mechanism: Workload Identity (IRSA)
IAM Roles for Service Accounts (IRSA) is the cloud-native standard for granting AWS permissions to Kubernetes pods. The Helm chart creates a ServiceAccount annotated with an AWS IAM Role ARN. Kubernetes automatically provides a token that the pod’s AWS SDK exchanges for credentials.
How It Works
1. Onyxia injects IRSA configuration via region.customValues
↓
Helm chart receives: serviceAccount.annotations.eks.amazonaws.com/role-arn
↓
2. Chart creates ServiceAccount with IRSA annotation
↓
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT:role/handbook-reader
↓
3. Kubernetes IRSA webhook injects OIDC token into pod
↓
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
AWS_ROLE_ARN=arn:aws:iam::ACCOUNT:role/handbook-reader
↓
4. AWS SDK automatically detects IRSA environment
↓
Calls: sts:AssumeRoleWithWebIdentity (no frontend involved)
↓
5. Pod receives auto-refreshing AWS credentials
↓
R/Python libraries use them automatically
Benefits
- Portable: Works on any Kubernetes cluster with OIDC (EKS, GKE, AKS, self-hosted)
- Auto-refresh: AWS SDK handles credential rotation automatically
- Decoupled: Chart doesn’t depend on Onyxia-specific features
- Secure: Short-lived tokens, never stored in config
- Standard: Uses official AWS SDK credential chain
Infrastructure Setup (One-Time)
1. Enable OIDC provider for EKS cluster:
eksctl utils associate-iam-oidc-provider --cluster=my-cluster --approve2. Create IAM role for handbook readers:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::142496269814:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/YOUR_CLUSTER_ID"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"oidc.eks.us-west-2.amazonaws.com/id/YOUR_CLUSTER_ID:sub": "system:serviceaccount:user-*:*"
}
}
}
]
}Or use eksctl (recommended):
eksctl create iamserviceaccount \
--name handbook-reader \
--namespace default \
--cluster my-cluster \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve3. Attach S3 access policy to role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::sentinel-s2-l2a",
"arn:aws:s3:::sentinel-s2-l2a/*",
"arn:aws:s3:::usgs-landsat",
"arn:aws:s3:::usgs-landsat/*"
]
}
]
}4. Configure Onyxia region with IRSA (via region.customValues):
# In Onyxia Helm values or platform configuration
regions:
- id: "jakarta"
name: "Jakarta"
services:
customValues:
# IRSA configuration injected into all Helm charts
serviceAccount:
create: true
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::142496269814:role/handbook-reader"
aws:
region: "us-west-2"
defaultConfiguration:
ipprotection: true # Enable IP-based access control by default
networkPolicy: true # Enable Kubernetes NetworkPolicy by defaultThe region.customValues configuration is automatically injected into Helm chart values when services are deployed via Onyxia. This allows region-wide defaults like ServiceAccount annotations for IRSA/Workload Identity to be applied consistently across all deployed services.
Note on region.customValues: While fully implemented in Onyxia’s codebase, this feature is not yet documented in the official Onyxia region configuration documentation. The implementation allows arbitrary key-value pairs to be injected into all Helm charts via onyxia.region.customValues. Charts can access these values using the standard x-onyxia schema pattern:
{
"serviceAccount": {
"annotations": {
"x-onyxia": {
"overwriteDefaultWith": "region.customValues.serviceAccount.annotations"
}
}
}
}