feat(iam): add paychex-integrations hcptf roles and boundary

This commit is contained in:
Adam Moussa 2026-08-27 15:39:16 -04:00
parent 608c11ed0a
commit 25bef0a621
No known key found for this signature in database
2 changed files with 218 additions and 4 deletions

View file

@ -147,13 +147,14 @@ Description: >-
# seahaven-lambda-execution-boundary-procurement-ingest: 3977 / 11 statements
# seahaven-lambda-execution-boundary-meal-order-manager: 2380 / 10 statements
# seahaven-lambda-execution-boundary-seahaven-site: 1159 / 6 statements
# seahaven-lambda-execution-boundary-paychex-integrations: floor-only (PLAT-120)
# Dev copies are floor-only (691 / 4) via IsProdAccount.
#
# Guardrail PolicyDocuments also cap at 6,144. Each extra allow-list ARN
# is copied into four Sids in EACH of SamCfnIamManagementPolicy and
# HcptfIamManagementPolicy. Measured after this list (6 ARNs):
# seahaven-cfn-exec-iam-management: 4571 / 10 statements (1573 headroom)
# seahaven-hcptf-iam-management: 4693 / 10 statements (1451 headroom)
# HcptfIamManagementPolicy. Measured after this list (7 ARNs, PLAT-120):
# seahaven-cfn-exec-iam-management: 4571 / 10 statements before seventh ARN
# seahaven-hcptf-iam-management: 4693 / 10 statements before seventh ARN
#
# CRITICAL: a role has exactly ONE permissions boundary, so statements cannot
# be spilled into a second attached managed policy. Do not introduce
@ -366,6 +367,16 @@ Resources:
# - no IAM permissions for S3 / SQS / SSM / SES / KMS / VPC in this
# stack's template as of 2026-07-30
#
# paychex-integrations (functions: paychex-*, PLAT-120)
# - Authority: Sea-Haven-Industries/paychex-integrations terraform/
# (placeholder Lambda). Floor only in this PR: secrets do not exist
# yet so exact GetSecretValue ARNs cannot be pinned. Do NOT add
# secret:paychex-integrations/* patterns. After first HCP apply,
# widen with the six minted secret ARNs.
# - CloudWatch Logs (floor)
# - no DynamoDB / EventBridge / S3 data plane / SES / KMS / VPC in the
# scaffold Terraform
#
# afi-backup-monitor (functions: afi-*)
# - secretsmanager:GetSecretValue on TWO exact prod secret ARNs
# (PLAT-56, created 2026-08-05 in seahaven-prod; no name patterns):
@ -836,6 +847,23 @@ Resources:
- !Sub "arn:aws:dynamodb:us-east-1:${AWS::AccountId}:table/front-sla-alerts/index/*"
- !Ref AWS::NoValue
PaychexIntegrationsBoundary:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: seahaven-lambda-execution-boundary-paychex-integrations
Description: >-
Per-workload permissions boundary for paychex-integrations (PLAT-120).
Floor only until first HCP apply mints secret suffixes.
PolicyDocument:
Version: "2012-10-17"
Statement:
# Floor aliases — edit the &lambdaBoundaryFloor* anchors on
# AfiBackupMonitorBoundary only; do not inline a divergent copy.
- *lambdaBoundaryFloorLogsWrite
- *lambdaBoundaryFloorLogsDescribe
- *lambdaBoundaryFloorXRay
- *lambdaBoundaryFloorEc2Eni
ProcurementIngestBoundary:
Type: AWS::IAM::ManagedPolicy
Properties:
@ -1648,6 +1676,7 @@ Resources:
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-procurement-ingest"
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-meal-order-manager"
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-seahaven-site"
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-paychex-integrations"
# Attach managed policies — MUST have boundary already on role
- Sid: IAMAttachPolicyWithBoundary

View file

