Skip to main content
友田 陽大
AWS CloudTrail audit & governance
AWS
CloudTrail
AWS Organizations
マルチアカウント
ガバナンス
Terraform

Building a Company-Wide CloudTrail Audit Platform with AWS Organizations (2026 Edition): Aggregating Every Account's Trail with Organization Trails, Delegated Administrators, a Log Archive Account, SCPs, and Control Tower

Explains, faithful to the official docs, the design for governing CloudTrail company-wide in a multi-account environment. Auto-apply to all members with an organization trail, operate from the audit team via a delegated administrator, aggregate into a dedicated log archive account, prevent disabling the trail with SCPs, and build Control Tower integration and cross-account analysis in real code.

Published
Reading time
20 min read
Author
友田 陽大
Share

"Is CloudTrail actually enabled in all your accounts?" — not many organizations can answer immediately when an audit firm asks this.

Accounts grow. dev, staging, prod, per team, per product, per acquisition. Before you know it, 10, 20 accounts line up, and in each someone individually configured CloudTrail (or forgot), the logs are scattered across separate buckets, and cross-cutting investigation is impossible — this is the most common audit breakdown you see in a multi-account environment.

I've designed and operated a multi-account, multi-tier-commerce B2B SaaS and a serverless (Lambda + DynamoDB) payment platform reliability layer, maintaining 0 double charges in production. From that experience, I can assert that an audit platform will definitely break down unless you "enforce it with the organization's code" rather than "each account's goodwill." Accounts may grow infinitely. But aggregate the audit in one place and fix it in a tamper-proof form. This is the core of multi-account governance.

This article is an implementation guide for designing CloudTrail as "the company-wide audit platform" on the premise of AWS Organizations. It assembles, end to end in real Terraform / JSON / CLI code, organization trails, delegated administrators, the log archive account, SCPs, and Control Tower.

This article's premise and related articles: The mechanism of CloudTrail alone (the 4 event types / how to create a trail / SSE-KMS / log integrity validation / official security BPs) is not repeated in this article. For the basics, see the pillar article AWS CloudTrail complete guide. This article digs deep specialized in multi-account / organization trails. The specs, pricing, and conditions have been checked against the AWS official documentation (as of June 2026), but always confirm the latest docs before going to production. Account IDs, organization IDs, and bucket names are illustrative.


0. Mental model: "accounts grow. The audit is aggregated in one place"

Before starting the design, let me pin down the target big picture in one line.

A company-wide CloudTrail audit platform = create just one organization trail, and aggregate all member accounts' trails into a centralized bucket in a dedicated log archive account, in a tamper-proof form.

As a diagram, it's this.

AWS Organizations (all features enabled)
│
├─ 管理アカウント (Management account) ── ※SCPが効かない特別なアカウント
│   └─ 組織トレイル(organization trail)を所有
│        └─ 委任管理者(Security/Audit account)へ運用を委譲
│
├─ ログアーカイブアカウント (Log Archive account)
│   └─ 集中S3バケット (SSE-KMS + 整合性検証 + Object Lock)
│        └─ AWSLogs/<組織ID>/<アカウントID>/CloudTrail/<region>/...
│             ↑ 全メンバーのログがここに集まる
│
├─ メンバーアカウント A (prod)  ── トレイルは「見える」が変更不可
├─ メンバーアカウント B (dev)   ── 同上。SCPでStopLogging等をDeny
└─ メンバーアカウント C (...)   ── アカウント追加時に自動でトレイル適用

Each element of this diagram — "one organization trail," "delegate to a delegated administrator," "aggregate into the log archive account," "protect with SCPs" — we'll now assemble in code one by one. First, let me articulate why per-account trails break down.


1. Why per-account trails break down

The multi-account approach of "create an individual trail in each account" works while the scale is small, but it inevitably collapses on four problems.

ProblemWhat happens with per-account trails
ProliferationYou manually create a trail every time an account grows. The settings (encryption, region, integrity validation) waver per account
GapsYou forget to create a trail in a new account. You can't prove "all accounts enabled" (you're stuck in an audit)
Tampering riskEach account's admin can StopLogging / DeleteTrail their own trail. A compromised attacker erases the trail first
No cross-cutting investigationLogs scatter across separate buckets per account, and you can't follow "who changed an IAM policy across the whole organization" in one query

What structurally solves these four is the organization trail. It realizes "auto-apply to all accounts, members can't change it, logs aggregated in one place" as an organization feature. Let me look at them in order.


