mirror of
https://github.com/Sea-Haven-Industries/seahaven-org-baseline.git
synced 2026-10-07 12:38:55 +00:00
Merge 2b814d1705 into ff492de58d
This commit is contained in:
commit
bbc4180908
1 changed files with 28 additions and 238 deletions
|
|
@ -134,9 +134,11 @@ Description: >-
|
||||||
# on the synthesized PolicyDocument with ${AWS::AccountId} resolved, and UPDATE
|
# on the synthesized PolicyDocument with ${AWS::AccountId} resolved, and UPDATE
|
||||||
# THE NUMBERS in the same edit.
|
# THE NUMBERS in the same edit.
|
||||||
#
|
#
|
||||||
# Shared LambdaExecutionBoundary (legacy ceiling; do not widen): 5986
|
# Shared LambdaExecutionBoundary (floor only; do not widen): 708
|
||||||
# characters / 15 statements as of 2026-08-10 (PLAT-100). Headroom 158.
|
# characters / 4 statements as of 2026-09-28 (PLAT-52). Headroom 5436.
|
||||||
# Leave it unchanged until live roles retarget (PLAT-52 phase 2).
|
# 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
|
# Per-workload policies (floor + own data plane). Compact sizes recorded
|
||||||
# after synth (prod, ${AWS::AccountId}=011934824531):
|
# after synth (prod, ${AWS::AccountId}=011934824531):
|
||||||
|
|
@ -147,9 +149,10 @@ Description: >-
|
||||||
# seahaven-lambda-execution-boundary-seahaven-site: 1159 / 6 statements
|
# seahaven-lambda-execution-boundary-seahaven-site: 1159 / 6 statements
|
||||||
# seahaven-lambda-execution-boundary-seahaven-door-unlock-api: measure after deploy (PLAT-76)
|
# seahaven-lambda-execution-boundary-seahaven-door-unlock-api: measure after deploy (PLAT-76)
|
||||||
# seahaven-lambda-execution-boundary-paychex-integrations: 3250 / 10 statements (PLAT-228)
|
# seahaven-lambda-execution-boundary-paychex-integrations: 3250 / 10 statements (PLAT-228)
|
||||||
# Dev copies are floor-only (691 / 4) via IsProdAccount, except
|
# The same four floor statements measure 708 / 4 on the dev policies once
|
||||||
# meal-order-manager (PLAT-210): DynamoDB/S3/SSM/invoke plus the
|
# IsProdAccount drops the prod-only statements. meal-order-manager
|
||||||
# seahaven-dev slack-bot-token ARN. SNS, SQS (Paychex), and SES stay prod.
|
# (PLAT-210) also keeps DynamoDB/S3/SSM/invoke plus the seahaven-dev
|
||||||
|
# slack-bot-token ARN. SNS, SQS (Paychex), and SES stay prod.
|
||||||
#
|
#
|
||||||
# Guardrail PolicyDocuments also cap at 6,144. Each extra allow-list ARN
|
# Guardrail PolicyDocuments also cap at 6,144. Each extra allow-list ARN
|
||||||
# is copied into four Sids in EACH of SamCfnIamManagementPolicy and
|
# is copied into four Sids in EACH of SamCfnIamManagementPolicy and
|
||||||
|
|
@ -214,16 +217,15 @@ Resources:
|
||||||
# intersection of the role's own policies and this boundary, so a misconfigured
|
# intersection of the role's own policies and this boundary, so a misconfigured
|
||||||
# SAM role can never exceed what is listed here.
|
# SAM role can never exceed what is listed here.
|
||||||
#
|
#
|
||||||
# SCOPING RULE (PLAT-52 phase 1, 2026-08-13). New workloads get their own
|
# SCOPING RULE (PLAT-52). New workloads get their own ManagedPolicy
|
||||||
# ManagedPolicy seahaven-lambda-execution-boundary-<workload>: the fleet-wide
|
# seahaven-lambda-execution-boundary-<workload>: the four-statement floor
|
||||||
# floor (CloudWatchLogsWrite / CloudWatchLogsDescribe / XRay / Ec2Eni) plus
|
# (CloudWatchLogsWrite / CloudWatchLogsDescribe / XRay / Ec2Eni) plus that
|
||||||
# that workload's data plane, derived from ITS OWN template. Do not add new
|
# workload's data plane, derived from its own template. The shared
|
||||||
# data-plane statements to the shared seahaven-lambda-execution-boundary
|
# seahaven-lambda-execution-boundary document is that same four-statement
|
||||||
# document — it is the legacy ceiling for roles not yet retargeted and stays
|
# floor. Do not add data-plane statements to it. PermissionsBoundaryUsageCount
|
||||||
# unchanged until PermissionsBoundaryUsageCount is 0. INFRA-186 reduced this
|
# is 0 in prod and dev, so the packed IsProdAccount statements are removed.
|
||||||
# copy to a floor and later migrations packed data plane back into it under
|
# Retiring the SAM allow-list of boundary ARNs in SamCfnIamManagementPolicy
|
||||||
# the 6,144-character cap (PLAT-93 / PLAT-100). Per-workload policies are
|
# is a follow-up pull request.
|
||||||
# the escape hatch from that cap and from the shared-ceiling residual.
|
|
||||||
#
|
#
|
||||||
# A resource pattern that genuinely CANNOT be scoped keeps its wildcard WITH a
|
# A resource pattern that genuinely CANNOT be scoped keeps its wildcard WITH a
|
||||||
# written justification on the statement: CloudWatchLogsDescribe, XRay and
|
# written justification on the statement: CloudWatchLogsDescribe, XRay and
|
||||||
|
|
@ -523,232 +525,20 @@ Resources:
|
||||||
- ec2:DescribeVpcs
|
- ec2:DescribeVpcs
|
||||||
Resource: "*"
|
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 ────────────────────────────────
|
# ── FURTHER PER-WORKLOAD DATA-PLANE ────────────────────────────────
|
||||||
# Do not add statements here. Remaining SAM stacks: create
|
# Do not add statements here. The shared document is the four-statement
|
||||||
# seahaven-lambda-execution-boundary-<stack> below and append its ARN
|
# floor (PLAT-52). Remaining SAM stacks use
|
||||||
# to SamCfnIamManagementPolicy only (WIDENING PATH). New HCP stacks
|
# seahaven-lambda-execution-boundary-<stack> below. New HCP stacks
|
||||||
# do not append here. This shared document stays unchanged until live
|
# do not append here.
|
||||||
# roles retarget (PLAT-52 phase 2) and PermissionsBoundaryUsageCount
|
|
||||||
# reaches 0.
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Per-workload Lambda execution boundaries (PLAT-52 phase 1)
|
# Per-workload Lambda execution boundaries (PLAT-52 phase 1)
|
||||||
#
|
#
|
||||||
# Each policy is the fleet floor plus that workload's data plane, split from
|
# Each policy is the fleet floor plus that workload's data plane.
|
||||||
# the shared document above without editing it. Live roles keep the shared
|
# Guardrail StringEquals lists still include the shared ARN and each
|
||||||
# ARN until app-repo retargets. Guardrail StringEquals lists include both.
|
# per-workload ARN until the allow-list follow-up. Floor statements are
|
||||||
# Floor statements are YAML-anchored on AfiBackupMonitorBoundary; later
|
# YAML-anchored on AfiBackupMonitorBoundary; later policies alias them.
|
||||||
# policies alias them. Floor rationale lives on LambdaExecutionBoundary.
|
# Floor rationale lives on LambdaExecutionBoundary.
|
||||||
# Prod-only data plane stays behind IsProdAccount (same as the shared copy).
|
# Prod-only data plane on these policies stays behind IsProdAccount.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
AfiBackupMonitorBoundary:
|
AfiBackupMonitorBoundary:
|
||||||
Type: AWS::IAM::ManagedPolicy
|
Type: AWS::IAM::ManagedPolicy
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue