@@ -31,9 +31,133 @@ resource "aws_iam_policy" "terraform_state" {
3131 )
3232}
3333
34+ # Lambda Management Policy
35+ resource "aws_iam_policy" "lambda_management" {
36+ name = " lambda-management"
37+ description = " Policy granting permissions to manage Lambda functions for this stack"
38+ path = " /service-policies/"
39+
40+ policy = jsonencode ({
41+ Version = " 2012-10-17" ,
42+ Statement = [
43+ {
44+ Effect = " Allow" ,
45+ Action = [
46+ " lambda:CreateFunction" ,
47+ " lambda:UpdateFunctionCode" ,
48+ " lambda:UpdateFunctionConfiguration" ,
49+ " lambda:DeleteFunction" ,
50+ " lambda:GetFunction" ,
51+ " lambda:GetFunctionConfiguration" ,
52+ " lambda:GetFunctionCodeSigningConfig" ,
53+ " lambda:ListVersionsByFunction" ,
54+ " lambda:TagResource" ,
55+ " lambda:UntagResource" ,
56+ " lambda:ListTags" ,
57+ " lambda:PublishVersion" ,
58+ " lambda:CreateAlias" ,
59+ " lambda:UpdateAlias" ,
60+ " lambda:DeleteAlias" ,
61+ " lambda:ListAliases" ,
62+ " lambda:AddPermission" ,
63+ " lambda:RemovePermission" ,
64+ " lambda:GetPolicy"
65+ ],
66+ Resource = [
67+ " arn:aws:lambda:*:${ data . aws_caller_identity . current . account_id } :function:*eligibility_signposting_api"
68+ ]
69+ }
70+ ]
71+ })
72+
73+ tags = merge (local. tags , { Name = " lambda-management" })
74+ }
75+
76+ # DynamoDB Management Policy
77+ resource "aws_iam_policy" "dynamodb_management" {
78+ name = " dynamodb-management"
79+ description = " Policy granting permissions to manage DynamoDB tables for this stack"
80+ path = " /service-policies/"
81+
82+ policy = jsonencode ({
83+ Version = " 2012-10-17" ,
84+ Statement = [
85+ {
86+ Effect = " Allow" ,
87+ Action = [
88+ " dynamodb:DescribeTimeToLive" ,
89+ " dynamodb:DescribeTable" ,
90+ " dynamodb:DescribeContinuousBackups" ,
91+ " dynamodb:ListTables" ,
92+ " dynamodb:DeleteTable" ,
93+ " dynamodb:CreateTable"
94+ ],
95+ Resource = [
96+ " arn:aws:dynamodb:*:${ data . aws_caller_identity . current . account_id } :table:*eligibility_datastore"
97+ ]
98+ }
99+ ]
100+ })
101+
102+ tags = merge (local. tags , { Name = " dynamodb-management" })
103+ }
104+
105+ # S3 Management Policy
106+ resource "aws_iam_policy" "s3_management" {
107+ name = " s3-management"
108+ description = " Policy granting permissions to manage S3 buckets"
109+ path = " /service-policies/"
110+
111+ policy = jsonencode ({
112+ Version = " 2012-10-17" ,
113+ Statement = [
114+ {
115+ Effect = " Allow" ,
116+ Action = [
117+ " s3:GetLifecycleConfiguration" ,
118+ " s3:PutLifecycleConfiguration" ,
119+ " s3:GetBucketVersioning" ,
120+ " s3:GetEncryptionConfiguration" ,
121+ " s3:PutEncryptionConfiguration" ,
122+ " s3:GetBucketPolicy" ,
123+ " s3:GetBucketObjectLockConfiguration" ,
124+ " s3:GetBucketLogging" ,
125+ " s3:GetReplicationConfiguration" ,
126+ " s3:GetBucketWebsite" ,
127+ " s3:GetBucketRequestPayment" ,
128+ " s3:GetBucketCORS" ,
129+ " s3:GetBucketAcl" ,
130+ " s3:PutBucketAcl" ,
131+ " s3:GetAccelerateConfiguration" ,
132+ " s3:ListBucket" ,
133+ " s3:GetObject" ,
134+ " s3:PutObject" ,
135+ " s3:DeleteObject" ,
136+ " s3:GetBucketLocation" ,
137+ " s3:GetBucketPublicAccessBlock" ,
138+ " s3:PutBucketCORS" ,
139+ " s3:CreateBucket" ,
140+ " s3:DeleteBucket"
141+ ],
142+ Resource = [
143+ " arn:aws:s3:::*eligibility-signposting-${ var . environment } -eli-rules" ,
144+ " arn:aws:s3:::*eligibility-signposting-${ var . environment } -eli-rules/*" ,
145+ " arn:aws:s3:::*eligibility-signposting-${ var . environment } -eli-audit" ,
146+ " arn:aws:s3:::*eligibility-signposting-${ var . environment } -eli-audit/*" ,
147+ " arn:aws:s3:::*eligibility-signposting-${ var . environment } -eli-rules-access-logs" ,
148+ " arn:aws:s3:::*eligibility-signposting-${ var . environment } -eli-rules-access-logs/*" ,
149+ " arn:aws:s3:::*eligibility-signposting-${ var . environment } -eli-audit-access-logs" ,
150+ " arn:aws:s3:::*eligibility-signposting-${ var . environment } -eli-audit-access-logs/*"
151+ ]
152+ }
153+ ]
154+ })
155+
156+ tags = merge (local. tags , { Name = " s3-management" })
157+ }
158+
34159# API Infrastructure Management Policy
35160resource "aws_iam_policy" "api_infrastructure" {
36- # checkov:skip=CKV_AWS_287 Ensure IAM policies does not allow credentials exposure
37161 # checkov:skip=CKV_AWS_355 Ensure no IAM policies documents allow "*" as a statement's resource for restrictable actions
38162 # checkov:skip=CKV_AWS_288 Ensure IAM policies does not allow data exfiltration
39163 # checkov:skip=CKV_AWS_289 Ensure IAM policies does not allow permissions management / resource exposure without constraints
@@ -50,34 +174,6 @@ resource "aws_iam_policy" "api_infrastructure" {
50174 {
51175 Effect = " Allow" ,
52176 Action = [
53- # Lambda permissions
54- " lambda:*" ,
55-
56- # DynamoDB permissions
57- " dynamodb:*" ,
58-
59- # API Gateway permissions
60- " apigateway:*" ,
61-
62- # S3 permissions
63- " s3:*" ,
64-
65- # KMS permissions
66- " kms:List*" ,
67- " kms:Describe*" ,
68- " kms:GetKeyPolicy*" ,
69- " kms:GetKeyRotationStatus" ,
70- " kms:Decrypt*" ,
71- " kms:DeleteAlias" ,
72- " kms:UpdateKeyDescription" ,
73- " kms:CreateGrant" ,
74- " kms:CreateAlias" ,
75- " kms:TagResource" ,
76- " kms:CreateKey" ,
77- " kms:EnableKeyRotation" ,
78- " kms:ScheduleKeyDeletion" ,
79- " kms:PutKeyPolicy" ,
80- " kms:Encrypt" ,
81177
82178 # Cloudwatch permissions
83179 " logs:Describe*" ,
@@ -95,11 +191,14 @@ resource "aws_iam_policy" "api_infrastructure" {
95191 " iam:GetPolicy*" ,
96192 " iam:GetRole*" ,
97193 " iam:List*" ,
98- " iam:Create*" ,
99- " iam:Update*" ,
100- " iam:Delete*" ,
101- " iam:PutRolePermissionsBoundary" ,
194+ " iam:CreateRole" ,
195+ " iam:DeleteRole" ,
196+ " iam:UpdateRole" ,
102197 " iam:PutRolePolicy" ,
198+ " iam:PutRolePermissionsBoundary" ,
199+ " iam:AttachRolePolicy" ,
200+ " iam:DetachRolePolicy" ,
201+ " iam:CreatePolicyVersion" ,
103202
104203 # ssm
105204 " ssm:GetParameter" ,
@@ -131,8 +230,8 @@ resource "aws_iam_policy" "api_infrastructure" {
131230# Assume role policy document for GitHub Actions
132231data "aws_iam_policy_document" "github_actions_assume_role" {
133232 statement {
134- sid = " OidcAssumeRoleWithWebIdentity"
135- effect = " Allow"
233+ sid = " OidcAssumeRoleWithWebIdentity"
234+ effect = " Allow"
136235 actions = [" sts:AssumeRoleWithWebIdentity" ]
137236
138237 principals {
@@ -145,13 +244,13 @@ data "aws_iam_policy_document" "github_actions_assume_role" {
145244 condition {
146245 test = " StringLike"
147246 variable = " token.actions.githubusercontent.com:sub"
148- values = [" repo:${ var . github_org } /${ var . github_repo } :*" ]
247+ values = [" repo:${ var . github_org } /${ var . github_repo } :*" ]
149248 }
150249
151250 condition {
152251 test = " StringEquals"
153252 variable = " token.actions.githubusercontent.com:aud"
154- values = [" sts.amazonaws.com" ]
253+ values = [" sts.amazonaws.com" ]
155254 }
156255 }
157256}
@@ -166,3 +265,20 @@ resource "aws_iam_role_policy_attachment" "api_infrastructure" {
166265 role = aws_iam_role. github_actions . name
167266 policy_arn = aws_iam_policy. api_infrastructure . arn
168267}
268+
269+ resource "aws_iam_role_policy_attachment" "lambda_management" {
270+ role = aws_iam_role. github_actions . name
271+ policy_arn = aws_iam_policy. lambda_management . arn
272+ }
273+
274+ resource "aws_iam_role_policy_attachment" "dynamodb_management" {
275+ role = aws_iam_role. github_actions . name
276+ policy_arn = aws_iam_policy. dynamodb_management . arn
277+ }
278+
279+ resource "aws_iam_role_policy_attachment" "s3_management" {
280+ role = aws_iam_role. github_actions . name
281+ policy_arn = aws_iam_policy. s3_management . arn
282+ }
283+
284+ data "aws_caller_identity" "current" {}
0 commit comments