terraform-aws-access/notes/policies.md

18 KiB

Policies

Specifically talking about IAM policies necessary for enabling OIDC between GitHub runners and AWS. There is an excellent tutorial on how to get started with this in the AWS credential action's repo: https://github.com/aws-actions/configure-aws-credentials?tab=readme-ov-file#oidc.

One thing they can't cover there is what permissions to give, because they are application specific. I have been meaning to add the policies you should set here somewhere, so I am dumping it in this note.

I split my policies into two parts: access and server. I am not sure if these are exactly least priviledge, but pretty close, I suggest monitoring the access and reducing as seems possible.

Please remember that these are just my notes, make good decisions and evaluate your security concerns.

Access

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Tags",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags",
                "ec2:DeleteTags",
                "ec2:DescribeTags"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VPC",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateVpc",
                "ec2:DeleteVpc",
                "ec2:DescribeVpcs",
                "ec2:DescribeVpcAttribute",
                "ec2:ModifyVpcAttribute",
                "ec2:MoveAddressToVpc",
                "ec2:DisassociateVpcCidrBlock",
                "ec2:AssociateVpcCidrBlock",
                "ec2:CreateDefaultVpc"
            ],
            "Resource": "*"
        },
        {
            "Sid": "InternetGateway",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateInternetGateway",
                "ec2:DeleteInternetGateway",
                "ec2:AttachInternetGateway",
                "ec2:DetachInternetGateway",
                "ec2:DescribeInternetGateways"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Route",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateRoute",
                "ec2:DeleteRoute",
                "ec2:CreateRouteTable",
                "ec2:DeleteRouteTable",
                "ec2:DescribeRouteTables",
                "ec2:DisassociateRouteTable",
                "ec2:ReplaceRoute",
                "ec2:ReplaceRouteTableAssociation",
                "ec2:AssociateRouteTable"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Subnet",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateSubnet",
                "ec2:AssociateSubnetCidrBlock",
                "ec2:CreateSubnetCidrReservation",
                "ec2:DeleteSubnetCidrReservation",
                "ec2:DisassociateSubnetCidrBlock",
                "ec2:GetSubnetCidrReservations",
                "ec2:ModifySubnetAttribute",
                "ec2:CreateDefaultSubnet",
                "ec2:DeleteSubnet",
                "ec2:DescribeSubnets",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeAddresses",
                "ec2:DescribeAddressesAttribute",
                "ec2:DescribeAddressTransfers",
                "ec2:DescribeMovingAddresses",
                "ec2:AllocateAddress",
                "ec2:AssociateAddress",
                "ec2:DisassociateAddress",
                "ec2:ModifyAddressAttribute",
                "ec2:ReleaseAddress"
            ],
            "Resource": "*"
        },
        {
            "Sid": "SecurityGroup",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateSecurityGroup",
                "ec2:DeleteSecurityGroup",
                "ec2:DescribeSecurityGroups",
                "ec2:AuthorizeSecurityGroupEgress",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:DescribeSecurityGroupReferences",
                "ec2:ModifySecurityGroupRules",
                "ec2:DescribeSecurityGroupRules",
                "ec2:RevokeSecurityGroupIngress",
                "ec2:RevokeSecurityGroupEgress",
                "ec2:UpdateSecurityGroupRuleDescriptionsEgress",
                "ec2:UpdateSecurityGroupRuleDescriptionsIngress"
            ],
            "Resource": "*"
        },
        {
            "Sid": "SshKeyPair",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateKeyPair",
                "ec2:DeleteKeyPair",
                "ec2:DescribeKeyPairs",
                "ec2:ImportKeyPair"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Domain",
            "Effect": "Allow",
            "Action": [
                "route53:GetChange",
                "route53:GetHostedZone",
                "route53:ListCidrBlocks",
                "route53:ListHostedZones",
                "route53:ListHostedZonesByName",
                "route53:ListHostedZonesByVPC",
                "route53:ListResourceRecordSets",
                "route53:GetHostedZoneLimit",
                "route53:ListTagsForResource",
                "route53:ListTagsForResources",
                "route53:TestDNSAnswer",
                "route53:AssociateVPCWithHostedZone",
                "route53:ChangeResourceRecordSets",
                "route53:ChangeCidrCollection",
                "route53:CreateCidrCollection",
                "route53:CreateHostedZone",
                "route53:DeleteHostedZone",
                "route53:DeleteCidrCollection",
                "route53:CreateVPCAssociationAuthorization",
                "route53:DeleteVPCAssociationAuthorization",
                "route53:DisassociateVPCFromHostedZone",
                "route53:UpdateHostedZoneComment",
                "route53:UpdateHealthCheck",
                "route53:ChangeTagsForResource",
                "route53:ListHealthChecks",
                "route53:GetHealthCheck",
                "route53:GetAccountLimit",
                "route53:ListCidrLocations",
                "route53:ListCidrCollections",
                "route53:GetHostedZoneCount",
                "route53:CreateHealthCheck",
                "route53:DeleteHealthCheck",
                "iam:UploadServerCertificate",
                "iam:ListServerCertificates",
                "iam:ListServerCertificateTags",
                "iam:DeleteServerCertificate",
                "iam:TagServerCertificate",
                "iam:GetServerCertificate",
                "iam:UntagServerCertificate"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Loadbalancing",
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:CreateLoadBalancer",
                "ec2:CreateSecurityGroup",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "elasticloadbalancing:AttachLoadBalancerToSubnets",
                "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
                "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                "ec2:DescribeClassicLinkInstances",
                "ec2:DescribeInstances",
                "elasticloadbalancing:DescribeInstanceHealth",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DisableAvailabilityZonesForLoadBalancer",
                "elasticloadbalancing:EnableAvailabilityZonesForLoadBalancer",
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "ec2:DescribeVpcClassicLink",
                "elasticloadbalancing:AddTags",
                "elasticloadbalancing:ModifyLoadBalancerAttributes",
                "elasticloadbalancing:DescribeLoadBalancerAttributes",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeTags",
                "elasticloadbalancing:DescribeRules",
                "elasticloadbalancing:DescribeTargetGroupAttributes",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:DescribeSSLPolicies",
                "elasticloadbalancing:DescribeListenerCertificates",
                "elasticloadbalancing:AddListenerCertificates",
                "elasticloadbalancing:CreateListener",
                "elasticloadbalancing:CreateRule",
                "elasticloadbalancing:CreateTargetGroup",
                "elasticloadbalancing:DeleteListener",
                "elasticloadbalancing:DeleteLoadBalancer",
                "elasticloadbalancing:DeleteRule",
                "elasticloadbalancing:DeleteTargetGroup",
                "elasticloadbalancing:DeregisterTargets",
                "elasticloadbalancing:ModifyListener",
                "elasticloadbalancing:ModifyRule",
                "elasticloadbalancing:ModifyTargetGroup",
                "elasticloadbalancing:ModifyTargetGroupAttributes",
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:RemoveListenerCertificates",
                "elasticloadbalancing:SetIpAddressType",
                "elasticloadbalancing:SetRulePriorities",
                "elasticloadbalancing:SetSecurityGroups",
                "elasticloadbalancing:SetSubnets",
                "elasticloadbalancing:RemoveTags",
                "elasticloadbalancing:ConfigureHealthCheck",
                "elasticloadbalancing:DescribeLoadBalancerPolicies",
                "elasticloadbalancing:DescribeLoadBalancerPolicyTypes",
                "elasticloadbalancing:CreateLoadBalancerListeners",
                "elasticloadbalancing:CreateLoadBalancerPolicy",
                "elasticloadbalancing:DeleteLoadBalancerListeners",
                "elasticloadbalancing:DeleteLoadBalancerPolicy",
                "elasticloadbalancing:DetachLoadBalancerFromSubnets",
                "elasticloadbalancing:SetLoadBalancerListenerSSLCertificate",
                "elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer",
                "elasticloadbalancing:SetLoadBalancerPoliciesOfListener"
            ],
            "Resource": "*"
        }
    ]
}