2. How an organization trail works: create once, auto-apply to all members

2-1. The 5 properties the official docs guarantee

An organization trail is a special trail integrated with AWS Organizations. Let me accurately pin down the properties the official documentation guarantees (source: Creating a trail for an organization).

PropertyThe official guarantee
Creation originCreated in the management account, or a delegated administrator account
Auto-apply"When you create an organization trail, a copy of the trail with the same name is created in each member account that belongs to the organization." Even if an account is added later, "the organization trail and the service-linked role are automatically added, and logging for that account starts automatically"
Members can't change itMember-account users can view the organization trail with describe-trails etc., but "do not have sufficient permissions to delete the organization trail, toggle logging on/off, change the event types being recorded, or make any other change"
Logs not viewable (default)"By default, only the management account can access the trail's S3 bucket and the logs in it." Members can't even see their own logs
Common ARNThe trail's ARN is identical across all member accounts (e.g. arn:aws:cloudtrail:us-east-1:111111111111:trail/MyOrgTrail)

This is what pays off. Even a member-account admin can't stop or delete the organization trail. This is the core of an audit platform that "doesn't depend on each account's goodwill."

2-2. Prerequisites (when creating with CLI/Terraform)

Unless you meet the prerequisites the official docs require, you can't create an organization trail (source: Prepare for creating a trail for your organization).

  • "All features" must be enabled in the organization. You can't create it with "consolidated billing only."
  • Trusted access for CloudTrail must be enabled in Organizations. If you create it with CLI/API, you need to enable it manually (it's implicitly enabled at console creation).
  • The management account needs the AWSServiceRoleForCloudTrail service-linked role (so CloudTrail can record logs in each member).

Cost caution: an organization trail is created in addition even if a member account has an existing trail. If a member has "a second trail collecting the same management events," the second copy is billed (the first copy of management events per region is free). Once you introduce the organization trail, tidy up the member-side duplicate trails. For pricing details, see the CloudTrail pricing-optimization guide.

2-3. Create an organization trail with Terraform

Specify is_organization_trail = true on the aws_cloudtrail resource. The CLI/Terraform default is single-region, so for company-wide audit always make is_multi_region_trail = true explicit.

# 管理アカウント(または委任管理者アカウント)のプロバイダで実行する。
# S3バケットとKMSキーは ログアーカイブアカウント側にある(後述)。

resource "aws_cloudtrail" "org" {
  name = "org-audit-trail"

  # ── ログアーカイブアカウントの集中バケット ──
  s3_bucket_name = "org-cloudtrail-logs-central" # Log Archiveアカウントのバケット
  kms_key_id     = var.central_kms_key_arn       # 同アカウントのCMK

  # ── 全社監査の必須設定 ──
  is_organization_trail         = true # ★全メンバーに自動適用
  is_multi_region_trail         = true # ★全リージョンを記録(既定はsingle)
  enable_log_file_validation    = true # ★ログ整合性検証(SHA-256 digest)
  include_global_service_events = true # IAM/STS等のグローバルイベント

  # 管理イベントは全アカウント分を確実に記録
  advanced_event_selector {
    name = "Log all management events"
    field_selector {
      field  = "eventCategory"
      equals = ["Management"]
    }
  }

  depends_on = [aws_organizations_organization.this] # 信頼されたアクセスを先に
}

The Terraform AWS provider's is_organization_trail states clearly "Can only be created in the organization master account." Even when creating from a delegated administrator, the organization's management account becomes the owner.

With this, "one organization trail" is up. But as-is, owning and operating the trail is all done in the management account. Next, let me delegate this to the audit team.


3. Separate governance with a delegated administrator

3-1. Why a delegated administrator is needed

The management account (the billing parent account) is the most powerful account in the organization. Using its credentials for daily operation violates the principle of least privilege. So CloudTrail supports a delegated administrator.

Delegated administrator = a member account in the organization that can perform the same management tasks as the management account in CloudTrail (with some exceptions) (source: Delegated administrator).

With this, you can operate the organization trail from a dedicated security / audit team account, and limit the management account to just "changing the organization's structure." It's standard for the Security Tooling account in the AWS Security Reference Architecture (SRA) to play this role.

ItemOfficial spec
Maximum numberUp to 3 CloudTrail delegated administrators per organization
OwnershipResources like trails created by a delegated administrator have their owner stay the management account. Resources aren't deleted even if you deregister the delegated administrator
Registration originOnly the management account's admin can register a delegated administrator
What a delegated administrator can't doAdding/removing delegated administrators, converting the organization trail to account-level, etc. are management-account-only

3-2. Register a delegated administrator (CLI)

Register with CloudTrail's native API (run in the management account).

# 管理アカウントで実行: メンバーアカウント(Security/Auditアカウント)を委任管理者に登録
aws cloudtrail register-organization-delegated-admin \
  --member-account-id 222222222222

When deregistering, note that the parameter name changes from --member-account-id to --delegated-admin-account-id (confirmed in the official CLI reference).

# 委任管理者を解除する(管理アカウントで実行)
aws cloudtrail deregister-organization-delegated-admin \
  --delegated-admin-account-id 222222222222

When registered with CloudTrail's native CLI/API, the necessary service-linked roles (AWSServiceRoleForCloudTrail etc.) are auto-created. On the other hand, when registered with the Organizations-side CLI/API (organizations register-delegated-administrator), CloudTrail's service-linked role is not auto-created. Using CloudTrail's command is safe.

3-3. The IAM permissions needed for registration

The IAM principal that assigns / deregisters a delegated administrator needs the following actions defined by the official docs (source: Required permissions to assign a delegated administrator).

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AssignDelegatedAdminForCloudTrail",
      "Effect": "Allow",
      "Action": [
        "cloudtrail:RegisterOrganizationDelegatedAdmin",
        "cloudtrail:DeregisterOrganizationDelegatedAdmin",
        "organizations:RegisterDelegatedAdministrator",
        "organizations:DeregisterDelegatedAdministrator",
        "organizations:ListAWSServiceAccessForOrganization",
        "iam:CreateServiceLinkedRole",
        "iam:GetRole"
      ],
      "Resource": "*"
    }
  ]
}

