Configuring OIDC with Amazon Web Services

Use OpenID Connect within your tasks to authenticate with Amazon Web Services.
OpenID Connect (OIDC) allows your tasks to access resources in Amazon Web Services (AWS) without needing to store the credentials. This enables a seamless and safe interaction between your tasks and the cloud services they rely on.
This guide will walk you through how to configure AWS to trust Airplane's OIDC. See Airplane OpenID Connect provider for an overview of how to generate tokens and the token format.

Add Airplane as an identity provider to AWS

To add the Airplane OIDC provider to IAM, see the AWS documentation on Creating OpenID Connect (OIDC) identity providers. Use the following configuration:
  • Provider URL: https://api.airplane.dev
  • Audience: Set the audience you are setting when generating the OIDC token. For example, if you are generating in a JST as {{auth.idToken('sts.amazonaws.com')}}, set the audience in your AWS configuration to sts.amazonaws.com.
For an example Terraform configuration, see the Advanced section below.

Configure a role and trust policy

Next, create an IAM role that can be assumed by Airplane tasks via web identity.
To configure the role, see the AWS documentation for creating a role for web identity. Airplane's OIDC token can be used to obtain temporary credentials using AWS Security Token Service.
Be sure to edit the trust policy to add the sub field to the validation conditions. Doing so will ensure that tokens from other Airplane teams or tasks cannot be used to access your cloud resources. The subject is formatted as team:{$team_id}:env:{$env_slug}:task:{$task_slug}. For example:
json
Copied
1
"Condition": {
2
"StringEquals": {
3
"api.airplane.dev:aud": "sts.amazonaws.com",
4
"api.airplane.dev:sub": "team:tea20010101aaaaaaaaaa:env:prod:task:add_s3_bucket_tag"
5
}
6
}
StringLike can be used with a wildcard operator (*) to allow any tasks in your team to assume the role. For example:
json
Copied
1
"Condition": {
2
"StringEquals": {
3
"api.airplane.dev:aud": "sts.amazonaws.com"
4
},
5
"StringLike": {
6
"api.airplane.dev:sub": "team:tea20010101aaaaaaaaaa:*"
7
}
8
}
You can find your team ID under Team settings.

Generate a token with the Airplane SDK to assume an AWS role

Now that AWS is configured to accept Airplane OIDC tokens, you can generate a token from within an Airplane task.
typescript
Copied
1
import { STSClient } from "@aws-sdk/client-sts";
2
import { AssumeRoleWithWebIdentityCommand } from "@aws-sdk/client-sts";
3
import airplane from "airplane";
4
5
const getAWSCredentials = async () => {
6
const client = new STSClient({ region: "us-east-1" });
7
8
const token = await airplane.auth.idToken("sts.amazonaws.com");
9
10
const response = await client.send(
11
new AssumeRoleWithWebIdentityCommand({
12
RoleArn: "arn:aws:iam::000000000000:role/my_aws_role",
13
WebIdentityToken: token,
14
RoleSessionName: "my_session",
15
})
16
);
17
return response.Credentials;
18
};

Use the token to make an AWS API call

You can now use the generated AWS credentials to initiate an AWS client like you normally would.
typescript
Copied
1
import { S3Client, PutBucketTaggingCommand } from "@aws-sdk/client-s3";
2
import { STSClient, AssumeRoleWithWebIdentityCommand } from "@aws-sdk/client-sts";
3
import airplane from "airplane";
4
5
export default airplane.task(
6
{
7
slug: "add_s3_bucket_tag",
8
},
9
async (params) => {
10
const credentials = await getAWSCredentials();
11
12
const client = new S3Client({
13
region: "us-east-1",
14
credentials: {
15
accessKeyId: credentials.AccessKeyId,
16
secretAccessKey: credentials.SecretAccessKey,
17
sessionToken: credentials.SessionToken,
18
},
19
});
20
21
const putBucketTaggingCommand = new PutBucketTaggingCommand({
22
Bucket: "your-bucket-name",
23
Tagging: {
24
TagSet: [
25
{
26
Key: "example-key",
27
Value: "example-value",
28
},
29
],
30
},
31
});
32
33
const response = await client.send(putBucketTaggingCommand);
34
35
console.log("Successfully added tag to bucket:", response);
36
}
37
);
38
39
const getAWSCredentials = async () => {
40
const client = new STSClient({ region: "us-east-1" });
41
42
const token = await airplane.auth.idToken("sts.amazonaws.com");
43
44
const response = await client.send(
45
new AssumeRoleWithWebIdentityCommand({
46
RoleArn: "arn:aws:iam::000000000000:role/my_aws_role",
47
WebIdentityToken: token,
48
RoleSessionName: "my_session",
49
})
50
);
51
return response.Credentials;
52
};

Advanced

Managing the OIDC provider using Infrastructure as Code

You can use Infrastructure as Code tools like Terraform to manage the IAM OIDC provider in your AWS account. To add Airplane as an OIDC provider, you will need to specify a thumbprint, which can be obtained by following these instructions.
This Terraform example uses the current thumbprint, which is subject to change.
hcl
Copied
1
resource "aws_iam_openid_connect_provider" "airplane" {
2
url = "https://api.airplane.dev"
3
4
client_id_list = [
5
"sts.amazonaws.com",
6
]
7
8
thumbprint_list = ["08745487E891C19E3078C1F2A07E452950EF36F6"]
9
}