sh-openswe-traces/bootstrap.yaml

210 lines
9.1 KiB
YAML
Raw Permalink Normal View History

AWSTemplateFormatVersion: "2010-09-09"
Description: >
Bootstrap IAM for the sh-openswe-traces app stack. Deployed ONCE, manually, under
admin (CAPABILITY_NAMED_IAM). Creates two named roles so CI never touches the shared
github-cfn-execution-role:
- DeployRole (githubdeploy-sh-openswe-traces): assumed by this repo's GitHub
Actions via OIDC (main branch only); can drive CloudFormation for THIS stack and
pass the exec role.
- ExecRole (sh-openswe-traces-cfn-exec-role): assumed by CloudFormation to create
the app stack's resources; least-privilege to exactly this stack's resource set.
Resources:
ExecRole:
Type: AWS::IAM::Role
Properties:
RoleName: sh-openswe-traces-cfn-exec-role
Description: CloudFormation execution role for the sh-openswe-traces app stack.
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: cloudformation.amazonaws.com
Action: sts:AssumeRole
Condition:
StringEquals:
"aws:SourceAccount": !Ref "AWS::AccountId"
Policies:
- PolicyName: manage-sh-openswe-traces-resources
PolicyDocument:
Version: "2012-10-17"
Statement:
# Defense-in-depth: this role can create sh-openswe-traces-* users, so
# explicitly forbid the actions that would turn one into a usable/escalated
# principal (credentials, console login, extra policies, boundary removal).
- Sid: DenyUserCredentialAndEscalation
Effect: Deny
Action:
- "iam:CreateAccessKey"
- "iam:CreateLoginProfile"
- "iam:UpdateLoginProfile"
- "iam:AttachUserPolicy"
- "iam:CreateServiceSpecificCredential"
- "iam:PutUserPermissionsBoundary"
- "iam:DeleteUserPermissionsBoundary"
Resource: "*"
- Sid: Buckets
Effect: Allow
Action:
- "s3:CreateBucket"
- "s3:DeleteBucket"
- "s3:PutBucketPolicy"
- "s3:DeleteBucketPolicy"
- "s3:GetBucketPolicy"
- "s3:PutEncryptionConfiguration"
- "s3:GetEncryptionConfiguration"
- "s3:PutBucketVersioning"
- "s3:GetBucketVersioning"
- "s3:PutBucketPublicAccessBlock"
- "s3:GetBucketPublicAccessBlock"
- "s3:PutBucketOwnershipControls"
- "s3:GetBucketOwnershipControls"
- "s3:PutLifecycleConfiguration"
- "s3:GetLifecycleConfiguration"
- "s3:PutBucketLogging"
- "s3:GetBucketLogging"
- "s3:PutBucketTagging"
- "s3:GetBucketTagging"
- "s3:GetBucketLocation"
- "s3:GetBucketAcl"
Resource:
- "arn:aws:s3:::sh-openswe-traces"
- "arn:aws:s3:::sh-openswe-traces-logs"
# CreateKey/CreateAlias cannot be resource-scoped (the key does not yet
# exist). Only CloudFormation can assume this role, and only to deploy this
# stack, so the blast radius is bounded to this stack's deployments.
- Sid: Kms
Effect: Allow
Action:
- "kms:CreateKey"
- "kms:CreateAlias"
- "kms:DeleteAlias"
- "kms:UpdateAlias"
- "kms:PutKeyPolicy"
- "kms:GetKeyPolicy"
- "kms:EnableKeyRotation"
- "kms:DisableKeyRotation"
- "kms:GetKeyRotationStatus"
- "kms:DescribeKey"
- "kms:TagResource"
- "kms:UntagResource"
- "kms:ListResourceTags"
- "kms:ScheduleKeyDeletion"
- "kms:EnableKey"
Resource: "*"
- Sid: Secret
Effect: Allow
Action:
- "secretsmanager:CreateSecret"
- "secretsmanager:DeleteSecret"
- "secretsmanager:DescribeSecret"
- "secretsmanager:UpdateSecret"
- "secretsmanager:TagResource"
- "secretsmanager:UntagResource"
- "secretsmanager:GetResourcePolicy"
- "secretsmanager:PutResourcePolicy"
Resource: !Sub "arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:sh-openswe/*"
- Sid: ExportUser
Effect: Allow
Action:
- "iam:CreateUser"
- "iam:DeleteUser"
- "iam:GetUser"
- "iam:TagUser"
- "iam:UntagUser"
- "iam:PutUserPolicy"
- "iam:DeleteUserPolicy"
- "iam:GetUserPolicy"
- "iam:ListUserPolicies"
- "iam:ListUserTags"
- "iam:ListAttachedUserPolicies"
- "iam:ListGroupsForUser"
Resource: !Sub "arn:aws:iam::${AWS::AccountId}:user/sh-openswe-traces-*"
# Required because template.yaml uses Transform: AWS::Serverless-2016-10-31.
# CloudFormation (as this exec role) must CreateChangeSet on the AWS-managed
# SAM transform macro. Scoped to only that transform ARN.
- Sid: SamTransform
Effect: Allow
Action: "cloudformation:CreateChangeSet"
Resource: !Sub "arn:aws:cloudformation:${AWS::Region}:aws:transform/Serverless-2016-10-31"
DeployRole:
Type: AWS::IAM::Role
Properties:
RoleName: githubdeploy-sh-openswe-traces
Description: GitHub Actions OIDC deploy role for the sh-openswe-traces app stack.
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Federated: !Sub "arn:aws:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com"
Action: sts:AssumeRoleWithWebIdentity
Condition:
StringEquals:
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
"token.actions.githubusercontent.com:sub": "repo:Sea-Haven-Industries/sh-openswe-traces:ref:refs/heads/main"
Policies:
- PolicyName: deploy-sh-openswe-traces
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: AppStack
Effect: Allow
Action:
- "cloudformation:CreateChangeSet"
- "cloudformation:ExecuteChangeSet"
- "cloudformation:DescribeChangeSet"
- "cloudformation:DeleteChangeSet"
- "cloudformation:CreateStack"
- "cloudformation:UpdateStack"
- "cloudformation:DescribeStacks"
- "cloudformation:DescribeStackEvents"
- "cloudformation:DescribeStackResource"
- "cloudformation:DescribeStackResources"
- "cloudformation:ListStackResources"
- "cloudformation:GetTemplate"
- "cloudformation:GetTemplateSummary"
Resource:
- !Sub "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/sh-openswe-traces/*"
- !Sub "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:changeSet/*/*"
# SAM's --resolve-s3 looks up (does not recreate) the pre-existing managed
# artifact stack + bucket.
- Sid: SamManagedStackRead
Effect: Allow
Action:
- "cloudformation:DescribeStacks"
Resource: !Sub "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/aws-sam-cli-managed-default/*"
- Sid: SamArtifactBucket
Effect: Allow
Action:
- "s3:GetObject"
- "s3:PutObject"
- "s3:GetBucketLocation"
- "s3:ListBucket"
Resource:
- "arn:aws:s3:::aws-sam-cli-managed-default-*"
- "arn:aws:s3:::aws-sam-cli-managed-default-*/*"
- Sid: CfnValidate
Effect: Allow
Action:
- "cloudformation:ValidateTemplate"
Resource: "*"
- Sid: PassExecRoleToCfn
Effect: Allow
Action: "iam:PassRole"
Resource: !GetAtt ExecRole.Arn
Condition:
StringEquals:
"iam:PassedToService": cloudformation.amazonaws.com
Outputs:
DeployRoleArn:
Description: Set as the repo secret AWS_DEPLOY_ROLE_ARN.
Value: !GetAtt DeployRole.Arn
ExecRoleArn:
Description: Set as cfn-role-arn in .github/workflows/deploy.yaml.
Value: !GetAtt ExecRole.Arn