mirror of
https://github.com/Sea-Haven-Industries/seahaven-account-baseline.git
synced 2026-08-04 16:56:14 +00:00
Promote account trail to organization trail (INFRA-73)
INFRA-73: set isOrganizationTrail on seahaven-org-trail and pass orgId (o-9kufuzz6b4) so the L2 Trail attaches the AWSLogs/<org-id>/* bucket PutObject statement for member-account delivery. CloudTrail org trusted-access is already enabled on the management account. Broaden the KMS key policy with an org-scoped GenerateDataKey/DescribeKey statement for member-account trail delivery, guarded by aws:PrincipalOrgID. The existing single-account statements are preserved so management-account delivery is unaffected. Cross-review (GPT-4.1) BLOCK: the member KMS SourceArn and encryption context must be wildcarded across accounts (org-trail shadow trails present the member account id), not pinned to the management account, or member delivery silently fails. Fixed before checkpoint. CHECKPOINT: delicate org-trail KMS/bucket-policy change — code + diff captured for review, NOT deployed. Refs: INFRA-73
This commit is contained in:
parent
ec5c939d58
commit
b2071e9df1
1 changed files with 38 additions and 0 deletions
|
|
@ -37,6 +37,10 @@ export class AccountBaselineStack extends cdk.Stack {
|
|||
super(scope, id, props);
|
||||
|
||||
const trailName = "seahaven-org-trail";
|
||||
// AWS Organizations org id (o-9kufuzz6b4). CloudTrail org trusted-access is
|
||||
// already enabled on the management account; promoting this trail to an org
|
||||
// trail (INFRA-73) makes it collect member-account events into this bucket.
|
||||
const orgId = "o-9kufuzz6b4";
|
||||
// Static trail ARN (built from name, not trail.trailArn) so the key policy
|
||||
// does not create a circular dependency with the Trail resource.
|
||||
const trailArn = cdk.Arn.format(
|
||||
|
|
@ -71,6 +75,33 @@ export class AccountBaselineStack extends cdk.Stack {
|
|||
},
|
||||
})
|
||||
);
|
||||
// INFRA-73 (org trail): member accounts deliver their CloudTrail events to
|
||||
// this CMK-encrypted bucket, so the CloudTrail service principal must be able
|
||||
// to GenerateDataKey using each member trail's own encryption context.
|
||||
//
|
||||
// Cross-review BLOCK (GPT-4.1): the SourceArn must NOT be pinned to the
|
||||
// management account 328440206208 — org-trail shadow trails in member
|
||||
// accounts present their OWN account id in both the SourceArn and the
|
||||
// encryption-context arn, so pinning to the management account would silently
|
||||
// block all member-account delivery. Both are wildcarded across accounts and
|
||||
// the statement is org-scoped by aws:PrincipalOrgID so only accounts in
|
||||
// o-9kufuzz6b4 — not arbitrary CloudTrail principals — can use the key.
|
||||
trailKey.addToResourcePolicy(
|
||||
new iam.PolicyStatement({
|
||||
sid: "AllowOrgMemberCloudTrailEncrypt",
|
||||
effect: iam.Effect.ALLOW,
|
||||
principals: [new iam.ServicePrincipal("cloudtrail.amazonaws.com")],
|
||||
actions: ["kms:GenerateDataKey*", "kms:DescribeKey"],
|
||||
resources: ["*"],
|
||||
conditions: {
|
||||
StringEquals: { "aws:PrincipalOrgID": orgId },
|
||||
StringLike: {
|
||||
"kms:EncryptionContext:aws:cloudtrail:arn": `arn:${this.partition}:cloudtrail:*:*:trail/*`,
|
||||
"aws:SourceArn": `arn:${this.partition}:cloudtrail:*:*:trail/*`,
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
trailKey.addToResourcePolicy(
|
||||
new iam.PolicyStatement({
|
||||
sid: "AllowCloudTrailDescribeKey",
|
||||
|
|
@ -132,6 +163,13 @@ export class AccountBaselineStack extends cdk.Stack {
|
|||
bucket: logBucket,
|
||||
encryptionKey: trailKey,
|
||||
isMultiRegionTrail: true,
|
||||
// INFRA-73: promote to an organization trail. CloudTrail org
|
||||
// trusted-access is already enabled on the management account; this makes
|
||||
// the trail collect every member account's events into this bucket.
|
||||
// Passing orgId lets the L2 construct auto-attach the AWSLogs/<orgId>/*
|
||||
// bucket-policy PutObject statement (scoped to this trail's SourceArn).
|
||||
isOrganizationTrail: true,
|
||||
orgId,
|
||||
includeGlobalServiceEvents: true,
|
||||
enableFileValidation: true,
|
||||
sendToCloudWatchLogs: true,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue