Workload Identity Federation
What is Workload Identity Federation?
Section titled “What is Workload Identity Federation?”Workload Identity Federation (WIF) lets Baponi access your cloud storage buckets without storing any secrets. Instead of sharing service account keys or access credentials, Baponi’s cluster proves its identity to your cloud provider using short-lived OIDC tokens. Your cloud verifies the token and grants scoped access — no keys to rotate, no secrets to store. The trust is cross-project (GCP) or cross-account (AWS), so your data stays in your environment while Baponi gets the minimum access it needs.
Prerequisites
Section titled “Prerequisites”- A Baponi account with admin access
- GCP: A project with a GCS bucket and the
gcloudCLI installed - AWS: An account with an S3 bucket and the
awsCLI installed
-
Get Baponi’s cluster identity
In the Baponi console, go to Settings > WIF Configuration. Note the OIDC issuer URL and audience values. You will use these in the next steps.
-
Create a Workload Identity Pool
Terminal window gcloud iam workload-identity-pools create baponi-pool \--location="global" \--display-name="Baponi Code Execution" -
Add Baponi as a trusted OIDC provider
Replace
OIDC_ISSUER_URLandAUDIENCEwith the values from step 1.Terminal window gcloud iam workload-identity-pools providers create-oidc baponi-provider \--workload-identity-pool="baponi-pool" \--location="global" \--issuer-uri="OIDC_ISSUER_URL" \--allowed-audiences="AUDIENCE" \--attribute-mapping="google.subject=assertion.sub" -
Create a service account for Baponi
Terminal window gcloud iam service-accounts create baponi-storage \--display-name="Baponi Storage Access" -
Grant the service account access to your bucket
Replace
YOUR_BUCKETwith your GCS bucket name.Terminal window gcloud storage buckets add-iam-policy-binding gs://YOUR_BUCKET \--member="serviceAccount:baponi-storage@YOUR_PROJECT.iam.gserviceaccount.com" \--role="roles/storage.objectUser" -
Allow Baponi to impersonate the service account
Replace
YOUR_PROJECT,YOUR_PROJECT_NUMBER,YOUR_NAMESPACE, andYOUR_SERVICE_ACCOUNTwith your values. For Baponi Cloud, usebaponifor both namespace and service account. For self-hosted deployments, check the namespace and service account name from your Helm release:kubectl get sa -n <namespace>.Terminal window gcloud iam service-accounts add-iam-policy-binding \baponi-storage@YOUR_PROJECT.iam.gserviceaccount.com \--role="roles/iam.workloadIdentityUser" \--member="principalSet://iam.googleapis.com/projects/YOUR_PROJECT_NUMBER/locations/global/workloadIdentityPools/baponi-pool/attribute.sub/system:serviceaccount:YOUR_NAMESPACE:YOUR_SERVICE_ACCOUNT" -
Configure in Baponi
Go to Storage Connections, click New Connection, select GCS, choose Cross-Account WIF, and enter the pool provider resource name and service account email.
-
Get Baponi’s cluster identity
In the Baponi console, go to Settings > WIF Configuration. Note the OIDC issuer URL and audience values. You will use these in the next steps.
-
Create an OIDC identity provider in AWS
Replace
OIDC_ISSUER_URLandAUDIENCEwith your values. Get the OIDC issuer’s TLS thumbprint first:Terminal window # Extract the TLS certificate thumbprint from the OIDC issuerISSUER_HOST=$(echo "OIDC_ISSUER_URL" | sed 's|https://||')THUMBPRINT=$(echo | openssl s_client -servername "$ISSUER_HOST" \-showcerts -connect "$ISSUER_HOST:443" 2>/dev/null \| openssl x509 -fingerprint -sha1 -noout \| sed 's/://g' | cut -d= -f2)echo "$THUMBPRINT"Then create the OIDC provider:
Terminal window aws iam create-open-id-connect-provider \--url "OIDC_ISSUER_URL" \--client-id-list "AUDIENCE" \--thumbprint-list "$THUMBPRINT" -
Create an IAM role with a trust policy
Create a file called
trust-policy.jsonwith the following content. ReplaceYOUR_ACCOUNT_ID,OIDC_ISSUER_HOST, andAUDIENCEwith your values.{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Federated": "arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/OIDC_ISSUER_HOST"},"Action": "sts:AssumeRoleWithWebIdentity","Condition": {"StringEquals": {"OIDC_ISSUER_HOST:aud": "AUDIENCE","OIDC_ISSUER_HOST:sub": "system:serviceaccount:YOUR_NAMESPACE:YOUR_SERVICE_ACCOUNT"}}}]}Then create the role:
Terminal window aws iam create-role \--role-name baponi-storage-access \--assume-role-policy-document file://trust-policy.json -
Attach S3 access policy
Replace
YOUR_BUCKETwith your S3 bucket name.Terminal window aws iam put-role-policy \--role-name baponi-storage-access \--policy-name BaponiS3Access \--policy-document '{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": ["s3:GetObject","s3:PutObject","s3:ListBucket","s3:DeleteObject"],"Resource": ["arn:aws:s3:::YOUR_BUCKET","arn:aws:s3:::YOUR_BUCKET/*"]}]}' -
Configure in Baponi
Go to Storage Connections, click New Connection, select AWS S3, choose Cross-Account WIF, and enter the IAM Role ARN.
Verify the Connection
Section titled “Verify the Connection”Run a quick test to confirm the connection works. Execute code in a Baponi sandbox that reads from or writes to your bucket:
import os
# List files in the mounted storagefiles = os.listdir("/data")print(f"Connected. Found {len(files)} files in /data")
# Write a test filewith open("/data/wif-test.txt", "w") as f: f.write("WIF connection verified.")
print("Write succeeded.")If the execution completes without errors, WIF is configured correctly.
Troubleshooting
Section titled “Troubleshooting”How long do tokens last? Default 1 hour. Kubernetes automatically rotates tokens at 80% of expiry — no manual renewal needed.
How do I revoke access? Delete the WIF pool provider (GCP) or remove the OIDC identity provider trust (AWS). Access is revoked immediately.
What information does Baponi store? Only the WIF pool provider resource name (GCP) or IAM Role ARN (AWS). No secrets, no keys, no credentials.
Can I audit token usage? Yes. GCP Cloud Audit Logs and AWS CloudTrail both log STS token exchanges, giving you full visibility into when and how tokens are used.