- 05 Nov 2026
- Print
- DarkLight
How to Configure OIDC Workload Identity
- Updated on 05 Nov 2026
- Print
- DarkLight
This guide registers an OIDC provider, creates a trusted IAM role, exchanges a JWT, and uses the resulting credentials with Backblaze B2 Cloud Storage.
Prerequisites
Before you begin, you must have the following items:
A Backblaze account with IAM enabled.
IAM credentials authorized to manage OIDC providers, roles, and role policies.
An OIDC provider that meets the compatibility requirements.
A representative JWT issued to the intended workload.
AWS CLI with
jqavailable for handling responses.A Backblaze B2 bucket for the verification request.
1. Inspect the token
A representative decoded JWT payload is:
{
"iss": "https://issuer.example.com",
"aud": "backblaze-workload",
"sub": "workload:production:reader",
"iat": 1793300400,
"exp": 1793304000
}Record:
iss: provider issuer URL.Effective audience:
azpwhen present; otherwise the singleaud.sub: stable workload identifier.
Do not register values taken from an untrusted or unrelated token.
2. Register the provider
export AWS_ACCESS_KEY_ID="<administrator-access-key>"
export AWS_SECRET_ACCESS_KEY="<administrator-secret-key>"
export AWS_REGION="us-west-002"aws iam create-open-id-connect-provider \
--endpoint-url https://iam.backblazeb2.com \
--url https://issuer.example.com \
--client-id-list backblaze-workloadThumbprintList is optional. When omitted, Backblaze connects to the provider and derives a certificate thumbprint.
Response:
{
"OpenIDConnectProviderArn": "arn:aws:iam::123456789012:oidc-provider/issuer.example.com"
}Register each distinct issuer separately.
3. Create the role trust policy
Save as trust-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/issuer.example.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"issuer.example.com:aud": "backblaze-workload",
"issuer.example.com:sub": "workload:production:reader"
}
}
}
]
}Create the role:
aws iam create-role \
--endpoint-url https://iam.backblazeb2.com \
--role-name WorkloadReadOnly \
--max-session-duration 3600 \
--assume-role-policy-document file://trust-policy.jsonUse exact subjects when practical. StringLike supports case-sensitive * and ?, but broad patterns can authorize unintended workloads.
4. Attach role permissions
Save as role-permissions.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::example-data-bucket"
},
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-data-bucket/*"
}
]
}aws iam put-role-policy \
--endpoint-url https://iam.backblazeb2.com \
--role-name WorkloadReadOnly \
--policy-name ReadExampleBucket \
--policy-document file://role-permissions.json5. Exchange the JWT
aws sts assume-role-with-web-identity \
--endpoint-url https://sts.backblazeb2.com \
--no-sign-request \
--role-arn arn:aws:iam::123456789012:role/WorkloadReadOnly \
--role-session-name production-reader \
--web-identity-token file:///var/run/secrets/oidc/token \
--duration-seconds 3600The JWT authenticates this request. Do not provide an IAM authorization header.
Successful response:
{
"Audience": "backblaze-workload",
"Provider": "arn:aws:iam::123456789012:oidc-provider/issuer.example.com",
"SubjectFromWebIdentityToken": "workload:production:reader",
"AssumedRoleUser": {
"Arn": "arn:aws:sts::123456789012:assumed-role/WorkloadReadOnly/production-reader"
},
"Credentials": {
"AccessKeyId": "<temporary-access-key>",
"SecretAccessKey": "<temporary-secret-key>",
"SessionToken": "<temporary-session-token>",
"Expiration": "2026-10-29T23:00:00Z"
}
}The access key, secret key, and session token are all required.
6. Use the temporary credentials
export AWS_ACCESS_KEY_ID="<temporary-access-key>"
export AWS_SECRET_ACCESS_KEY="<temporary-secret-key>"
export AWS_SESSION_TOKEN="<temporary-session-token>"
export AWS_REGION="us-west-002"aws s3api list-objects-v2 \
--endpoint-url https://s3.us-west-002.backblazeb2.com \
--bucket example-data-bucketThis request is authorized by the role permission policy, not the role trust policy.
Runtime endpoints
Endpoint | When called | Purpose |
|---|---|---|
| Every exchange | Exchange the JWT for credentials |
| Discovery-cache miss | Locate |
| Key-cache miss or unknown | Obtain JWT verification keys |
Regional B2 S3 endpoint | After exchange | Perform authorized storage operations |
Backblaze does not call the public IAM endpoint or the provider’s token endpoint during the exchange.
Authorization decision
Credentials are returned only when:
JWT signature and required claims are valid
AND issuer identifies a registered provider
AND effective audience is registered
AND provider ARN matches Principal.Federated
AND the trust policy allows sts:AssumeRoleWithWebIdentity
AND all trust conditions match
AND no applicable explicit Deny existsTroubleshooting
Token exchange fails
Check:
The token is a signed JWT rather than an OAuth access token.
The discovery document and JWKS are publicly reachable.
issexactly matches a registered provider.The effective audience is registered.
exp,iat, and optionalnbfare valid.The JWT
kidappears in the current JWKS.The provider ARN matches
Principal.Federated.The trust-policy subject and other conditions match.
Exchange succeeds but S3 returns AccessDenied
Check:
The role permission policy allows the requested S3 action.
Bucket and object ARNs are correct.
The regional S3 endpoint is correct.
AWS_SESSION_TOKENis set.No applicable policy contains an explicit
Deny.
Never log the JWT, temporary secret access key, or session token.