Note: this delegated-administrator-assignment policy does not include organizations:EnableAWSServiceAccess or organizations:ListAccounts. Those are permissions of a separate policy needed for "creating the organization trail." Don't confuse the roles. CloudTrail's service principal is cloudtrail.amazonaws.com, and the one for event context is context.cloudtrail.amazonaws.com.

With this, the permission separation of "operation in the audit team's account, ownership in the management account" is complete. Next, let me fix the log aggregation destination to a dedicated account.


4. Aggregate into a log archive account (AWS SRA-compliant)

4-1. Why a dedicated account

Putting the organization trail's logs in the management account's or a production account's bucket is a bad move. The AWS Security Reference Architecture (SRA) recommends aggregating all security logs into a dedicated "Log Archive account" (source: Security OU – Log Archive account).

"The Log Archive account is dedicated to ingesting and archiving all security-related logs and backups. The key logs shown in the AWS SRA include CloudTrail (organization trail)."

The SRA's account structure has these three as the basis.

AccountRole
Org Management accountOwns the organization. Allows CloudTrail's trusted access and creates/owns the organization trail
Security Tooling accountThe delegated administrator of security services. Operates the organization trail from here
Log Archive accountHolds the centralized S3 bucket + KMS key. All accounts' logs gather here

For accuracy (a caution close to UNVERIFIED): in the SRA's authoritative description, the organization trail itself is created/owned by the management account via trusted access, and logs are aggregated into the Log Archive account's bucket. "Delegating CloudTrail to the Security Tooling account" is possible (§3), but CloudTrail is not listed in the service list (Config, GuardDuty, Security Hub, etc.) that the SRA explicitly delegates to a delegated administrator. Using a delegated administrator is a valid option, but grasp that the SRA's standard form is "the management account owns the organization trail, and logs are aggregated into Log Archive."

4-2. The S3 bucket policy for the organization trail (HCL)

