feat(iam): add paychex-integrations hcptf roles and boundary (PLAT-120) (#124)

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

* fix(iam): split paychex plan lambda list onto Resource *
This commit is contained in:
Adam Moussa 2026-08-27 21:50:11 +00:00 • committed by GitHub
parent 689ec147a3
commit e5e7980508
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 224 additions and 2 deletions

View file

@ -148,13 +148,15 @@ Description: >-
# seahaven-lambda-execution-boundary-meal-order-manager: 2380 / 10 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-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 (7 ARNs, PLAT-76):
# HcptfIamManagementPolicy. Measured after PLAT-76 (7 ARNs):
# seahaven-cfn-exec-iam-management: 4571 / 10 statements (1573 headroom)
# seahaven-hcptf-iam-management: 4693 / 10 statements (1451 headroom)
# PLAT-120 adds an 8th ARN (paychex-integrations). Re-measure after deploy.
#
# CRITICAL: a role has exactly ONE permissions boundary, so statements cannot
# be spilled into a second attached managed policy. Do not introduce
@ -367,6 +369,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):
@ -837,6 +849,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:
@ -1691,6 +1720,7 @@ Resources:
- !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-seahaven-door-unlock-api"
- !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,9 @@ 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-76 added a seventh ARN. PLAT-120 adds an eighth (paychex-integrations,
# ~380 characters across four Sids). Re-measure after deploy.
#
# PER-WORKSPACE ROLE ACCUMULATOR
# At each stack's migration, a PR appends to this template:
@ -212,6 +214,7 @@ Resources:
- !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-seahaven-door-unlock-api"
- !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary-paychex-integrations"
# Attach managed policies — MUST have boundary already on role
- Sid: IAMAttachPolicyWithBoundary
@ -739,6 +742,195 @@ 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*
Resource:
- !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:paychex-*"
# Collection/list APIs authorize only against Resource "*".
- Sid: RefreshLambdaList
Effect: Allow
Action:
- lambda:ListFunctions
- lambda:GetAccountSettings
Resource: "*"
- 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).
#