Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cdk/bootstrap/BOOTSTRAP_HASH
Original file line number Diff line number Diff line change
@@ -1 +1 @@
40d0a8b2343663084f614423fc3e6210761377dedf0bc079956ba7d4cea84c5e
4591304250a01e0d9e45d6890ab09a0b69aa6199b1149399fbb6418a91d1d77d
2 changes: 1 addition & 1 deletion cdk/bootstrap/BOOTSTRAP_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.3.0
1.4.0
44 changes: 40 additions & 4 deletions cdk/bootstrap/bootstrap-template.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# GENERATED FILE - DO NOT EDIT DIRECTLY
# This template is generated by: npx tsx scripts/generate-bootstrap-template.ts
# ABCA Bootstrap Policy Version: 1.3.0
# ABCA Bootstrap Policy Hash: 40d0a8b2343663084f614423fc3e6210761377dedf0bc079956ba7d4cea84c5e
# ABCA Bootstrap Policy Version: 1.4.0
# ABCA Bootstrap Policy Hash: 4591304250a01e0d9e45d6890ab09a0b69aa6199b1149399fbb6418a91d1d77d
#
# Based on the default CDK bootstrap template with the following modifications:
# - BootstrapVariant set to "ABCA: Least-Privilege Bootstrap"
Expand Down Expand Up @@ -1119,6 +1119,21 @@ Resources:
Effect: Allow
Resource: arn:aws:sqs:*:*:backgroundagent-dev-*
Sid: SQS
- Action:
- sns:CreateTopic
- sns:DeleteTopic
- sns:GetTopicAttributes
- sns:SetTopicAttributes
- sns:Subscribe
- sns:Unsubscribe
- sns:GetSubscriptionAttributes
- sns:ListSubscriptionsByTopic
- sns:TagResource
- sns:UntagResource
- sns:ListTagsForResource
Effect: Allow
Resource: arn:aws:sns:*:*:backgroundagent-dev-*
Sid: SNS
- Action:
- cloudfront:CreateDistribution
- cloudfront:UpdateDistribution
Expand Down Expand Up @@ -1269,6 +1284,27 @@ Resources:
Effect: Allow
Resource: '*'
Sid: KMSForCDKAssets
- Action:
- kms:CreateKey
- kms:GetKeyPolicy
- kms:GetKeyRotationStatus
- kms:TagResource
- kms:ListResourceTags
Effect: Allow
Resource: '*'
Sid: KMSCustomerManagedKeys
- Action:
- kms:PutKeyPolicy
- kms:ScheduleKeyDeletion
- kms:EnableKeyRotation
- kms:DisableKeyRotation
- kms:UntagResource
Condition:
StringEquals:
aws:ResourceTag/ABCA: operational-alerts
Effect: Allow
Resource: '*'
Sid: KMSCustomerManagedKeysLifecycle
- Action:
- ecr:CreateRepository
- ecr:DescribeRepositories
Expand Down Expand Up @@ -1420,10 +1456,10 @@ Outputs:
Value: '32'
BootstrapPolicyVersion:
Description: The version of the ABCA bootstrap policy bundle
Value: 1.3.0
Value: 1.4.0
BootstrapPolicyHash:
Description: SHA-256 hash of the ABCA bootstrap policy bundle for drift detection
Value: 40d0a8b2343663084f614423fc3e6210761377dedf0bc079956ba7d4cea84c5e
Value: 4591304250a01e0d9e45d6890ab09a0b69aa6199b1149399fbb6418a91d1d77d
BootstrapPolicySet:
Description: Comma-separated list of active ABCA bootstrap policy names
Value:
Expand Down
18 changes: 18 additions & 0 deletions cdk/bootstrap/policies/application.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,24 @@
"Resource": "arn:aws:sqs:*:*:backgroundagent-dev-*",
"Sid": "SQS"
},
{
"Action": [
"sns:CreateTopic",
"sns:DeleteTopic",
"sns:GetTopicAttributes",
"sns:SetTopicAttributes",
"sns:Subscribe",
"sns:Unsubscribe",
"sns:GetSubscriptionAttributes",
"sns:ListSubscriptionsByTopic",
"sns:TagResource",
"sns:UntagResource",
"sns:ListTagsForResource"
],
"Effect": "Allow",
"Resource": "arn:aws:sns:*:*:backgroundagent-dev-*",
"Sid": "SNS"
},
{
"Action": [
"cloudfront:CreateDistribution",
Expand Down
29 changes: 29 additions & 0 deletions cdk/bootstrap/policies/observability.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,35 @@
"Resource": "*",
"Sid": "KMSForCDKAssets"
},
{
"Action": [
"kms:CreateKey",
"kms:GetKeyPolicy",
"kms:GetKeyRotationStatus",
"kms:TagResource",
"kms:ListResourceTags"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "KMSCustomerManagedKeys"
},
{
"Action": [
"kms:PutKeyPolicy",
"kms:ScheduleKeyDeletion",
"kms:EnableKeyRotation",
"kms:DisableKeyRotation",
"kms:UntagResource"
],
"Condition": {
"StringEquals": {
"aws:ResourceTag/ABCA": "operational-alerts"
}
},
"Effect": "Allow",
"Resource": "*",
"Sid": "KMSCustomerManagedKeysLifecycle"
},
{
"Action": [
"ecr:CreateRepository",
Expand Down
19 changes: 19 additions & 0 deletions cdk/src/bootstrap/policies/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,25 @@ export function applicationPolicy(): iam.PolicyDocument {
resources: ['arn:aws:sqs:*:*:backgroundagent-dev-*'],
}),

new iam.PolicyStatement({
sid: 'SNS',
effect: iam.Effect.ALLOW,
actions: [
'sns:CreateTopic',
'sns:DeleteTopic',
'sns:GetTopicAttributes',
'sns:SetTopicAttributes',
'sns:Subscribe',
'sns:Unsubscribe',
'sns:GetSubscriptionAttributes',
'sns:ListSubscriptionsByTopic',
'sns:TagResource',
'sns:UntagResource',
'sns:ListTagsForResource',
],
resources: ['arn:aws:sns:*:*:backgroundagent-dev-*'],
}),

new iam.PolicyStatement({
sid: 'CloudFront',
effect: iam.Effect.ALLOW,
Expand Down
46 changes: 46 additions & 0 deletions cdk/src/bootstrap/policies/observability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,52 @@ export function observabilityPolicy(): iam.PolicyDocument {
resources: ['*'],
}),

new iam.PolicyStatement({
// Create/read/tag for customer-managed keys the stack provisions
// (e.g. the OperationalAlerts SNS topic key, issue #629), distinct
// from the CDK bootstrap asset key above. kms:CreateKey cannot be
// resource-scoped (the key ARN does not exist yet) and CMK ARNs
// are UUIDs, so `*` is unavoidable here. This statement holds only
// create + read + tag actions — none can escalate privilege on an
// existing key. kms:TagResource must stay unconditioned because it
// applies the very `ABCA` tag that scopes the mutation statement
// below (a tag condition would deny the call that sets the tag).
sid: 'KMSCustomerManagedKeys',
effect: iam.Effect.ALLOW,
actions: [
'kms:CreateKey',
'kms:GetKeyPolicy',
'kms:GetKeyRotationStatus',
'kms:TagResource',
'kms:ListResourceTags',
],
resources: ['*'],
}),

new iam.PolicyStatement({
// Policy-mutation and deletion actions that COULD take over or
// destroy an unrelated account CMK if granted on `*`. CMK ARNs are
// UUIDs (still unscopable), so instead we gate them on the `ABCA`
// resource tag that the OperationalAlerts construct stamps on its
// key at creation (CloudFormation tags atomically in the CreateKey
// call, so an existing key always carries the tag by the time any
// of these run). This bounds the blast radius to keys this
// solution owns. Issue #629 review — MEDIUM 2.
sid: 'KMSCustomerManagedKeysLifecycle',
effect: iam.Effect.ALLOW,
actions: [
'kms:PutKeyPolicy',
'kms:ScheduleKeyDeletion',
'kms:EnableKeyRotation',
'kms:DisableKeyRotation',
'kms:UntagResource',
],
resources: ['*'],
conditions: {
StringEquals: { 'aws:ResourceTag/ABCA': 'operational-alerts' },
},
}),

new iam.PolicyStatement({
sid: 'ECRForDockerAssets',
effect: iam.Effect.ALLOW,
Expand Down
4 changes: 4 additions & 0 deletions cdk/src/bootstrap/resource-action-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const CFN_TYPES_WITHOUT_EXEC_ROLE_IAM = new Set([
'AWS::ApiGateway::Stage',
'AWS::ApiGateway::Account',
'AWS::S3::BucketPolicy',
'AWS::SNS::TopicPolicy',
'AWS::SQS::QueuePolicy',
'AWS::EC2::VPCGatewayAttachment',
'AWS::EC2::SubnetRouteTableAssociation',
Expand Down Expand Up @@ -77,6 +78,7 @@ export const RESOURCE_ACTION_MAP: Record<string, readonly string[]> = {
'AWS::Events::Rule': ['events:PutRule'],
'AWS::IAM::Policy': ['iam:CreatePolicy', 'iam:PutRolePolicy'],
'AWS::IAM::Role': ['iam:CreateRole'],
'AWS::KMS::Key': ['kms:CreateKey'],
'AWS::Lambda::EventInvokeConfig': ['lambda:PutFunctionEventInvokeConfig'],
'AWS::Lambda::EventSourceMapping': ['lambda:CreateEventSourceMapping'],
'AWS::Lambda::Function': ['lambda:CreateFunction'],
Expand All @@ -98,6 +100,8 @@ export const RESOURCE_ACTION_MAP: Record<string, readonly string[]> = {
'AWS::Route53Resolver::ResolverQueryLoggingConfigAssociation': ['route53resolver:AssociateResolverQueryLogConfig'],
'AWS::S3::Bucket': ['s3:CreateBucket'],
'AWS::SecretsManager::Secret': ['secretsmanager:CreateSecret'],
'AWS::SNS::Subscription': ['sns:Subscribe'],
'AWS::SNS::Topic': ['sns:CreateTopic'],
'AWS::SQS::Queue': ['sqs:CreateQueue'],
'AWS::WAFv2::WebACL': ['wafv2:CreateWebACL'],
'AWS::WAFv2::WebACLAssociation': ['wafv2:AssociateWebACL'],
Expand Down
8 changes: 5 additions & 3 deletions cdk/src/bootstrap/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import { allPolicies } from './policies';
*
* Bump history: 1.0.0 → 1.1.0 added the `compute-ecs` policy (#162), 1.1.0 →
* 1.2.0 refreshed policies for a full deploy (#350), 1.2.0 → 1.3.0 adds the
* `compute-lambda-microvm` policy (#645 / ADR-021). Adding a policy to the
* bundle is a minor bump — that is the precedent `compute-ecs` set.
* `compute-lambda-microvm` policy (#645 / ADR-021), 1.3.0 → 1.4.0 grants SNS
* topic + customer-managed-KMS-key create/lifecycle for the OperationalAlerts
* notification channel (#629). Expanding the granted action set is a minor
* bump — that is the precedent the #350 policy refresh set.
*/
export const BOOTSTRAP_VERSION = '1.3.0';
export const BOOTSTRAP_VERSION = '1.4.0';

/**
* Computes a SHA-256 hash over all bootstrap policies.
Expand Down
Loading
Loading