The bucket policy for an organization trail has a different resource ARN from a single-account one. The official docs define three statements (source: Amazon S3 bucket policy for CloudTrail – organization trail).

  • AclCheck: s3:GetBucketAcl (the bucket ARN)
  • Write (the management account's portion): AWSLogs/<management account ID>/* — for when you revert the organization trail to a single-account trail
  • OrganizationWrite: AWSLogs/<org ID>/* — the organization's path (not the account ID but the organization ID o-xxxxxxxxxx)

What's important is that all three's aws:SourceArn are the trail ARN using the management account ID. The official docs state clearly that "for an organization trail, the value of aws:SourceArn must be a trail ARN that is owned by and uses the management account ID."

# ログアーカイブアカウントのプロバイダで実行する。
# 例: bucket=org-cloudtrail-logs-central, org=o-abc123example,
#     mgmt account=111111111111, region=us-east-1, trail=org-audit-trail

data "aws_iam_policy_document" "org_trail_bucket" {
  # 1) ACLチェック
  statement {
    sid     = "AWSCloudTrailAclCheck20150319"
    effect  = "Allow"
    actions = ["s3:GetBucketAcl"]
    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }
    resources = [aws_s3_bucket.central.arn]
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = [local.org_trail_arn] # arn:aws:cloudtrail:us-east-1:111111111111:trail/org-audit-trail
    }
  }

  # 2) 管理アカウント分の書き込み(組織トレイル→単一に戻す場合の保険)
  statement {
    sid     = "AWSCloudTrailWrite20150319"
    effect  = "Allow"
    actions = ["s3:PutObject"]
    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }
    resources = ["${aws_s3_bucket.central.arn}/AWSLogs/111111111111/*"]
    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"
      values   = ["bucket-owner-full-control"]
    }
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = [local.org_trail_arn]
    }
  }

  # 3) ★組織全体の書き込み(組織IDのパス)
  statement {
    sid     = "AWSCloudTrailOrganizationWrite20150319"
    effect  = "Allow"
    actions = ["s3:PutObject"]
    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }
    resources = ["${aws_s3_bucket.central.arn}/AWSLogs/o-abc123example/*"]
    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"
      values   = ["bucket-owner-full-control"]
    }
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = [local.org_trail_arn]
    }
  }
}

aws:SourceOrgID can also be used: as a confused-deputy countermeasure, in addition to aws:SourceArn / aws:SourceAccount, AWS supports the global condition key aws:SourceOrgID and recommends it for restricting access per organization (source: IAM confused deputy). Setting aws:SourceOrgID to the organization ID prevents "CloudTrail logs from outside the organization writing to the bucket." But the official organization-trail standard example is composed with aws:SourceArn + the organization-ID path, and the accurate understanding is to use aws:SourceOrgID as a condition key that reinforces it.

4-3. The KMS key policy (so CloudTrail can encrypt with the CMK)

If you encrypt the centralized bucket with SSE-KMS, the CMK's key policy needs a statement allowing CloudTrail's encryption (source: Configure AWS KMS key policies for CloudTrail).

{
  "Sid": "AllowCloudTrailEncryptLogs",
  "Effect": "Allow",
  "Principal": { "Service": "cloudtrail.amazonaws.com" },
  "Action": "kms:GenerateDataKey*",
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "aws:SourceArn": "arn:aws:cloudtrail:us-east-1:111111111111:trail/org-audit-trail"
    },
    "StringLike": {
      "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:111111111111:trail/*"
    }
  }
}

Using the organization trail's ARN (management account ID) for aws:SourceArn, and the management account ID for the aws:SourceAccount equivalent, is the caution unique to an organization trail.

4-4. Harden tamper-resistance "with code"

The log archive bucket needs to be protected from both attackers and operators. In addition to the pillar article's security BPs, in multi-account, fix the following especially.

  • S3 Object Lock (compliance mode) or MFA Delete: make overwriting/deleting logs physically impossible.
  • Lifecycle: tier migration to Glacier and a retention period per compliance requirements.
  • Least privilege: other than the audit team's read, the only writer to the bucket is the CloudTrail service principal.
  • Minimize granting AWSCloudTrail_FullAccess: this managed policy can disable the most important audit functions. The SRA also warns "grant it to as few people as possible."

5. Protect the trail with SCPs: organizationally enforce "can't be stopped"

An organization trail guarantees that "members can't change that trail," but room remains for a member to do other mischief in their own account (e.g. attack the log-destination bucket, disable Insights). So with SCPs (Service Control Policies), organizationally Deny CloudTrail's disabling operations themselves.

5-1. An SCP that forbids disabling the trail

AWS Control Tower's mandatory control "Disallow Configuration Changes to CloudTrail" is exactly the AWS-native SCP for this purpose. Generalized, it takes this form.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ProtectCloudTrail",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:StopLogging",
        "cloudtrail:DeleteTrail",
        "cloudtrail:UpdateTrail",
        "cloudtrail:PutEventSelectors"
      ],
      "Resource": "*"
    }
  ]
}

Control Tower's native version excepts automation roles while narrowing the target to its own trail ARN (reference: Control Tower mandatory controls).

{
  "Sid": "GRCLOUDTRAILENABLED",
  "Effect": "Deny",
  "Action": [
    "cloudtrail:DeleteTrail",
    "cloudtrail:PutEventSelectors",
    "cloudtrail:StopLogging",
    "cloudtrail:UpdateTrail"
  ],
  "Resource": ["arn:aws:cloudtrail:*:*:trail/aws-controltower-*"],
  "Condition": {
    "ArnNotLike": {
      "aws:PrincipalARN": "arn:aws:iam::*:role/AWSControlTowerExecution"
    }
  }
}

5-2. The design crux: SCPs don't apply to the management account

Miss this and the design collapses. The official docs state it repeatedly (source: Service control policies (SCPs)).

"SCPs don't affect users or roles in the management account. They affect only member accounts." "Tasks SCPs can't restrict: any action performed by the management account"

That is —

  • SCPs can prevent "a member account disabling the trail." SCPs apply even to a member account designated as a delegated administrator.
  • SCPs can't prevent anything "that happens in the management account" at all. If the management account owns the organization trail, you can't protect that trail with SCPs. The management account's access must be protected by other means (strict IAM, credential storage, CloudTrail event monitoring).
  • SCPs can only be used in an organization with "all features" enabled. They can't be used in a consolidated-billing-only organization.

Excluding the management account's credentials from daily operation (§3's delegated administrator) and making operations in the management account itself a monitoring target — how to fill "the area SCPs can't protect" is where governance design shows its skill. AWS-official SCP samples are also aggregated at aws-samples/service-control-policy-examples.


6. When using Control Tower: choosing between auto-configuration and self-building

Instead of assembling all of the above yourself, use AWS Control Tower's landing zone and the organization trail and the log archive / audit accounts are auto-configured.

6-1. What Control Tower auto-configures

The official statement (source: Logging with CloudTrail).

"AWS Control Tower configures a new CloudTrail trail during landing-zone setup. This is an organization-level trail that records all events in the management account and all member accounts."

What Control Tower createsContent
Organization trailDeploys an organization-level CloudTrail trail in the management account (via trusted access)
Log Archive accountDefault name "Log archive." A shared account holding an S3 bucket that centrally stores all logs
Audit accountDefault name "Audit." A shared account for cross-account security auditing
Mandatory SCPsAuto-applies SCPs forbidding encryption/lifecycle changes to CloudTrail/Config buckets, StopLogging, etc.

A historically important change (confirmed): Control Tower once created individual trails in each member account, but migrated to an organization trail in landing zone version 3.0. The official docs state clearly that "when you update to 3.0, the CloudTrail trail becomes an organization trail. Each account-level trail is deleted, but the existing log files are retained in the S3 bucket." The old-article description "Control Tower creates a trail per account" is now wrong.

6-2. Self-build vs. Control Tower

AspectSelf-build (this article §2-5)Control Tower
Startup speedSlow (you assemble everything)Fast (the landing zone configures it all at once)
FlexibilityHigh (can fully fit requirements)Medium (within Control Tower's frame; since 3.0, you can opt out of organization-trail management and self-operate)
GuardrailsWrite SCPs yourselfMandatory / recommended controls come standard
Suited caseAn existing custom multi-account, wanting to manage everything with IaCAbout to launch an organization, getting best-practice compliance fastest

The option for Control Tower to use your own organization trail / operate a separate self-built trail is provided since landing zone 3.0 (you can opt out and manage CloudTrail yourself). Note that Control Tower operates its own organization trail with the management account's trusted access, and does not register a CloudTrail delegated administrator.


7. Company-wide cross-cutting investigation: cross-account Athena and Lake

Once logs gather in one place, you can investigate the whole organization in one query.

The standard pattern where the audit personnel (the Audit account) query the Log Archive account's centralized bucket with Athena. Because the bucket is KMS-encrypted, AWS requires three permissions (source: Athena cross-account access).

  1. The Log Archive account's S3 bucket policy allows the Audit account's assumed role s3:GetObject / s3:ListBucket etc.
  2. The Log Archive account's KMS key policy allows the same role kms:Decrypt / kms:DescribeKey etc.
  3. The Audit account's IAM role allows access to the counterpart bucket and key.

With these in place, you can ask, against a table with an organization-ID partition, like this.

-- 組織全体で、過去24時間に「ルートユーザー」が行った操作をすべて洗い出す
SELECT eventtime, recipientaccountid, eventsource, eventname, sourceipaddress
FROM org_cloudtrail_logs
WHERE useridentity.type = 'Root'
  AND eventtime > to_iso8601(current_timestamp - interval '1' day)
ORDER BY eventtime DESC;

Knowing which member account's operation it is by recipientaccountid is a strength unique to an organization trail. For details of Athena partition design and partition projection, see the pillar article's Athena section.

7-2. CloudTrail Lake's organization event data store (current caution)

CloudTrail Lake's organization event data store aggregates events of all accounts and multiple regions in the organization into one place, and you can cross-query with Trino-compatible SQL. It can be created from the management account or a delegated administrator, and even if a delegated administrator creates it, the substance exists in the management account.

Important (confirmed): CloudTrail Lake ended new-customer onboarding as of May 31, 2026 (existing customers can continue using it). The official docs state that "Lake receives only critical bug fixes and security updates" and recommend migrating Lake data to Amazon CloudWatch (source: CloudTrail Lake service availability change). If you're building a company-wide audit platform newly from now, it's realistic to place Athena + centralized S3 as the mainline for the analysis platform.

Flow the organization trail to EventBridge / CloudWatch Logs and you can detect "a root-user login," "a StopLogging attempt," etc. across the organization in near real time. I leave the design of threat detection / incident response to the sister articles threat detection and incident response with CloudTrail and GuardDuty multi-account threat detection. This article's main focus is "a platform that aggregates and preserves the trail company-wide."


8. Summary: a company-wide CloudTrail audit-platform checklist

A multi-account CloudTrail audit platform holds only when you "enforce it with the organization's code," not "each account's goodwill." Finally, let me close with a pre-production checklist.

Organization trail

  • "All features" enabled in the organization
  • CloudTrail's trusted access enabled
  • One organization trail created (is_organization_trail = true)
  • Multi-region (is_multi_region_trail = true; CLI/TF default is single)
  • Log integrity validation (enable_log_file_validation = true)
  • Include global service events

Governance separation

  • Register the Security/Audit account as a delegated administrator (don't use the management account's credentials for daily operation)
  • Understand that delegated administrators are max 3 and the owner stays the management account

Log aggregation (SRA-compliant)

  • A centralized S3 bucket in a dedicated log archive account
  • An organization-trail bucket policy (AWSLogs/<org ID>/*, aws:SourceArn is the management account's trail ARN)
  • SSE-KMS (an aws:SourceArn condition in the CMK key policy)
  • S3 Object Lock / MFA Delete, lifecycle, least privilege
  • Minimize granting AWSCloudTrail_FullAccess

Trail preservation

  • Deny StopLogging / DeleteTrail / UpdateTrail / PutEventSelectors with SCPs
  • On the premise that SCPs don't apply to the management account, defend the management account by other means

Cross-cutting investigation

  • Cross-account Athena (the 3-point permission of S3 + KMS + IAM)
  • Make the analysis platform for a new build Athena + S3 as the mainline (Lake ended new onboarding)

Accounts will keep growing. As the business grows, teams increase, acquisitions happen, and environments split. It's fine for them to grow — as long as the audit is aggregated in one place, fixed in a tamper-proof form, and enforced by the organization's code.

In a structure of one person × generative AI (Claude Code), I've designed and operated a multi-account, multi-tier-commerce B2B SaaS and a serverless payment platform with 0 double charges in production, fast and safely. Its crux is always "guaranteeing correctness with the structure of code and governance, not operational vigilance." This article's organization trail, delegated administrator, SCPs, and log archive account are exactly that philosophy embodied on AWS Organizations.

Consultation on company-wide AWS governance: "Accounts grew and I can't keep up with the audit," "I want to design a landing zone with code," "An audit firm asked for the trail" — such challenges are structurally solved with the design of an organization trail and a log archive account. For consultation on multi-account governance / landing-zone design, reach out from contact. Together with keyless CI/CD (GitHub Actions OIDC) and cost optimization (Terraform FinOps), I design a fast, cheap, and safe AWS platform end to end.

友田

友田 陽大

Developer of a METI Minister's Award–winning product. With TypeScript + Python + AWS, I deliver SaaS, industry DX, and production-grade generative AI (RAG) end to end — from requirements to infrastructure and operations — single-handedly.

Got a challenge?

From design to implementation and operations — solo × generative AI

Implementation like this article's, end to end from requirements to production. Start with a free 30-minute technical consult and tell me about your situation.

Available for both project-based (contract) and advisory engagements. Start with a free 30-minute consult.

Also worth reading