Server

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ManageEC2Instances",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstanceAttribute",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceStatus",
                "ec2:DescribeInstanceTypeOfferings",
                "ec2:DescribeInstanceCreditSpecifications",
                "ec2:DescribeInstanceTypes",
                "ec2:GetInstanceTypesFromInstanceRequirements",
                "ec2:ImportInstance",
                "ec2:ModifyInstanceAttribute",
                "ec2:ModifyInstanceMetadataOptions",
                "ec2:RebootInstances",
                "ec2:ReportInstanceStatus",
                "ec2:ResetInstanceAttribute",
                "ec2:RunInstances",
                "ec2:StartInstances",
                "ec2:StopInstances",
                "ec2:TerminateInstances",
                "ec2:CreateTags",
                "ec2:DeleteTags",
                "ec2:DescribeTags"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AddressAndInterface",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeAddresses",
                "ec2:DescribeAddressesAttribute",
                "ec2:DescribeAddressTransfers",
                "ec2:DescribeMovingAddresses",
                "ec2:DisableAddressTransfer",
                "ec2:DisassociateAddress",
                "ec2:EnableAddressTransfer",
                "ec2:ModifyAddressAttribute",
                "ec2:MoveAddressToVpc",
                "ec2:ReleaseAddress",
                "ec2:ResetAddressAttribute",
                "ec2:UnassignIpv6Addresses",
                "ec2:UnassignPrivateIpAddresses",
                "ec2:AcceptAddressTransfer",
                "ec2:AllocateAddress",
                "ec2:AssignIpv6Addresses",
                "ec2:AssignPrivateIpAddresses",
                "ec2:AssociateAddress",
                "ec2:AttachNetworkInterface",
                "ec2:CreateNetworkInterface",
                "ec2:CreateNetworkInterfacePermission",
                "ec2:DeleteNetworkInterface",
                "ec2:DeleteNetworkInterfacePermission",
                "ec2:DescribeNetworkInterfaceAttribute",
                "ec2:DescribeNetworkInterfacePermissions",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DetachNetworkInterface",
                "ec2:ModifyNetworkInterfaceAttribute",
                "ec2:ResetNetworkInterfaceAttribute",
                "ec2:CreateTags",
                "ec2:DeleteTags",
                "ec2:DescribeTags"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Image",
            "Effect": "Allow",
            "Action": [
                "ec2:CopyImage",
                "ec2:CreateImage",
                "ec2:CreateRestoreImageTask",
                "ec2:CreateStoreImageTask",
                "ec2:DeregisterImage",
                "ec2:DescribeExportImageTasks",
                "ec2:DescribeImageAttribute",
                "ec2:DescribeImages",
                "ec2:DescribeImportImageTasks",
                "ec2:DescribeStoreImageTasks",
                "ec2:DisableImageDeprecation",
                "ec2:EnableImageDeprecation",
                "ec2:ExportImage",
                "ec2:ImportImage",
                "ec2:ListImagesInRecycleBin",
                "ec2:ModifyImageAttribute",
                "ec2:RegisterImage",
                "ec2:ResetImageAttribute",
                "ec2:RestoreImageFromRecycleBin",
                "ec2:CancelImageLaunchPermission",
                "ec2:CreateTags",
                "ec2:DeleteTags",
                "ec2:DescribeTags"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ManageVolumesAndSnapshots",
            "Effect": "Allow",
            "Action": [
                "ec2:AttachVolume",
                "ec2:CreateReplaceRootVolumeTask",
                "ec2:CreateVolume",
                "ec2:DeleteVolume",
                "ec2:DescribeReplaceRootVolumeTasks",
                "ec2:DescribeVolumeAttribute",
                "ec2:DescribeVolumes",
                "ec2:DescribeVolumesModifications",
                "ec2:DescribeVolumeStatus",
                "ec2:DetachVolume",
                "ec2:EnableVolumeIO",
                "ec2:ImportVolume",
                "ec2:ModifyVolume",
                "ec2:ModifyVolumeAttribute",
                "ec2:CopySnapshot",
                "ec2:CreateSnapshot",
                "ec2:CreateSnapshots",
                "ec2:DeleteSnapshot",
                "ec2:DescribeImportSnapshotTasks",
                "ec2:DescribeSnapshotAttribute",
                "ec2:DescribeSnapshots",
                "ec2:DescribeSnapshotTierStatus",
                "ec2:ImportSnapshot",
                "ec2:ListSnapshotsInRecycleBin",
                "ec2:ModifySnapshotAttribute",
                "ec2:ModifySnapshotTier",
                "ec2:ResetSnapshotAttribute",
                "ec2:RestoreSnapshotFromRecycleBin",
                "ec2:RestoreSnapshotTier",
                "ec2:CreateTags",
                "ec2:DeleteTags",
                "ec2:DescribeTags"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ManageHostnames",
            "Effect": "Allow",
            "Action": [
                "route53Domains:EnableDomainAutoRenew",
                "route53Domains:GetDomainDetail",
                "route53Domains:ListDomains",
                "route53Domains:ListOperations",
                "route53Domains:PushDomain",
                "route53Domains:RegisterDomain",
                "route53Domains:RenewDomain",
                "route53Domains:UpdateDomainContact",
                "route53Domains:UpdateDomainContactPrivacy",
                "route53Domains:UpdateDomainNameservers",
                "route53Resolver:AssociateResolverEndpointIpAddress",
                "route53Resolver:UpdateResolverConfig",
                "route53:AssociateVPCWithHostedZone",
                "route53:CreateHostedZone",
                "route53:DeleteHostedZone",
                "route53:DisassociateVPCFromHostedZone",
                "route53:UpdateHostedZoneComment",
                "route53:GetHostedZone",
                "route53:GetHostedZoneCount",
                "route53:GetHostedZoneLimit",
                "route53:ListHostedZones",
                "route53:ListHostedZonesByName",
                "route53:ListHostedZonesByVPC",
                "route53:ListResourceRecordSets",
                "route53:ChangeResourceRecordSets",
                "route53Resolver:TagResource",
                "route53Resolver:UntagResource",
                "route53Domains:UpdateTagsForDomain",
                "route53Domains:ListTagsForDomain",
                "route53Domains:DeleteTagsForDomain",
                "route53:ListTagsForResource",
                "route53:ChangeTagsForResource",
                "route53:ListTagsForResource",
                "route53:ListTagsForResources"
            ],
            "Resource": "*"
        },
        {
            "Sid": "S3ForBackup",
            "Effect": "Allow",
            "Action": [
                "s3:CreateBucket",
                "s3:DeleteBucket",
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:PutBucketTagging",
                "s3:PutBucketVersioning",
                "s3:DeleteObject",
                "s3:DeleteObjectTagging",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:GetObjectAttributes",
                "s3:GetObjectRetention",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectRetention",
                "s3:PutObjectTagging",
                "s3:RestoreObject",
                "s3:GetBucketTagging"
            ],
            "Resource": "*"
        }
    ]
}