From a5997f878bf3b4fa3784fd4acd1cae8a41b67bf3 Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Fri, 7 Aug 2026 11:00:49 -0400 Subject: [PATCH] fix(iam): widen procurement-ingest plan refresh for import Add GetEventSourceMapping, SSM GetParameter pins, and Resource "*" for kms:ListAliases so the first HCP import plan can refresh. --- .../terraform-substrate.template.yaml | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/lib/terraform-substrate/terraform-substrate.template.yaml b/lib/terraform-substrate/terraform-substrate.template.yaml index 59ed71e..11c4ac4 100644 --- a/lib/terraform-substrate/terraform-substrate.template.yaml +++ b/lib/terraform-substrate/terraform-substrate.template.yaml @@ -999,11 +999,15 @@ Resources: - !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:workorder-*" - !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:procurement-api" # Collection/list APIs authorize only against Resource "*". + # GetEventSourceMapping is authorized on the UUID mapping ARN + # (no FunctionArn in the request context), so it cannot share + # the apply-role FunctionArn condition. - Sid: RefreshLambdaList Effect: Allow Action: - lambda:ListFunctions - lambda:ListEventSourceMappings + - lambda:GetEventSourceMapping - lambda:GetAccountSettings Resource: "*" - Sid: RefreshArtifactsBucket @@ -1093,10 +1097,16 @@ Resources: - kms:GetKeyPolicy - kms:GetKeyRotationStatus - kms:ListResourceTags - - kms:ListAliases Resource: - !Sub "arn:aws:kms:us-east-1:${AWS::AccountId}:key/*" - !Sub "arn:aws:kms:us-east-1:${AWS::AccountId}:alias/workorder-ingest-shoc-webhook-kms" + # ListAliases/ListKeys are collection APIs (Resource "*"). + - Sid: RefreshKmsList + Effect: Allow + Action: + - kms:ListAliases + - kms:ListKeys + Resource: "*" - Sid: RefreshSecrets Effect: Allow Action: @@ -1106,6 +1116,15 @@ Resources: Resource: - !Sub "arn:aws:secretsmanager:us-east-1:${AWS::AccountId}:secret:workorder-ingest/shoc-webhook-hmac-*" - !Sub "arn:aws:secretsmanager:us-east-1:${AWS::AccountId}:secret:procurement-ingest/web-ui-auth-token-*" + # OOB SSM pins used by data.aws_ssm_parameter (not in ViewOnlyAccess). + - Sid: RefreshSsm + Effect: Allow + Action: + - ssm:GetParameter + - ssm:GetParameters + Resource: + - !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/seahaven/dynamodb/cmk-arn" + - !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/procurement-api/custom-domain/certificate-arn" - Sid: RefreshSes Effect: Allow Action: @@ -1152,16 +1171,22 @@ Resources: - !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:workorder-*" - !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:procurement-api" # Event source mapping ARNs are UUID-keyed; AWS authorises Create against - # FunctionArn. Get/Update/Delete also take the mapping ARN, so Resource - # stays "*" but FunctionArn is constrained to this stack's functions. + # FunctionArn. Mutating Get/Update/Delete also take the mapping ARN. + # GetEventSourceMapping by UUID does not carry FunctionArn in the + # request context, so read is unconditioned on "*"; mutate stays + # FunctionArn-constrained. + - Sid: LambdaEventSourceMappingRead + Effect: Allow + Action: + - lambda:GetEventSourceMapping + - lambda:ListTags + Resource: "*" - Sid: LambdaEventSourceMappings Effect: Allow Action: - lambda:CreateEventSourceMapping - lambda:DeleteEventSourceMapping - lambda:UpdateEventSourceMapping - - lambda:GetEventSourceMapping - - lambda:ListTags - lambda:TagResource - lambda:UntagResource Resource: "*" @@ -1178,6 +1203,14 @@ Resources: - lambda:ListEventSourceMappings - lambda:GetAccountSettings Resource: "*" + - Sid: SsmRead + Effect: Allow + Action: + - ssm:GetParameter + - ssm:GetParameters + Resource: + - !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/seahaven/dynamodb/cmk-arn" + - !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/procurement-api/custom-domain/certificate-arn" - Sid: CloudWatchLogs Effect: Allow Action: