Skip to content

OIDC with AWS

In IAM, add an OpenID Connect provider with your Slipway base URL as the provider URL and sts.amazonaws.com as the audience.

Terminal window
aws iam create-open-id-connect-provider \
--url https://slipway.example.com \
--client-id-list sts.amazonaws.com

2. Create a role with a tight trust policy

Section titled “2. Create a role with a tight trust policy”
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/slipway.example.com" },
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"slipway.example.com:aud": "sts.amazonaws.com",
"slipway.example.com:sub": "<exact sub from a test job>"
}
}
}]
}

Print a real token’s sub from a test job (see OIDC job tokens) and match it exactly, or use StringLike with a pattern that includes your org, project and environment. Attach only the permissions the job needs (for example ECS deploy, ECR read).

permissions: { id_token: write }
jobs:
- name: deploy
environment: { name: production, service: api }
steps:
- name: Assume role
run: |
creds=$(aws sts assume-role-with-web-identity \
--role-arn arn:aws:iam::123456789012:role/slipway-deploy \
--role-session-name "slipway-deploy" \
--web-identity-token "$SLIPWAY_ID_TOKEN" \
--duration-seconds 900 \
--query Credentials --output json)
echo "::mask::$(echo "$creds" | jq -r .SecretAccessKey)"
echo "::mask::$(echo "$creds" | jq -r .SessionToken)"
echo "AWS_ACCESS_KEY_ID=$(echo "$creds" | jq -r .AccessKeyId)" >> "$SLIPWAY_ENV"
echo "AWS_SECRET_ACCESS_KEY=$(echo "$creds" | jq -r .SecretAccessKey)" >> "$SLIPWAY_ENV"
echo "AWS_SESSION_TOKEN=$(echo "$creds" | jq -r .SessionToken)" >> "$SLIPWAY_ENV"
- run: aws ecs update-service --cluster prod --service api --force-new-deployment

Alternatively write the token to a file and let the AWS SDK do the exchange:

- run: |
umask 077
printf %s "$SLIPWAY_ID_TOKEN" > /tmp/slipway-id-token
echo "AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/slipway-id-token" >> "$SLIPWAY_ENV"
echo "AWS_ROLE_ARN=arn:aws:iam::123456789012:role/slipway-deploy" >> "$SLIPWAY_ENV"

For Slipway’s built-in AWS integration (ECS and Lambda deployers, CloudWatch verification) enter the role ARN once and the platform performs the exchange for you.

Error Cause
InvalidIdentityToken: Couldn't retrieve verification key AWS cannot reach https://<base-url>/.well-known/jwks.json
AccessDenied ... not authorized to perform sts:AssumeRoleWithWebIdentity Trust policy sub or aud does not match the token’s claims
Token expired The token lives 15 minutes; exchange it early in the job