feat(iam): add hcptf roles and boundary for procurement-ingest (PLAT-86) (#85)

* feat(iam): add hcptf roles and boundary for procurement-ingest

* fix(iam): tighten procurement-ingest apply and plan scopes

Replace kms:* and secret-value writes on shell statements; split IAM
collection APIs onto Resource "*".
This commit is contained in:
Adam Moussa 2026-08-07 10:41:12 -04:00 • committed by GitHub
parent dd45c1ca07
commit a5fa0b16a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 539 additions and 4 deletions

View file

@ -541,12 +541,128 @@ Resources:
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/front-sla-alerts/index/*"
- !Ref AWS::NoValue
# ── procurement-ingest (PLAT-86) — prod-only exact secrets + data plane ─
# Derived from live CDK stacks in seahaven-prod 2026-08-06. Exact secret
# ARNs only (no secret:procurement-* / workorder-ingest/* wildcards).
- !If
- IsProdAccount
- Sid: ProcurementIngestSecrets
Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource:
- arn:aws:secretsmanager:us-east-1:011934824531:secret:procurement-ingest/web-ui-auth-token-ApAMmr
- arn:aws:secretsmanager:us-east-1:011934824531:secret:workorder-ingest/shoc-webhook-hmac-puYTcB
- !Ref AWS::NoValue
- !If
- IsProdAccount
- Sid: ProcurementIngestDynamoDB
Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
- dynamodb:Query
- dynamodb:Scan
- dynamodb:BatchGetItem
- dynamodb:BatchWriteItem
- dynamodb:DescribeTable
- dynamodb:ConditionCheckItem
- dynamodb:GetRecords
- dynamodb:GetShardIterator
- dynamodb:DescribeStream
# ListStreams is a collection API (Resource "*"); ARN-scoping
# it is a silent no-op. Runtime stream consumers use the
# stream ARN via DescribeStream/GetRecords above.
Resource:
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/purchase-orders"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/purchase-orders/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/verified-sites"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/verified-sites/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/pending-site-review"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/pending-site-review/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrders"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrders/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrderComments"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrderComments/*"
- !Ref AWS::NoValue
- !If
- IsProdAccount
- Sid: ProcurementIngestS3
Effect: Allow
Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
- s3:PutObject*
- s3:DeleteObject*
- s3:AbortMultipartUpload
Resource:
- !Sub "arn:aws:s3:::po-ingest-emails-${AWS::AccountId}"
- !Sub "arn:aws:s3:::po-ingest-emails-${AWS::AccountId}/*"
- !Sub "arn:aws:s3:::workorder-ingest-emails-${AWS::AccountId}"
- !Sub "arn:aws:s3:::workorder-ingest-emails-${AWS::AccountId}/*"
- !Ref AWS::NoValue
- !If
- IsProdAccount
- Sid: ProcurementIngestSqs
Effect: Allow
Action:
- sqs:SendMessage
- sqs:ReceiveMessage
- sqs:DeleteMessage
- sqs:GetQueueAttributes
- sqs:GetQueueUrl
- sqs:ChangeMessageVisibility
Resource:
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:po-ingest-*"
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:WorkorderIngestStack-*"
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:workorder-shoc-emitter-*"
- !Ref AWS::NoValue
- !If
- IsProdAccount
- Sid: ProcurementIngestKms
Effect: Allow
Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:GenerateDataKey*
- kms:ReEncrypt*
Resource:
- arn:aws:kms:us-east-1:011934824531:key/be5fa4cb-c546-40fe-a13d-c7bec79f5d12
- arn:aws:kms:us-east-1:011934824531:key/d10fd1f0-a61a-4405-8568-85e9fd11ba18
- !Ref AWS::NoValue
- !If
- IsProdAccount
- Sid: ProcurementIngestBedrock
Effect: Allow
Action:
- bedrock:InvokeModel
- bedrock:InvokeModelWithResponseStream
Resource:
- !Sub "arn:aws:bedrock:us-east-1:${AWS::AccountId}:inference-profile/us.anthropic.claude-haiku-4-5-20251001-v1:0"
- arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-haiku-4-5-20251001-v1:0
- arn:aws:bedrock:us-east-2::foundation-model/anthropic.claude-haiku-4-5-20251001-v1:0
- arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-haiku-4-5-20251001-v1:0
- !Ref AWS::NoValue
- !If
- IsProdAccount
- Sid: ProcurementIngestSns
Effect: Allow
Action:
- sns:Publish
Resource:
- !Sub "arn:aws:sns:us-east-1:${AWS::AccountId}:site-alerts"
- !Ref AWS::NoValue
# ── FURTHER PER-WORKLOAD DATA-PLANE STATEMENTS ──────────────────────
# Floor above + afi-backup-monitor (PLAT-56) + front-integrations
# (PLAT-72). Additional stacks add their own statements here, derived
# from THEIR OWN template, in their own PR, deployed to
# UPDATE_COMPLETE before first workload deploy. WIDENING PATH in the
# header still governs.
# (PLAT-72) + procurement-ingest (PLAT-86). Additional stacks add
# their own statements here, derived from THEIR OWN template, in
# their own PR, deployed to UPDATE_COMPLETE before first workload
# deploy. WIDENING PATH in the header still governs.
#
# WHY the floor stayed empty of data-plane (decided 2026-07-30, Adam):
# The security win of INFRA-186 comes from DELETION, not enumeration.

View file

@ -941,3 +941,422 @@ Resources:
Condition:
StringEquals:
"secretsmanager:Name": sh-openswe/langsmith-export-s3
# ---------------------------------------------------------------------------
# procurement-ingest (PLAT-86) — plan + apply roles for workspace
# procurement-ingest-prod. Import-in-place of three former CDK stacks
# (po-ingest, WorkorderIngestStack, procurement-api). Copy shape from
# front-integrations; extend for S3 email buckets, SQS, SES receipt rules,
# API Gateway, KMS (SHOC + DynamoDB CMK manage), Secrets Manager shell/
# rotation, DynamoDB streams, and prefix-scoped Lambda/alarms/log groups.
# ---------------------------------------------------------------------------
HcptfProcurementIngestPlanRole:
Type: AWS::IAM::Role
Condition: IsProdAccount
Properties:
RoleName: hcptf-procurement-ingest-plan
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Federated: !Sub "arn:aws:iam::${AWS::AccountId}:oidc-provider/app.terraform.io"
Action: sts:AssumeRoleWithWebIdentity
Condition:
StringEquals:
"app.terraform.io:aud": aws.workload.identity
"app.terraform.io:sub": organization:seahaven:project:seahaven-prod:workspace:procurement-ingest-prod:run_phase:plan
ManagedPolicyArns:
- arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
Policies:
- PolicyName: procurement-ingest-plan-refresh
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: RefreshIamRoles
Effect: Allow
Action:
- iam:GetRole
- iam:GetRolePolicy
- iam:ListRolePolicies
- iam:ListAttachedRolePolicies
Resource:
- !Sub "arn:aws:iam::${AWS::AccountId}:role/tf-managed/po-*"
- !Sub "arn:aws:iam::${AWS::AccountId}:role/tf-managed/workorder-*"
- !Sub "arn:aws:iam::${AWS::AccountId}:role/tf-managed/procurement-api"
- Sid: RefreshManagedPolicies
Effect: Allow
Action:
- iam:GetPolicy
- iam:GetPolicyVersion
Resource: "*"
- Sid: RefreshLambda
Effect: Allow
Action:
- lambda:Get*
Resource:
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:po-*"
- !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 "*".
- Sid: RefreshLambdaList
Effect: Allow
Action:
- lambda:ListFunctions
- lambda:ListEventSourceMappings
- lambda:GetAccountSettings
Resource: "*"
- Sid: RefreshArtifactsBucket
Effect: Allow
Action:
- s3:Get*
- s3:ListBucket
Resource:
- !Sub "arn:aws:s3:::procurement-ingest-artifacts-${AWS::AccountId}"
- !Sub "arn:aws:s3:::procurement-ingest-artifacts-${AWS::AccountId}/*"
- Sid: RefreshEmailBuckets
Effect: Allow
Action:
- s3:Get*
- s3:ListBucket
- s3:GetBucketNotification
- s3:GetBucketPolicy
- s3:GetEncryptionConfiguration
- s3:GetBucketTagging
- s3:GetBucketVersioning
- s3:GetBucketPublicAccessBlock
Resource:
- !Sub "arn:aws:s3:::po-ingest-emails-${AWS::AccountId}"
- !Sub "arn:aws:s3:::po-ingest-emails-${AWS::AccountId}/*"
- !Sub "arn:aws:s3:::workorder-ingest-emails-${AWS::AccountId}"
- !Sub "arn:aws:s3:::workorder-ingest-emails-${AWS::AccountId}/*"
- Sid: RefreshDynamoDB
Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:DescribeTimeToLive
- dynamodb:DescribeContinuousBackups
- dynamodb:DescribeStream
- dynamodb:ListTagsOfResource
Resource:
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/purchase-orders"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/purchase-orders/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/verified-sites"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/pending-site-review"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrders"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrders/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrderComments"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrderComments/*"
- Sid: RefreshDynamoDBList
Effect: Allow
Action:
- dynamodb:ListStreams
- dynamodb:ListTables
Resource: "*"
- Sid: RefreshSqs
Effect: Allow
Action:
- sqs:GetQueueAttributes
- sqs:GetQueueUrl
- sqs:ListQueueTags
Resource:
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:po-ingest-*"
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:WorkorderIngestStack-*"
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:workorder-shoc-emitter-*"
- Sid: RefreshCloudWatchAlarms
Effect: Allow
Action:
- cloudwatch:DescribeAlarms
- cloudwatch:ListTagsForResource
Resource:
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:po-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:workorder-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:procurement-api-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:purchase-orders-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:verified-sites-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:pending-site-review-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:WorkOrders-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:WorkOrderComments-*"
- Sid: RefreshApiGateway
Effect: Allow
Action:
- apigateway:GET
Resource:
- !Sub "arn:aws:apigateway:us-east-1::/restapis/mvul1efda2"
- !Sub "arn:aws:apigateway:us-east-1::/restapis/mvul1efda2/*"
- arn:aws:apigateway:us-east-1::/domainnames/procurement-api.seahaven.com
- arn:aws:apigateway:us-east-1::/domainnames/procurement-api.seahaven.com/*
- Sid: RefreshKms
Effect: Allow
Action:
- kms:DescribeKey
- 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"
- Sid: RefreshSecrets
Effect: Allow
Action:
- secretsmanager:DescribeSecret
- secretsmanager:GetResourcePolicy
- secretsmanager:ListSecretVersionIds
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-*"
- Sid: RefreshSes
Effect: Allow
Action:
- ses:DescribeReceiptRule
- ses:DescribeReceiptRuleSet
Resource: "*"
- Sid: RefreshLogs
Effect: Allow
Action:
- logs:DescribeLogGroups
- logs:DescribeMetricFilters
- logs:ListTagsForResource
Resource: "*"
HcptfProcurementIngestApplyRole:
Type: AWS::IAM::Role
Condition: IsProdAccount
Properties:
RoleName: hcptf-procurement-ingest
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Federated: !Sub "arn:aws:iam::${AWS::AccountId}:oidc-provider/app.terraform.io"
Action: sts:AssumeRoleWithWebIdentity
Condition:
StringEquals:
"app.terraform.io:aud": aws.workload.identity
"app.terraform.io:sub": organization:seahaven:project:seahaven-prod:workspace:procurement-ingest-prod:run_phase:apply
ManagedPolicyArns:
- !Ref HcptfIamManagementPolicy
Policies:
- PolicyName: procurement-ingest-services
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: LambdaAll
Effect: Allow
Action:
- lambda:*
Resource:
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:po-*"
- !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.
- Sid: LambdaEventSourceMappings
Effect: Allow
Action:
- lambda:CreateEventSourceMapping
- lambda:DeleteEventSourceMapping
- lambda:UpdateEventSourceMapping
- lambda:GetEventSourceMapping
- lambda:ListTags
- lambda:TagResource
- lambda:UntagResource
Resource: "*"
Condition:
"ForAnyValue:StringLike":
"lambda:FunctionArn":
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:po-*"
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:workorder-*"
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:procurement-api"
- Sid: LambdaList
Effect: Allow
Action:
- lambda:ListFunctions
- lambda:ListEventSourceMappings
- lambda:GetAccountSettings
Resource: "*"
- Sid: CloudWatchLogs
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:DeleteLogGroup
- logs:PutRetentionPolicy
- logs:DeleteRetentionPolicy
- logs:TagResource
- logs:UntagResource
- logs:ListTagsForResource
- logs:PutMetricFilter
- logs:DeleteMetricFilter
- logs:DescribeMetricFilters
Resource:
- !Sub "arn:aws:logs:us-east-1:${AWS::AccountId}:log-group:/aws/lambda/po-*"
- !Sub "arn:aws:logs:us-east-1:${AWS::AccountId}:log-group:/aws/lambda/workorder-*"
- !Sub "arn:aws:logs:us-east-1:${AWS::AccountId}:log-group:/aws/lambda/procurement-api*"
- Sid: CloudWatchLogsDescribe
Effect: Allow
Action:
- logs:DescribeLogGroups
Resource: "*"
- Sid: ArtifactsBucket
Effect: Allow
Action:
- s3:*
Resource:
- !Sub "arn:aws:s3:::procurement-ingest-artifacts-${AWS::AccountId}"
- !Sub "arn:aws:s3:::procurement-ingest-artifacts-${AWS::AccountId}/*"
- Sid: EmailBuckets
Effect: Allow
Action:
- s3:*
Resource:
- !Sub "arn:aws:s3:::po-ingest-emails-${AWS::AccountId}"
- !Sub "arn:aws:s3:::po-ingest-emails-${AWS::AccountId}/*"
- !Sub "arn:aws:s3:::workorder-ingest-emails-${AWS::AccountId}"
- !Sub "arn:aws:s3:::workorder-ingest-emails-${AWS::AccountId}/*"
- Sid: DynamoDBTables
Effect: Allow
Action:
- dynamodb:*
Resource:
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/purchase-orders"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/purchase-orders/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/verified-sites"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/verified-sites/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/pending-site-review"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/pending-site-review/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrders"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrders/*"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrderComments"
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/WorkOrderComments/*"
- Sid: DynamoDBList
Effect: Allow
Action:
- dynamodb:ListTables
- dynamodb:ListStreams
Resource: "*"
- Sid: SqsQueues
Effect: Allow
Action:
- sqs:*
Resource:
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:po-ingest-*"
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:WorkorderIngestStack-*"
- !Sub "arn:aws:sqs:us-east-1:${AWS::AccountId}:workorder-shoc-emitter-*"
- Sid: CloudWatchAlarms
Effect: Allow
Action:
- cloudwatch:*
Resource:
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:po-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:workorder-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:procurement-api-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:purchase-orders-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:verified-sites-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:pending-site-review-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:WorkOrders-*"
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:WorkOrderComments-*"
- Sid: SiteAlertsSns
Effect: Allow
Action:
- sns:Publish
- sns:GetTopicAttributes
- sns:ListTagsForResource
Resource:
- !Sub "arn:aws:sns:us-east-1:${AWS::AccountId}:site-alerts"
- Sid: ApiGateway
Effect: Allow
Action:
- apigateway:*
Resource:
- !Sub "arn:aws:apigateway:us-east-1::/restapis/mvul1efda2"
- !Sub "arn:aws:apigateway:us-east-1::/restapis/mvul1efda2/*"
- arn:aws:apigateway:us-east-1::/domainnames/procurement-api.seahaven.com
- arn:aws:apigateway:us-east-1::/domainnames/procurement-api.seahaven.com/*
- Sid: SesReceiptRules
Effect: Allow
Action:
- ses:CreateReceiptRule
- ses:UpdateReceiptRule
- ses:DeleteReceiptRule
- ses:DescribeReceiptRule
- ses:SetReceiptRulePosition
Resource:
- !Sub "arn:aws:ses:us-east-1:${AWS::AccountId}:receipt-rule-set/INBOUND_MAIL:receipt-rule/ExistingRuleSetPoEmailRuleAC8E9C87-qwGDj9lBoL1G"
- !Sub "arn:aws:ses:us-east-1:${AWS::AccountId}:receipt-rule-set/INBOUND_MAIL:receipt-rule/ExistingRuleSetWorkorderEmailRuleEA29F845-PKtaDBvIg61a"
- Sid: SesDescribeRuleSet
Effect: Allow
Action:
- ses:DescribeReceiptRuleSet
Resource: "*"
# Key management only on the live SHOC CMK — no kms:* (excludes
# unconstrained key-policy/destructive ops on other keys and
# avoids data-plane Encrypt/Decrypt on the apply role).
- Sid: ShocKms
Effect: Allow
Action:
- kms:DescribeKey
- kms:GetKeyPolicy
- kms:GetKeyRotationStatus
- kms:ListResourceTags
- kms:PutKeyPolicy
- kms:EnableKeyRotation
- kms:DisableKeyRotation
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
- kms:TagResource
- kms:UntagResource
- kms:EnableKey
- kms:DisableKey
Resource:
- !Sub "arn:aws:kms:us-east-1:${AWS::AccountId}:key/d10fd1f0-a61a-4405-8568-85e9fd11ba18"
- Sid: KmsList
Effect: Allow
Action:
- kms:ListAliases
- kms:ListKeys
Resource: "*"
- Sid: ShocKmsAlias
Effect: Allow
Action:
- kms:CreateAlias
- kms:DeleteAlias
- kms:UpdateAlias
Resource:
- !Sub "arn:aws:kms:us-east-1:${AWS::AccountId}:alias/workorder-ingest-shoc-webhook-kms"
- !Sub "arn:aws:kms:us-east-1:${AWS::AccountId}:key/d10fd1f0-a61a-4405-8568-85e9fd11ba18"
# Shell lifecycle only — no CreateSecret / UpdateSecret so apply
# never writes SecretString into HCP state or run logs. Create is
# isolated in ShocSecretCreate with an exact Name pin.
- Sid: ShocSecretShell
Effect: Allow
Action:
- secretsmanager:DeleteSecret
- secretsmanager:DescribeSecret
- secretsmanager:GetResourcePolicy
- secretsmanager:PutResourcePolicy
- secretsmanager:DeleteResourcePolicy
- secretsmanager:TagResource
- secretsmanager:UntagResource
- secretsmanager:RotateSecret
- secretsmanager:CancelRotateSecret
- secretsmanager:UpdateSecretVersionStage
Resource:
- !Sub "arn:aws:secretsmanager:us-east-1:${AWS::AccountId}:secret:workorder-ingest/shoc-webhook-hmac-*"
- Sid: ShocSecretCreate
Effect: Allow
Action:
- secretsmanager:CreateSecret
Resource: "*"
Condition:
StringEquals:
"secretsmanager:Name": workorder-ingest/shoc-webhook-hmac
- Sid: WebUiSecretDescribe
Effect: Allow
Action:
- secretsmanager:DescribeSecret
- secretsmanager:GetResourcePolicy
Resource:
- !Sub "arn:aws:secretsmanager:us-east-1:${AWS::AccountId}:secret:procurement-ingest/web-ui-auth-token-*"