Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Roles for our pathogen-repo-build GitHub Actions workflow, take 2 #7

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions env/production/aws-cognito-identity.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# XXX FIXME: describe what we're doing here
# <https://catnekaise.github.io/github-actions-abac-aws/cognito-identity/>
# <https://catnekaise.github.io/github-actions-abac-aws/detailed-explanation/>
# <https://awsteele.com/blog/2023/10/25/aws-role-session-tags-for-github-actions.html>
resource "aws_cognito_identity_pool" "github-actions" {
identity_pool_name = "github-actions"
allow_unauthenticated_identities = false
allow_classic_flow = true
openid_connect_provider_arns = [aws_iam_openid_connect_provider.github-actions.arn]
}

resource "aws_cognito_identity_pool_provider_principal_tag" "github-actions" {
identity_pool_id = aws_cognito_identity_pool.github-actions.id
identity_provider_name = aws_iam_openid_connect_provider.github-actions.id
use_defaults = false
principal_tags = {
# tag name = OIDC token claim
repository_owner = "repository_owner"
repository = "repository"
job_workflow_ref = "job_workflow_ref"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,36 @@ resource "aws_iam_role" "GitHubActionsRoleNextstrainBatchJobs" {
{
"Effect": "Allow",
"Principal": {
"Federated": aws_iam_openid_connect_provider.github-actions.arn
}
"Action": "sts:AssumeRoleWithWebIdentity",
"Federated": "cognito-identity.amazonaws.com"
},
"Action": [
"sts:AssumeRoleWithWebIdentity",
"sts:TagSession",
],
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": aws_cognito_identity_pool.github-actions.id,
"aws:RequestTag/repository_owner": "nextstrain",
"aws:RequestTag/respository": [
"nextstrain/$${sts:RoleSessionName}",
"nextstrain/$${sts:RoleSessionName}-ingest", # for ncov and ncov-ingest
],
},
"StringLike": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:nextstrain/.github:*"
}
"aws:RequestTag/job_workflow_ref": "nextstrain/.github/.github/workflows/pathogen-repo-build.yaml@*",
},
"ForAllValues:StringLike": {
"cognito-identity.amazonaws.com:amr": [
"authenticated",
"token.actions.githubusercontent.com",
"${aws_iam_openid_connect_provider.github-actions.arn}:*",
],
},
# Ensures that a missing/empty amr claim doesn't pass the
# ForAllValues condition above.
"Null": {
"cognito-identity.amazonaws.com:amr": "false",
},
},
}
]
Expand Down
143 changes: 143 additions & 0 deletions env/production/aws-iam-role-GitHubActionsRoleNextstrainBuilds.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
resource "aws_iam_role" "GitHubActionsRoleNextstrainBuilds" {
name = "GitHubActionsRoleNextstrainBuilds"
description = "Provides permissions for a Nextstrain build (i.e. in a pathogen repo) to upload datasets, workflow files, etc. for select GitHub Actions OIDC workflows."

max_session_duration = 43200 # seconds (12 hours)

assume_role_policy = aws_iam_role.GitHubActionsRoleNextstrainBatchJobs.assume_role_policy

# This role provides a superset of the permissions expected to actually be
# required by any individual Nextstrain pathogen build. In practice, we
# further scope down permissions per-repo using an inline session policy
# declared in our centralized and trusted pathogen-repo-build workflow. The
# inline session policy is obviously less of a hard boundary, but it still
# provides guardrails against accidental operations. See also the discussion
# in <https://github.com/nextstrain/private/issues/96>.
# -trs, 15 May 2024
managed_policy_arns = [
# Builds inside the AWS Batch runtime need access to the jobs bucket.
aws_iam_policy.NextstrainJobsAccessToBucket.arn,
]

# All builds need a subset of this access for downloading starting data and
# publishing results.
inline_policy {
name = "S3Access"
policy = jsonencode({
"Version": "2012-10-17",
"Statement": [
# Technically we don't need to include the public buckets
# nextstrain-data and nextstrain-staging in this statement since they
# already allow a superset of this with their bucket policies, but it's
# good to be explicit about what permissions we require.
# -trs, 16 Feb 2024
{
"Sid": "List",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketLocation",
"s3:GetBucketVersioning",
],
"Resource": [
"arn:aws:s3:::nextstrain-data",
"arn:aws:s3:::nextstrain-data-private",
"arn:aws:s3:::nextstrain-staging",
],
"Condition": {
"StringLike": {
"s3:prefix": [
"$${sts:RoleSessionName}.json",
"$${sts:RoleSessionName}_*.json",
"files/workflows/$${sts:RoleSessionName}/*",
"files/datasets/$${sts:RoleSessionName}/*",
]
}
}
},
{
"Sid": "ReadWrite",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectTagging",
"s3:GetObjectVersion",
"s3:GetObjectVersionTagging",
"s3:PutObject",
"s3:PutObjectTagging",
"s3:DeleteObject",
# but NOT s3:DeleteObjectVersion so objects can't be completely wiped
],
"Resource": [
# Auspice dataset JSONs
"arn:aws:s3:::nextstrain-data/$${sts:RoleSessionName}.json",
"arn:aws:s3:::nextstrain-data/$${sts:RoleSessionName}_*.json",
"arn:aws:s3:::nextstrain-staging/$${sts:RoleSessionName}.json",
"arn:aws:s3:::nextstrain-staging/$${sts:RoleSessionName}_*.json",
"arn:aws:s3:::nextstrain-staging/trial_*_$${sts:RoleSessionName}.json",
"arn:aws:s3:::nextstrain-staging/trial_*_$${sts:RoleSessionName}_*.json",

# Associated data files
# <https://docs.nextstrain.org/en/latest/reference/data-files.html>
"arn:aws:s3:::nextstrain-data/files/workflows/$${sts:RoleSessionName}/*",
"arn:aws:s3:::nextstrain-data/files/datasets/$${sts:RoleSessionName}/*",
"arn:aws:s3:::nextstrain-data-private/files/workflows/$${sts:RoleSessionName}/*",
"arn:aws:s3:::nextstrain-data-private/files/datasets/$${sts:RoleSessionName}/*",
"arn:aws:s3:::nextstrain-staging/files/workflows/$${sts:RoleSessionName}/*",
"arn:aws:s3:::nextstrain-staging/files/datasets/$${sts:RoleSessionName}/*",
],
},
{
"Sid": "NcovPrivateList",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketLocation",
"s3:GetBucketVersioning",
],
"Resource": [
"arn:aws:s3:::nextstrain-ncov-private",
],
"Condition": {
"StringEquals": {
"aws:PrincipalTag/repository": [
"nextstrain/ncov",
"nextstrain/ncov-ingest",
# XXX TODO: forecasts-ncov?
],
},
}
},
{
"Sid": "NcovPrivateReadWrite",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectTagging",
"s3:GetObjectVersion",
"s3:GetObjectVersionTagging",
"s3:PutObject",
"s3:PutObjectTagging",
"s3:DeleteObject",
# but NOT s3:DeleteObjectVersion so objects can't be completely wiped
],
"Resource": [
# This bucket is akin to nextstrain-data-private/files/{workflows,datasets}/ncov/.
"arn:aws:s3:::nextstrain-ncov-private/*",
],
"Condition": {
"StringEquals": {
"aws:PrincipalTag/repository": [
"nextstrain/ncov",
"nextstrain/ncov-ingest",
# XXX TODO: forecasts-ncov?
]
},
},
},
]
})
}
}