@ -82,7 +82,8 @@ Description: >-
# len(json.dumps(doc,separators=(',',':'))) on the synthesized PolicyDocument
# — the same wall the role INLINE limit (10,240 bytes) put the first
# deploy-substrate deploy into on 2026-07-27. Compact size recorded after
# synth in this PR: 4693 characters / 10 statements (1451 headroom).
# synth with 6 ARNs: 4693 characters / 10 statements (1451 headroom).
# PLAT-120 adds a seventh allow-list ARN (~380 characters across four Sids).
#
# PER-WORKSPACE ROLE ACCUMULATOR
# At each stack's migration, a PR appends to this template:
@ -211,6 +212,7 @@ Resources:
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-procurement-ingest"
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-meal-order-manager"
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-seahaven-site"
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-paychex-integrations"
# Attach managed policies — MUST have boundary already on role
- Sid: IAMAttachPolicyWithBoundary
@ -738,6 +740,189 @@ Resources:
Resource:
- !Sub "arn:aws:sns:us-east-1:${AWS::AccountId}:site-alerts"
# ---------------------------------------------------------------------------
# paychex-integrations (PLAT-120) — plan + apply roles for workspace
# paychex-integrations-prod. Copy shape from front-integrations; scaffold
# first apply is Lambda + artifact bucket + alarms + secret shells only
# (no EventBridge, no DynamoDB). Secret Get/Put value stays off the apply
# role. Lambda execution boundary is floor-only until first apply mints
# secret suffixes.
# ---------------------------------------------------------------------------
HcptfPaychexIntegrationsPlanRole:
Type: AWS::IAM::Role
Condition: IsProdAccount
Properties:
RoleName: hcptf-paychex-integrations-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:paychex-integrations-prod:run_phase:plan
ManagedPolicyArns:
- arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
Policies:
- PolicyName: paychex-integrations-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/paychex-*"
- Sid: RefreshManagedPolicies
Effect: Allow
Action:
- iam:GetPolicy
- iam:GetPolicyVersion
Resource: "*"
- Sid: RefreshLambda
Effect: Allow
Action:
- lambda:Get*
- lambda:List*
Resource:
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:paychex-*"
- Sid: RefreshArtifactsBucket
Effect: Allow
Action:
- s3:Get*
- s3:ListBucket
Resource:
- !Sub "arn:aws:s3:::paychex-integrations-artifacts-${AWS::AccountId}"
- !Sub "arn:aws:s3:::paychex-integrations-artifacts-${AWS::AccountId}/*"
- Sid: RefreshCloudWatchAlarms
Effect: Allow
Action:
- cloudwatch:DescribeAlarms
- cloudwatch:ListTagsForResource
Resource:
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:paychex-*"
- Sid: RefreshLogs
Effect: Allow
Action:
- logs:DescribeLogGroups
- logs:ListTagsForResource
Resource: "*"
- Sid: RefreshSecrets
Effect: Allow
Action:
- secretsmanager:DescribeSecret
- secretsmanager:GetResourcePolicy
- secretsmanager:ListSecretVersionIds
Resource:
- !Sub "arn:aws:secretsmanager:us-east-1:${AWS::AccountId}:secret:paychex-integrations/*"
HcptfPaychexIntegrationsApplyRole:
Type: AWS::IAM::Role
Condition: IsProdAccount
Properties:
RoleName: hcptf-paychex-integrations
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:paychex-integrations-prod:run_phase:apply
ManagedPolicyArns:
- !Ref HcptfIamManagementPolicy
Policies:
- PolicyName: paychex-integrations-services
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: LambdaAll
Effect: Allow
Action:
- lambda:*
Resource:
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:paychex-*"
- Sid: LambdaList
Effect: Allow
Action:
- lambda:ListFunctions
- lambda:ListLayers
- lambda:GetAccountSettings
Resource: "*"
- Sid: CloudWatchLogs
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:DeleteLogGroup
- logs:PutRetentionPolicy
- logs:DeleteRetentionPolicy
- logs:TagResource
- logs:UntagResource
- logs:ListTagsForResource
Resource:
- !Sub "arn:aws:logs:us-east-1:${AWS::AccountId}:log-group:/aws/lambda/paychex-*"
- Sid: CloudWatchLogsDescribe
Effect: Allow
Action:
- logs:DescribeLogGroups
Resource: "*"
- Sid: LambdaArtifactsBucket
Effect: Allow
Action:
- s3:*
Resource:
- !Sub "arn:aws:s3:::paychex-integrations-artifacts-${AWS::AccountId}"
- !Sub "arn:aws:s3:::paychex-integrations-artifacts-${AWS::AccountId}/*"
- Sid: CloudWatchAlarms
Effect: Allow
Action:
- cloudwatch:*
Resource:
- !Sub "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:paychex-*"
- Sid: SiteAlertsSns
Effect: Allow
Action:
- sns:Publish
- sns:GetTopicAttributes
Resource:
- !Sub "arn:aws:sns:us-east-1:${AWS::AccountId}:site-alerts"
- Sid: PaychexSecretShell
Effect: Allow
Action:
- secretsmanager:DeleteSecret
- secretsmanager:DescribeSecret
- secretsmanager:GetResourcePolicy
- secretsmanager:PutResourcePolicy
- secretsmanager:DeleteResourcePolicy
- secretsmanager:TagResource
- secretsmanager:UntagResource
Resource:
- !Sub "arn:aws:secretsmanager:us-east-1:${AWS::AccountId}:secret:paychex-integrations/*"
- Sid: PaychexSecretCreate
Effect: Allow
Action:
- secretsmanager:CreateSecret
Resource: "*"
Condition:
StringEquals:
"secretsmanager:Name":
- paychex-integrations/oauth-client
- paychex-integrations/webhook-api-key
- paychex-integrations/google-service-account
- paychex-integrations/slack-bot-token
- paychex-integrations/front-inboxes-write
- paychex-integrations/3cx-system-admin
# ---------------------------------------------------------------------------
# Per-workspace hcptf-* roles for sh-openswe-traces-prod (PLAT-73).
#