Skip to content

Conversation

@gfreeman-navapbc
Copy link
Contributor

🎫 Ticket

https://jira.cms.gov/browse/PLT-1366

🛠 Changes

Adds a policy document for the minimum permissions necessary for the github-actions IAM roles to work with our current workflows.

ℹ️ Context

Before now, we had all of the github-actions roles fully open on our services. This can be unsafe, so we decided to lock-down the permissions now that we have had some time in the Greenfield account to iron out what the necessary permissions are.

🧪 Validation

Tofu Plan Output (bcda-prod-github-actions)
OpenTofu will perform the following actions:

  # aws_iam_role_policy.github_actions_role_policy will be created
  + resource "aws_iam_role_policy" "github_actions_role_policy" {
      + id          = (known after apply)
      + name        = (known after apply)
      + name_prefix = (known after apply)
      + policy      = jsonencode(
            {
              + Statement = [
                  + {
                      + Action   = [
                          + "acm:ListCertificates",
                          + "acm:GetCertificate",
                          + "acm:DescribeCertificate",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "autoscaling:UpdateAutoScalingGroup",
                          + "autoscaling:StartInstanceRefresh",
                          + "autoscaling:PutNotificationConfiguration",
                          + "autoscaling:DescribeScalingActivities",
                          + "autoscaling:DescribePolicies",
                          + "autoscaling:DescribeNotificationConfigurations",
                          + "autoscaling:DescribeAutoScalingGroups",
                          + "autoscaling:DeleteNotificationConfiguration",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "backup:GetBackupSelection",
                          + "backup:GetBackupPlan",
                          + "backup:DescribeBackupVault",
                          + "backup:CreateBackupSelection",
                          + "backup:CreateBackupPlan",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "cloudfront:ListDistributions",
                          + "cloudfront:GetResponseHeadersPolicy",
                          + "cloudfront:GetOriginAccessControl",
                          + "cloudfront:CreateInvalidation",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = "cloudwatch:DescribeAlarms"
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "ec2:RunInstances",
                          + "ec2:RevokeSecurityGroupIngress",
                          + "ec2:RevokeSecurityGroupEgress",
                          + "ec2:ModifyImageAttribute",
                          + "ec2:GetSecurityGroupsForVpc",
                          + "ec2:GetManagedPrefixListEntries",
                          + "ec2:DescribeVpcs",
                          + "ec2:DescribeVpcAttribute",
                          + "ec2:DescribeVolumes",
                          + "ec2:DescribeSecurityGroups",
                          + "ec2:DescribeSecurityGroupRules",
                          + "ec2:DescribeRouteTables",
                          + "ec2:DescribeRegions",
                          + "ec2:DescribeNetworkInterfaces",
                          + "ec2:DescribeNatGateways",
                          + "ec2:DescribeManagedPrefixLists",
                          + "ec2:DescribeInternetGateways",
                          + "ec2:DescribeAvailabilityZones",
                          + "ec2:DescribeAccountAttributes",
                          + "ec2:DeleteSecurityGroup",
                          + "ec2:DeleteKeyPair",
                          + "ec2:CreateSecurityGroup",
                          + "ec2:CreateLaunchTemplateVersion",
                          + "ec2:CreateKeyPair",
                          + "ec2:CreateImage",
                          + "ec2:AuthorizeSecurityGroupIngress",
                          + "ec2:AuthorizeSecurityGroupEgress",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "ecr:UploadLayerPart",
                          + "ecr:PutImage",
                          + "ecr:InitiateLayerUpload",
                          + "ecr:GetAuthorizationToken",
                          + "ecr:DescribeRepositories",
                          + "ecr:DescribeImages",
                          + "ecr:CompleteLayerUpload",
                          + "ecr:BatchCheckLayerAvailability",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "ecs:UpdateService",
                          + "ecs:RegisterTaskDefinition",
                          + "ecs:ListTasks",
                          + "ecs:ListTaskDefinitions",
                          + "ecs:DescribeTasks",
                          + "ecs:DescribeTaskDefinition",
                          + "ecs:DescribeServices",
                          + "ecs:DescribeClusters",
                          + "ecs:DeregisterTaskDefinition",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "elasticache:DescribeReplicationGroups",
                          + "elasticache:DescribeCacheSubnetGroups",
                          + "elasticache:DescribeCacheClusters",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "elasticfilesystem:DescribeMountTargets",
                          + "elasticfilesystem:DescribeMountTargetSecurityGroups",
                          + "elasticfilesystem:DescribeLifecycleConfiguration",
                          + "elasticfilesystem:DescribeFileSystems",
                          + "elasticfilesystem:DescribeAccessPoints",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "elasticloadbalancing:SetSubnets",
                          + "elasticloadbalancing:SetSecurityGroups",
                          + "elasticloadbalancing:ModifyTargetGroup",
                          + "elasticloadbalancing:ModifyRule",
                          + "elasticloadbalancing:ModifyLoadBalancerAttributes",
                          + "elasticloadbalancing:ModifyListener",
                          + "elasticloadbalancing:DescribeTargetGroups",
                          + "elasticloadbalancing:DescribeTargetGroupAttributes",
                          + "elasticloadbalancing:DescribeRules",
                          + "elasticloadbalancing:DescribeLoadBalancers",
                          + "elasticloadbalancing:DescribeLoadBalancerAttributes",
                          + "elasticloadbalancing:DescribeListeners",
                          + "elasticloadbalancing:DescribeListenerAttributes",
                          + "elasticloadbalancing:DescribeCapacityReservation",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "events:PutTargets",
                          + "events:PutRule",
                          + "events:ListTargetsByRule",
                          + "events:DescribeRule",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "kms:ListAliases",
                          + "kms:GetKeyRotationStatus",
                          + "kms:GetKeyPolicy",
                          + "kms:GenerateDataKeyWithoutPlaintext",
                          + "kms:GenerateDataKey",
                          + "kms:Encrypt",
                          + "kms:EnableKeyRotation",
                          + "kms:DescribeKey",
                          + "kms:Decrypt",
                          + "kms:CreateKey",
                          + "kms:CreateGrant",
                          + "kms:CreateAlias",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "firehose:StartDeliveryStreamEncryption",
                          + "firehose:DescribeDeliveryStream",
                          + "firehose:CreateDeliveryStream",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "iam:UpdateOpenIDConnectProviderThumbprint",
                          + "iam:UpdateAssumeRolePolicy",
                          + "iam:PutRolePolicy",
                          + "iam:ListRolePolicies",
                          + "iam:ListPolicyVersions",
                          + "iam:ListPolicies",
                          + "iam:ListOpenIDConnectProviders",
                          + "iam:ListInstanceProfilesForRole",
                          + "iam:ListAttachedRolePolicies",
                          + "iam:ListAccountAliases",
                          + "iam:GetRolePolicy",
                          + "iam:GetRole",
                          + "iam:GetPolicyVersion",
                          + "iam:GetPolicy",
                          + "iam:GetOpenIDConnectProvider",
                          + "iam:GetInstanceProfile",
                          + "iam:DetachRolePolicy",
                          + "iam:DeleteRole",
                          + "iam:DeletePolicy",
                          + "iam:CreateRole",
                          + "iam:CreatePolicyVersion",
                          + "iam:CreatePolicy",
                          + "iam:AttachRolePolicy",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "lambda:UpdateFunctionConfiguration",
                          + "lambda:UpdateFunctionCode",
                          + "lambda:ListVersionsByFunction",
                          + "lambda:GetPolicy",
                          + "lambda:GetFunctionCodeSigningConfig",
                          + "lambda:GetFunction",
                          + "lambda:GetEventSourceMapping",
                          + "lambda:CreateFunction",
                          + "lambda:CreateEventSourceMapping",
                          + "lambda:AddPermission",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "logs:PutRetentionPolicy",
                          + "logs:DescribeSubscriptionFilters",
                          + "logs:DescribeLogStreams",
                          + "logs:DescribeLogGroups",
                          + "logs:CreateLogStream",
                          + "logs:CreateLogGroup",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "rds:ModifyDBSubnetGroup",
                          + "rds:ModifyDBParameterGroup",
                          + "rds:ModifyDBClusterParameterGroup",
                          + "rds:DescribeGlobalClusters",
                          + "rds:DescribeEventSubscriptions",
                          + "rds:DescribeDBSubnetGroups",
                          + "rds:DescribeDBParameters",
                          + "rds:DescribeDBParameterGroups",
                          + "rds:DescribeDBInstances",
                          + "rds:DescribeDBClusters",
                          + "rds:DescribeDBClusterParameters",
                          + "rds:DescribeDBClusterParameterGroups",
                          + "rds:DescribeDBClusterEndpoints",
                          + "rds:CreateDBSubnetGroup",
                          + "rds:CreateDBParameterGroup",
                          + "rds:AddSourceIdentifierToSubscription",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "route53:ListResourceRecordSets",
                          + "route53:ListHostedZones",
                          + "route53:GetHostedZone",
                          + "route53:GetChange",
                          + "route53:ChangeResourceRecordSets",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "s3:PutLifecycleConfiguration",
                          + "s3:PutEncryptionConfiguration",
                          + "s3:PutBucketVersioning",
                          + "s3:PutBucketPolicy",
                          + "s3:PutBucketOwnershipControls",
                          + "s3:PutBucketNotification",
                          + "s3:PutBucketLogging",
                          + "s3:GetReplicationConfiguration",
                          + "s3:GetLifecycleConfiguration",
                          + "s3:GetEncryptionConfiguration",
                          + "s3:GetBucketWebsite",
                          + "s3:GetBucketVersioning",
                          + "s3:GetBucketRequestPayment",
                          + "s3:GetBucketPolicy",
                          + "s3:GetBucketOwnershipControls",
                          + "s3:GetBucketObjectLockConfiguration",
                          + "s3:GetBucketNotification",
                          + "s3:GetBucketLogging",
                          + "s3:GetBucketCORS",
                          + "s3:GetBucketAcl",
                          + "s3:GetAccelerateConfiguration",
                          + "s3:DeleteBucketPolicy",
                          + "s3:DeleteBucket",
                          + "s3:CreateBucket",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "secretsmanager:GetSecretValue",
                          + "secretsmanager:GetResourcePolicy",
                          + "secretsmanager:DescribeSecret",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "sqs:SetQueueAttributes",
                          + "sqs:CreateQueue",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "sns:ListTopics",
                          + "sns:ListTagsForResource",
                          + "sns:ListSubscriptionsByTopic",
                          + "sns:GetTopicAttributes",
                          + "sns:GetSubscriptionAttributes",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "ssm:TerminateSession",
                          + "ssm:StartSession",
                          + "ssm:PutParameter",
                          + "ssm:GetParametersByPath",
                          + "ssm:GetParameters",
                          + "ssm:GetParameter",
                          + "ssm:DescribeParameters",
                          + "ssm:DeleteParameter",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = "sts:GetCallerIdentity"
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                  + {
                      + Action   = [
                          + "wafv2:UpdateIPSet",
                          + "wafv2:ListWebACLs",
                          + "wafv2:ListIPSets",
                          + "wafv2:GetWebACLForResource",
                          + "wafv2:GetIPSet",
                          + "wafv2:CreateWebACL",
                          + "wafv2:CreateIPSet",
                          + "wafv2:AssociateWebACL",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + role        = "bcda-prod-github-actions"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

@gfreeman-navapbc gfreeman-navapbc self-assigned this Sep 30, 2025
@gfreeman-navapbc gfreeman-navapbc requested a review from a team as a code owner September 30, 2025 18:31
bhagatparwinder
bhagatparwinder previously approved these changes Oct 1, 2025
@gfreeman-navapbc gfreeman-navapbc merged commit 506ab2d into main Oct 8, 2025
@gfreeman-navapbc gfreeman-navapbc deleted the gfreeman/PLT-1366 branch October 8, 2025 15:14
gfreeman-navapbc added a commit that referenced this pull request Oct 14, 2025
…tions-role (#329)

## 🎫 Ticket

https://jira.cms.gov/browse/PLT-1388

## 🛠 Changes

Adds sandbox back to the deploy matrix for `github-actions-role`.

## ℹ️ Context

We had a code freeze on the sandbox environment for the pentesting that
ended 10/10/2025. This PR aims to add the sandbox environment back to
the deploy matrix to reflect changes that were made to the permissions
of the `github-actions-role`, bringing it into parity with the other
environments.

## 🧪 Validation
This change has been validated in
#321
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants