mirror of
https://github.com/Sea-Haven-Industries/seahaven-org-baseline.git
synced 2026-10-03 04:33:13 +00:00
fix(iam): shrink shared lambda boundary to the four-statement floor (PLAT-52)
PermissionsBoundaryUsageCount is 0 in prod and dev, so the shared seahaven-lambda-execution-boundary drops the packed IsProdAccount data-plane statements and keeps CloudWatchLogsWrite, CloudWatchLogsDescribe, XRay, and Ec2Eni. Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
This commit is contained in:
parent
d80295c005
commit
06c0be8314
1 changed files with 9 additions and 219 deletions
|
|
@ -134,9 +134,11 @@ Description: >-
|
|||
# on the synthesized PolicyDocument with ${AWS::AccountId} resolved, and UPDATE
|
||||
# THE NUMBERS in the same edit.
|
||||
#
|
||||
# Shared LambdaExecutionBoundary (legacy ceiling; do not widen): 5986
|
||||
# characters / 15 statements as of 2026-08-10 (PLAT-100). Headroom 158.
|
||||
# Leave it unchanged until live roles retarget (PLAT-52 phase 2).
|
||||
# Shared LambdaExecutionBoundary (floor only; do not widen): 708
|
||||
# characters / 4 statements as of 2026-09-28 (PLAT-52). Headroom 5436.
|
||||
# Statements: CloudWatchLogsWrite, CloudWatchLogsDescribe, XRay, Ec2Eni.
|
||||
# Packed IsProdAccount data-plane statements removed once
|
||||
# PermissionsBoundaryUsageCount was 0 in prod and dev.
|
||||
#
|
||||
# Per-workload policies (floor + own data plane). Compact sizes recorded
|
||||
# after synth (prod, ${AWS::AccountId}=011934824531):
|
||||
|
|
@ -523,223 +525,11 @@ Resources:
|
|||
- ec2:DescribeVpcs
|
||||
Resource: "*"
|
||||
|
||||
# ── Shared workload data-plane (PLAT-93 PolicySize consolidation) ───
|
||||
# Per-workload secret/DDB/S3 SIDs were merged so meal-order-manager
|
||||
# (PLAT-70) can fit under the 6,144-character managed-policy cap
|
||||
# without introducing new action wildcards. Exact secret ARNs only.
|
||||
# End-state isolation remains PLAT-52 / INFRA-187.
|
||||
#
|
||||
# WorkloadSecrets covers: afi-backup-monitor (PLAT-56),
|
||||
# front-integrations (PLAT-72), procurement-ingest (PLAT-86),
|
||||
# meal-order-manager (PLAT-70).
|
||||
- !If
|
||||
- IsProdAccount
|
||||
- Sid: WorkloadSecrets
|
||||
Effect: Allow
|
||||
Action:
|
||||
- secretsmanager:GetSecretValue
|
||||
Resource:
|
||||
- arn:aws:secretsmanager:us-east-1:011934824531:secret:afi-api-key-w0E02a
|
||||
- arn:aws:secretsmanager:us-east-1:011934824531:secret:afi-slack-webhook-T4oR3G
|
||||
- arn:aws:secretsmanager:us-east-1:011934824531:secret:front-integrations/front-api-token-UXKv0U
|
||||
- arn:aws:secretsmanager:us-east-1:011934824531:secret:front-integrations/slack-bot-token-giGfA7
|
||||
- arn:aws:secretsmanager:us-east-1:011934824531:secret:front-integrations/google-service-account-dqv3Bo
|
||||
- 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
|
||||
- arn:aws:secretsmanager:us-east-1:011934824531:secret:meal-order-manager/slack-bot-token-ZGmSGw
|
||||
- !Ref AWS::NoValue
|
||||
|
||||
# WorkloadDynamoDB: enumerated union of front-integrations CRUD +
|
||||
# procurement-ingest CRUD/stream actions. Meal-order table ARNs appended.
|
||||
# Stream actions on non-stream tables are inert at the ceiling.
|
||||
- !If
|
||||
- IsProdAccount
|
||||
- Sid: WorkloadDynamoDB
|
||||
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/front-sla-alerts"
|
||||
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/front-sla-alerts/index/*"
|
||||
- !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/work-orders"
|
||||
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/work-orders/*"
|
||||
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/work-order-comments"
|
||||
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/work-order-comments/*"
|
||||
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/meal-order-manager-orders"
|
||||
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/meal-order-manager-orders/index/*"
|
||||
- !Ref AWS::NoValue
|
||||
|
||||
# ── procurement-ingest remaining data plane + meal-order S3 (PLAT-86/70) ─
|
||||
# WorkloadS3 keeps the prior ProcurementIngestS3 action list and appends
|
||||
# meal-order form/reports bucket ARNs (same object CRUD shape).
|
||||
- !If
|
||||
- IsProdAccount
|
||||
- Sid: WorkloadS3
|
||||
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}/*"
|
||||
- !Sub "arn:aws:s3:::meal-order-manager-form-${AWS::AccountId}"
|
||||
- !Sub "arn:aws:s3:::meal-order-manager-form-${AWS::AccountId}/*"
|
||||
- !Sub "arn:aws:s3:::meal-order-manager-reports-${AWS::AccountId}"
|
||||
- !Sub "arn:aws:s3:::meal-order-manager-reports-${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
|
||||
# site-alerts publish shared by procurement-ingest alarms and
|
||||
# meal-order-manager (PLAT-70); no separate MealOrder SNS statement.
|
||||
- !If
|
||||
- IsProdAccount
|
||||
- Sid: ProcurementIngestSns
|
||||
Effect: Allow
|
||||
Action:
|
||||
- sns:Publish
|
||||
Resource:
|
||||
- !Sub "arn:aws:sns:us-east-1:${AWS::AccountId}:site-alerts"
|
||||
- !Ref AWS::NoValue
|
||||
|
||||
# ── seahaven-site (PLAT-91) — content-deploy role data plane ────────
|
||||
# TF creates githubdeploy-seahaven-site under /tf-managed/ with this
|
||||
# boundary as ceiling. Role policy is S3 sync + CloudFront invalidate
|
||||
# only; no Lambda. Exact origin bucket + distribution-scoped invalidate.
|
||||
- !If
|
||||
- IsProdAccount
|
||||
- Sid: SeahavenSiteOriginS3
|
||||
Effect: Allow
|
||||
Action:
|
||||
- s3:GetObject
|
||||
- s3:PutObject
|
||||
- s3:DeleteObject
|
||||
- s3:GetObjectTagging
|
||||
- s3:PutObjectTagging
|
||||
- s3:ListBucket
|
||||
- s3:GetBucketLocation
|
||||
Resource:
|
||||
- arn:aws:s3:::seahaven-site-prod
|
||||
- arn:aws:s3:::seahaven-site-prod/*
|
||||
- !Ref AWS::NoValue
|
||||
- !If
|
||||
- IsProdAccount
|
||||
- Sid: SeahavenSiteCloudFrontInvalidate
|
||||
Effect: Allow
|
||||
Action:
|
||||
- cloudfront:CreateInvalidation
|
||||
- cloudfront:GetInvalidation
|
||||
Resource:
|
||||
- !Sub "arn:aws:cloudfront::${AWS::AccountId}:distribution/*"
|
||||
- !Ref AWS::NoValue
|
||||
|
||||
# ── meal-order-manager (PLAT-70 / PLAT-100) — not covered above ─────
|
||||
# Secrets → WorkloadSecrets; DynamoDB → WorkloadDynamoDB; S3 → WorkloadS3;
|
||||
# SNS → ProcurementIngestSns. SSM + Lambda Invoke + execute-api share
|
||||
# one Sid (scoped Resources only) so PolicySize stays under 6,144 —
|
||||
# a standalone execute-api Sid is ~243 chars against 241 headroom and
|
||||
# would fail UPDATE with LimitExceeded. SES stays in its own Sid:
|
||||
# Resource:"*" must not share a statement with execute-api:Invoke
|
||||
# (that would allow Invoke on every API in the account).
|
||||
# Weekly-menu OIDC identity policy pins the API id; boundary pins
|
||||
# method/path only.
|
||||
- !If
|
||||
- IsProdAccount
|
||||
- Sid: MealOrderManager
|
||||
Effect: Allow
|
||||
Action:
|
||||
- ssm:GetParameter
|
||||
- lambda:InvokeFunction
|
||||
- execute-api:Invoke
|
||||
Resource:
|
||||
- !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/meal-order-manager/*"
|
||||
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:meal-order-manager-*"
|
||||
- !Sub "arn:aws:execute-api:us-east-1:${AWS::AccountId}:*/*/GET/api/publish/settings"
|
||||
- !Sub "arn:aws:execute-api:us-east-1:${AWS::AccountId}:*/*/POST/api/publish/menu"
|
||||
- !Ref AWS::NoValue
|
||||
- !If
|
||||
- IsProdAccount
|
||||
- Sid: MealOrderManagerSes
|
||||
Effect: Allow
|
||||
Action:
|
||||
- ses:SendRawEmail
|
||||
Resource: "*"
|
||||
- !Ref AWS::NoValue
|
||||
|
||||
# ── FURTHER PER-WORKLOAD DATA-PLANE ────────────────────────────────
|
||||
# Do not add statements here. Remaining SAM stacks: create
|
||||
# seahaven-lambda-execution-boundary-<stack> below and append its ARN
|
||||
# to SamCfnIamManagementPolicy only (WIDENING PATH). New HCP stacks
|
||||
# do not append here. This shared document stays unchanged until live
|
||||
# roles retarget (PLAT-52 phase 2) and PermissionsBoundaryUsageCount
|
||||
# reaches 0.
|
||||
# Do not add statements here. The shared document is the four-statement
|
||||
# floor (PLAT-52). Remaining SAM stacks use
|
||||
# seahaven-lambda-execution-boundary-<stack> below. New HCP stacks
|
||||
# do not append here.
|
||||
# ---------------------------------------------------------------------------
|
||||
# Per-workload Lambda execution boundaries (PLAT-52 phase 1)
|
||||
#
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue