[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F3M5N2GJK48ZB2CJ8DAMEE":3,"skill-same:01M6F3M5N2GJK48ZB2CJ8DAMEE":73},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":40,"linkOnly":41,"markdownContent":42,"markdownBody":43,"frontMatter":44,"refName":27,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":6,"ownerHtmlUrl":57,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":58,"install":59,"resources":72},"01M6F3M5N2GJK48ZB2CJ8DAMEE","aws-cloudtrail",null,"Configure AWS CloudTrail for audit logging. Set up organization trails and event analysis. Use when auditing AWS activity.","boisenoise\u002Fskills-collections","boisenoise","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F193180?v=4","01M6CDBDQK6BDN55ZMA6B6PKBM","01M6CDBDVSJ3JPTBYN26FZ7TZK",12,"MIT","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-aws-cloudtrail\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"aws cloudtrail","cloudtrail","aws","analysis","2026","when","activity","event","organization","main","community","up","configure","safe","devops-security","SET","audit","license","logging","framework","change","security","2026-11-10 10:12:30",false,"---\nname: aws-cloudtrail\ndescription: Configure AWS CloudTrail for audit logging. Set up organization trails\n  and event analysis. Use when auditing AWS activity.\ncategory: security\nrisk: safe\nsource: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\nsource_repo: BagelHole\u002FDevOps-Security-Agent-Skills\nsource_type: community\ndate_added: '2026-09-20'\nlicense: MIT\nlicense_source: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE\ncompatibility: Checklist and framework guidance; no privileged tooling required. Apply\n  controls through your own change process.\nmetadata:\n  author: devops-skills\n  version: '1.0'\n---\n\n# AWS CloudTrail\n\nAudit AWS account activity with CloudTrail for compliance, security investigation, and operational troubleshooting.\n\n## When to Use\n\n- Enabling organization-wide audit logging across all AWS accounts\n- Investigating security incidents or unauthorized API activity\n- Meeting compliance requirements for SOC 2, HIPAA, PCI DSS, or FedRAMP\n- Setting up automated alerting on sensitive AWS API calls\n- Querying historical AWS activity for forensic analysis\n\n## Prerequisites and Change Scope\n\nVerify the AWS identity, partition, region and organization management\u002Fdelegated-administrator permissions before mutation. All names, account IDs and ARNs below are synthetic placeholders; choose a globally unique owned bucket. Have a working KMS key policy permitting the selected CloudTrail trail and authorized readers, an existing CloudWatch log group and scoped role\u002Ftrust policy before passing their ARNs. The snippets do not provision those dependencies. Review paid data-event\u002FLake\u002FAthena scope and retention costs first. Export existing policies\u002Fselectors\u002Flifecycle settings and merge intended changes; put-* operations can replace existing configuration. Never apply expiration to audit evidence under a legal hold.\n\n## Create an Organization Trail\n\n```bash\n# Create the S3 bucket for log storage\naws s3api create-bucket \\\n  --bucket org-cloudtrail-audit-logs \\\n  --region us-east-1\n# Apply bucket policy allowing CloudTrail to write\naws s3api put-bucket-policy \\\n  --bucket org-cloudtrail-audit-logs \\\n  --policy '{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n      {\n        \"Sid\": \"AWSCloudTrailAclCheck\",\n        \"Effect\": \"Allow\",\n        \"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\n        \"Action\": \"s3:GetBucketAcl\",\n        \"Resource\": \"arn:aws:s3:::org-cloudtrail-audit-logs\",\n        \"Condition\": {\"StringEquals\": {\"aws:SourceArn\": \"arn:aws:cloudtrail:us-east-1:123456789012:trail\u002Forg-audit-trail\"}}\n      },\n      {\n        \"Sid\": \"AWSCloudTrailWrite\",\n        \"Effect\": \"Allow\",\n        \"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\n        \"Action\": \"s3:PutObject\",\n        \"Resource\": [\"arn:aws:s3:::org-cloudtrail-audit-logs\u002FAWSLogs\u002F123456789012\u002F*\", \"arn:aws:s3:::org-cloudtrail-audit-logs\u002FAWSLogs\u002Fo-exampleorgid\u002F*\"],\n        \"Condition\": {\n          \"StringEquals\": {\"s3:x-amz-acl\": \"bucket-owner-full-control\", \"aws:SourceArn\": \"arn:aws:cloudtrail:us-east-1:123456789012:trail\u002Forg-audit-trail\"}\n        }\n      }\n    ]\n  }'\n# Block public access on the audit bucket\naws s3api put-public-access-block \\\n  --bucket org-cloudtrail-audit-logs \\\n  --public-access-block-configuration \\\n    BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\n# Enable version history (not WORM\u002Ftamper prevention)\naws s3api put-bucket-versioning \\\n  --bucket org-cloudtrail-audit-logs \\\n  --versioning-configuration Status=Enabled\n# Enable server-side encryption\naws s3api put-bucket-encryption \\\n  --bucket org-cloudtrail-audit-logs \\\n  --server-side-encryption-configuration '{\n    \"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"aws:kms\", \"KMSMasterKeyID\": \"alias\u002Fcloudtrail-key\"}}]\n  }'\n# Set lifecycle policy for log retention\naws s3api put-bucket-lifecycle-configuration \\\n  --bucket org-cloudtrail-audit-logs \\\n  --lifecycle-configuration '{\n    \"Rules\": [\n      {\n        \"ID\": \"TransitionToGlacier\",\n        \"Status\": \"Enabled\",\n        \"Filter\": {\"Prefix\": \"AWSLogs\u002F\"},\n        \"Transitions\": [\n          {\"Days\": 90, \"StorageClass\": \"GLACIER\"}\n        ]\n      },\n      {\n        \"ID\": \"ExpireOldLogs\",\n        \"Status\": \"Enabled\",\n        \"Filter\": {\"Prefix\": \"AWSLogs\u002F\"},\n        \"Expiration\": {\"Days\": 2555}\n      }\n    ]\n  }'\n# Create the organization trail\naws cloudtrail create-trail \\\n  --name org-audit-trail \\\n  --s3-bucket-name org-cloudtrail-audit-logs \\\n  --is-organization-trail \\\n  --is-multi-region-trail \\\n  --enable-log-file-validation \\\n  --kms-key-id arn:aws:kms:us-east-1:123456789012:alias\u002Fcloudtrail-key \\\n  --cloud-watch-logs-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:CloudTrail:* \\\n  --cloud-watch-logs-role-arn arn:aws:iam::123456789012:role\u002FCloudTrail-CWLogs-Role\n# Start logging\naws cloudtrail start-logging --name org-audit-trail\n```\n\nThe organization prefix must use the real organization ID and the trail ARN must use the management account ID. Log-file validation detects changes; it does not prevent deletion. Versioning alone is not immutable retention. Validate Object Lock\u002Flegal-hold design separately where required.\n\n## Event Selectors for Management and Data Events\n\n```bash\n# Configure advanced event selectors for granular control\naws cloudtrail put-event-selectors \\\n  --trail-name org-audit-trail \\\n  --advanced-event-selectors '[\n    {\n      \"Name\": \"AllManagementEvents\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Management\"]}\n      ]\n    },\n    {\n      \"Name\": \"S3DataEventsForSensitiveBuckets\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Data\"]},\n        {\"Field\": \"resources.type\", \"Equals\": [\"AWS::S3::Object\"]},\n        {\"Field\": \"resources.ARN\", \"StartsWith\": [\n          \"arn:aws:s3:::sensitive-data-bucket\u002F\",\n          \"arn:aws:s3:::pii-bucket\u002F\",\n          \"arn:aws:s3:::financial-data\u002F\"\n        ]}\n      ]\n    },\n    {\n      \"Name\": \"LambdaInvocations\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Data\"]},\n        {\"Field\": \"resources.type\", \"Equals\": [\"AWS::Lambda::Function\"]}\n      ]\n    },\n    {\n      \"Name\": \"DynamoDBDataEvents\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Data\"]},\n        {\"Field\": \"resources.type\", \"Equals\": [\"AWS::DynamoDB::Table\"]}\n      ]\n    }\n  ]'\n```\n\n## CloudWatch Alerts for Sensitive Activity\n\n```bash\n# Create metric filter for unauthorized API calls\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name UnauthorizedAPICalls \\\n  --filter-pattern '{ ($.errorCode = \"*UnauthorizedAccess*\") || ($.errorCode = \"AccessDenied*\") }' \\\n  --metric-transformations \\\n    metricName=UnauthorizedAPICalls,metricNamespace=CloudTrailMetrics,metricValue=1\n# Create alarm for unauthorized calls\naws cloudwatch put-metric-alarm \\\n  --alarm-name UnauthorizedAPICallsAlarm \\\n  --metric-name UnauthorizedAPICalls \\\n  --namespace CloudTrailMetrics \\\n  --statistic Sum \\\n  --period 300 \\\n  --threshold 5 \\\n  --comparison-operator GreaterThanOrEqualToThreshold \\\n  --evaluation-periods 1 \\\n  --alarm-actions arn:aws:sns:us-east-1:123456789012:security-alerts\n# Root account usage alarm\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name RootAccountUsage \\\n  --filter-pattern '{ ($.userIdentity.type = \"Root\") && ($.userIdentity.invokedBy NOT EXISTS) && ($.eventType != \"AwsServiceEvent\") }' \\\n  --metric-transformations \\\n    metricName=RootAccountUsage,metricNamespace=CloudTrailMetrics,metricValue=1\naws cloudwatch put-metric-alarm \\\n  --alarm-name RootAccountUsageAlarm \\\n  --metric-name RootAccountUsage \\\n  --namespace CloudTrailMetrics \\\n  --statistic Sum \\\n  --period 300 \\\n  --threshold 1 \\\n  --comparison-operator GreaterThanOrEqualToThreshold \\\n  --evaluation-periods 1 \\\n  --alarm-actions arn:aws:sns:us-east-1:123456789012:security-alerts\n# Console login without MFA\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name ConsoleLoginWithoutMFA \\\n  --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") }' \\\n  --metric-transformations \\\n    metricName=ConsoleLoginWithoutMFA,metricNamespace=CloudTrailMetrics,metricValue=1\n# IAM policy changes\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name IAMPolicyChanges \\\n  --filter-pattern '{ ($.eventName=CreatePolicy) || ($.eventName=DeletePolicy) || ($.eventName=AttachRolePolicy) || ($.eventName=DetachRolePolicy) || ($.eventName=AttachUserPolicy) || ($.eventName=PutUserPolicy) }' \\\n  --metric-transformations \\\n    metricName=IAMPolicyChanges,metricNamespace=CloudTrailMetrics,metricValue=1\n# Security group changes\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name SecurityGroupChanges \\\n  --filter-pattern '{ ($.eventName=AuthorizeSecurityGroupIngress) || ($.eventName=RevokeSecurityGroupIngress) || ($.eventName=CreateSecurityGroup) || ($.eventName=DeleteSecurityGroup) }' \\\n  --metric-transformations \\\n    metricName=SecurityGroupChanges,metricNamespace=CloudTrailMetrics,metricValue=1\n```\n\n## Athena Queries for CloudTrail Analysis\n\n```sql\n-- Create Athena table for CloudTrail logs\nCREATE EXTERNAL TABLE IF NOT EXISTS cloudtrail_logs (\n  eventVersion STRING,\n  userIdentity STRUCT\u003C\n    type: STRING,\n    principalId: STRING,\n    arn: STRING,\n    accountId: STRING,\n    invokedBy: STRING,\n    accessKeyId: STRING,\n    userName: STRING,\n    sessionContext: STRUCT\u003C\n      attributes: STRUCT\u003CmfaAuthenticated: STRING, creationDate: STRING>,\n      sessionIssuer: STRUCT\u003Ctype: STRING, principalId: STRING, arn: STRING, accountId: STRING, userName: STRING>\n    >\n  >,\n  eventTime STRING,\n  eventSource STRING,\n  eventName STRING,\n  awsRegion STRING,\n  sourceIPAddress STRING,\n  userAgent STRING,\n  errorCode STRING,\n  errorMessage STRING,\n  requestParameters STRING,\n  responseElements STRING,\n  additionalEventData STRING,\n  requestId STRING,\n  eventId STRING,\n  readOnly STRING,\n  resources ARRAY\u003CSTRUCT\u003Carn: STRING, accountId: STRING, type: STRING>>,\n  eventType STRING,\n  recipientAccountId STRING\n)\nPARTITIONED BY (region STRING, year STRING, month STRING, day STRING)\nROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'\nSTORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'\nOUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'\nLOCATION 's3:\u002F\u002Forg-cloudtrail-audit-logs\u002FAWSLogs\u002Fo-exampleorgid\u002F123456789012\u002FCloudTrail\u002F';\n-- Add a known delivered partition before querying (repeat for required account\u002Fdates).\nALTER TABLE cloudtrail_logs ADD IF NOT EXISTS\nPARTITION (region='us-east-1', year='2026', month='10', day='22')\nLOCATION 's3:\u002F\u002Forg-cloudtrail-audit-logs\u002FAWSLogs\u002Fo-exampleorgid\u002F123456789012\u002FCloudTrail\u002Fus-east-1\u002F2026\u002F10\u002F22\u002F';\n-- Find all delete operations in the last 7 days\nSELECT eventTime, userIdentity.arn, eventName, sourceIPAddress,\n       requestParameters\nFROM cloudtrail_logs\nWHERE eventName LIKE '%Delete%'\n  AND eventTime > date_format(date_add('day', -7, current_date), '%Y-%m-%dT%H:%i:%sZ')\nORDER BY eventTime DESC\nLIMIT 100;\n-- Identify console logins outside a synthetic exact-IP allowlist (not CIDR matching)\nSELECT eventTime, userIdentity.userName, sourceIPAddress,\n       additionalEventData\nFROM cloudtrail_logs\nWHERE eventName = 'ConsoleLogin'\n  AND sourceIPAddress NOT IN ('198.51.100.10', '203.0.113.20')\n  AND eventTime > date_format(date_add('day', -30, current_date), '%Y-%m-%dT%H:%i:%sZ')\nORDER BY eventTime DESC;\n-- Access key usage patterns per principal\nSELECT userIdentity.arn,\n       count(*) AS api_call_count,\n       count(DISTINCT eventName) AS unique_actions,\n       count(DISTINCT sourceIPAddress) AS unique_ips,\n       min(eventTime) AS first_seen,\n       max(eventTime) AS last_seen\nFROM cloudtrail_logs\nWHERE eventTime > date_format(date_add('day', -30, current_date), '%Y-%m-%dT%H:%i:%sZ')\nGROUP BY userIdentity.arn\nORDER BY api_call_count DESC\nLIMIT 50;\n-- Failed API calls indicating permission issues or reconnaissance\nSELECT eventTime, userIdentity.arn, eventName, errorCode, errorMessage,\n       sourceIPAddress\nFROM cloudtrail_logs\nWHERE errorCode IN ('AccessDenied', 'UnauthorizedAccess', 'Client.UnauthorizedAccess')\n  AND eventTime > date_format(date_add('day', -7, current_date), '%Y-%m-%dT%H:%i:%sZ')\nORDER BY eventTime DESC\nLIMIT 200;\n-- Track KMS key usage\nSELECT eventTime, userIdentity.arn, eventName, requestParameters,\n       resources[1].arn AS key_arn\nFROM cloudtrail_logs\nWHERE eventSource = 'kms.amazonaws.com'\n  AND eventName IN ('Decrypt', 'Encrypt', 'GenerateDataKey', 'DisableKey', 'ScheduleKeyDeletion')\n  AND eventTime > date_format(date_add('day', -7, current_date), '%Y-%m-%dT%H:%i:%sZ')\nORDER BY eventTime DESC;\n```\n\nFor production query volumes, register\u002Fproject all intended partitions and constrain region\u002Fyear\u002Fmonth\u002Fday to prune scan cost; eventTime alone does not prune these partitions. This DDL covers one organization\u002Faccount prefix, not every member account. Values such as AWS service names or IPv6 addresses need an explicit policy when classifying unusual source IPs.\n\n## CloudTrail Lake (Existing Eligible Customers Only)\n\nCloudTrail Lake closed to new customers on May 31, 2026. Verify existing eligibility and organization\u002Faccount event-store coverage before using this optional example; new customers should choose a supported CloudWatch or S3\u002FAthena design. Trails remain supported. See [AWS availability change](https:\u002F\u002Fdocs.aws.amazon.com\u002Fawscloudtrail\u002Flatest\u002Fuserguide\u002Fcloudtrail-lake-service-availability-change.html).\n\n```bash\n# Create an event data store for long-term queryable storage\naws cloudtrail create-event-data-store \\\n  --name org-audit-event-store \\\n  --multi-region-enabled \\\n  --organization-enabled \\\n  --retention-period 2555 \\\n  --advanced-event-selectors '[\n    {\n      \"Name\": \"AllManagementEvents\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Management\"]}\n      ]\n    }\n  ]'\n```\n\n```sql\n-- CloudTrail Lake SQL queries (run in console or via StartQuery API)\n-- Investigate a specific user's activity\nSELECT eventTime, eventName, eventSource, sourceIPAddress,\n       errorCode, requestParameters\nFROM EVENT_DATA_STORE_ID\nWHERE userIdentity.arn = 'arn:aws:iam::123456789012:user\u002Fsuspicious-user'\n  AND eventTime > '2024-01-01 00:00:00'\nORDER BY eventTime DESC;\n-- Cross-account activity summary\nSELECT recipientAccountId, userIdentity.arn,\n       count(*) AS event_count\nFROM EVENT_DATA_STORE_ID\nWHERE eventTime > '2024-01-01 00:00:00'\nGROUP BY recipientAccountId, userIdentity.arn\nORDER BY event_count DESC;\n```\n\n## Validate Trail Integrity\n\n```bash\n# Validate log file integrity for a date range\naws cloudtrail validate-logs \\\n  --trail-arn arn:aws:cloudtrail:us-east-1:123456789012:trail\u002Forg-audit-trail \\\n  --start-time \"2024-01-01T00:00:00Z\" \\\n  --end-time \"2024-01-31T23:59:59Z\"\n\n# Check trail status\naws cloudtrail get-trail-status --name org-audit-trail\n\n# Describe the trail configuration\naws cloudtrail describe-trails --trail-name-list org-audit-trail\n```\n\n## Terraform Configuration\n\n```hcl\nresource \"aws_cloudtrail\" \"org_trail\" {\n  name                          = \"org-audit-trail\"\n  s3_bucket_name                = aws_s3_bucket.cloudtrail.id\n  is_organization_trail         = true\n  is_multi_region_trail         = true\n  enable_log_file_validation    = true\n  kms_key_id                    = aws_kms_key.cloudtrail.arn\n  cloud_watch_logs_group_arn    = \"${aws_cloudwatch_log_group.cloudtrail.arn}:*\"\n  cloud_watch_logs_role_arn     = aws_iam_role.cloudtrail_cw.arn\n  include_global_service_events = true\n\n  advanced_event_selector {\n    name = \"AllManagementEvents\"\n    field_selector {\n      field  = \"eventCategory\"\n      equals = [\"Management\"]\n    }\n  }\n\n  advanced_event_selector {\n    name = \"SensitiveS3DataEvents\"\n    field_selector {\n      field  = \"eventCategory\"\n      equals = [\"Data\"]\n    }\n    field_selector {\n      field  = \"resources.type\"\n      equals = [\"AWS::S3::Object\"]\n    }\n    field_selector {\n      field       = \"resources.ARN\"\n      starts_with = [\"arn:aws:s3:::sensitive-data-bucket\u002F\"]\n    }\n  }\n\n  tags = {\n    Environment = \"production\"\n    Compliance  = \"soc2,hipaa\"\n  }\n}\n```\n\nThe Terraform fragment references externally defined bucket\u002Fkey\u002Flog-role resources and policies; it is not standalone. Plan and inspect changes before applying. For an organization-wide rollout, verify representative member-account\u002Fregion delivery and CloudWatch access as well as the management account. A metric filter without an alarm does not notify anyone; the example only creates two alarms and the remaining checklist alarms must be implemented and tested separately.\n\n## Setup Checklist\n\n```yaml\ncloudtrail_checklist:\n  trail_configuration:\n    - \"Organization trail enabled across all accounts\"\n    - \"Multi-region trail enabled\"\n    - \"Log file validation enabled\"\n    - \"KMS encryption configured with dedicated key\"\n    - \"CloudWatch Logs integration active\"\n    - \"S3 bucket policy restricts access to CloudTrail service only\"\n\n  s3_bucket_hardening:\n    - \"Public access blocked\"\n    - \"Versioning enabled\"\n    - \"Server-side encryption enabled\"\n    - \"Lifecycle policy set for retention and archival\"\n    - \"Access logging enabled on the bucket itself\"\n    - \"Object Lock enabled for WORM compliance (if required)\"\n\n  monitoring_and_alerting:\n    - \"Metric filters for unauthorized API calls\"\n    - \"Alarm on root account usage\"\n    - \"Alarm on console login without MFA\"\n    - \"Alarm on IAM policy changes\"\n    - \"Alarm on security group and NACL changes\"\n    - \"Alarm on CloudTrail configuration changes\"\n    - \"Alarm on S3 bucket policy changes\"\n\n  analysis:\n    - \"Athena table created for ad-hoc queries\"\n    - \"CloudTrail Lake event data store for long-term queries\"\n    - \"Regular review of high-risk API patterns\"\n    - \"Automated reports for compliance evidence\"\n\n  operational:\n    - \"Trail status health check automated\"\n    - \"Log delivery latency monitored\"\n    - \"Log file validation run periodically\"\n    - \"SNS notification for trail configuration changes\"\n```\n\n## Verification\n\nAfter the authorized change, inspect get-trail-status for delivery errors and delivered object\u002Fdigest timestamps. Use a harmless authorized management event in a test account, find its event ID in S3 and the selected query system, and test alarm routing without disclosing sensitive log bodies. Retain the before\u002Fafter configuration and unresolved regions\u002Faccounts. Compliance tags and a green trail status do not establish complete event coverage or certification.\n\n## Best Practices\n\n- Enable organization-wide trails from the management account for full coverage\n- Always enable log file validation to detect tampering\n- Encrypt logs with a customer-managed KMS key and restrict key usage\n- Use advanced event selectors to capture data events on sensitive resources without logging everything\n- Integrate with CloudWatch Logs for real-time metric filters and alarms\n- Set up Athena or CloudTrail Lake for efficient querying during investigations\n- Apply S3 lifecycle policies to transition old logs to Glacier and enforce retention\n- Monitor the trail itself (delivery errors, configuration changes) as a meta-control\n- Validate log integrity periodically as part of compliance evidence collection\n- Restrict access to the CloudTrail S3 bucket and KMS key with least-privilege IAM policies\n\n## Limitations\n\n- Guidance and checklists only; not legal advice and not a substitute for a qualified auditor.\n- Docs-only import: upstream templates and scripts not bundled.\n\n### Example\n\n```markdown\nMap this skill's control checklist to our current evidence and list gaps.\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n","# AWS CloudTrail\n\nAudit AWS account activity with CloudTrail for compliance, security investigation, and operational troubleshooting.\n\n## When to Use\n\n- Enabling organization-wide audit logging across all AWS accounts\n- Investigating security incidents or unauthorized API activity\n- Meeting compliance requirements for SOC 2, HIPAA, PCI DSS, or FedRAMP\n- Setting up automated alerting on sensitive AWS API calls\n- Querying historical AWS activity for forensic analysis\n\n## Prerequisites and Change Scope\n\nVerify the AWS identity, partition, region and organization management\u002Fdelegated-administrator permissions before mutation. All names, account IDs and ARNs below are synthetic placeholders; choose a globally unique owned bucket. Have a working KMS key policy permitting the selected CloudTrail trail and authorized readers, an existing CloudWatch log group and scoped role\u002Ftrust policy before passing their ARNs. The snippets do not provision those dependencies. Review paid data-event\u002FLake\u002FAthena scope and retention costs first. Export existing policies\u002Fselectors\u002Flifecycle settings and merge intended changes; put-* operations can replace existing configuration. Never apply expiration to audit evidence under a legal hold.\n\n## Create an Organization Trail\n\n```bash\n# Create the S3 bucket for log storage\naws s3api create-bucket \\\n  --bucket org-cloudtrail-audit-logs \\\n  --region us-east-1\n# Apply bucket policy allowing CloudTrail to write\naws s3api put-bucket-policy \\\n  --bucket org-cloudtrail-audit-logs \\\n  --policy '{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n      {\n        \"Sid\": \"AWSCloudTrailAclCheck\",\n        \"Effect\": \"Allow\",\n        \"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\n        \"Action\": \"s3:GetBucketAcl\",\n        \"Resource\": \"arn:aws:s3:::org-cloudtrail-audit-logs\",\n        \"Condition\": {\"StringEquals\": {\"aws:SourceArn\": \"arn:aws:cloudtrail:us-east-1:123456789012:trail\u002Forg-audit-trail\"}}\n      },\n      {\n        \"Sid\": \"AWSCloudTrailWrite\",\n        \"Effect\": \"Allow\",\n        \"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\n        \"Action\": \"s3:PutObject\",\n        \"Resource\": [\"arn:aws:s3:::org-cloudtrail-audit-logs\u002FAWSLogs\u002F123456789012\u002F*\", \"arn:aws:s3:::org-cloudtrail-audit-logs\u002FAWSLogs\u002Fo-exampleorgid\u002F*\"],\n        \"Condition\": {\n          \"StringEquals\": {\"s3:x-amz-acl\": \"bucket-owner-full-control\", \"aws:SourceArn\": \"arn:aws:cloudtrail:us-east-1:123456789012:trail\u002Forg-audit-trail\"}\n        }\n      }\n    ]\n  }'\n# Block public access on the audit bucket\naws s3api put-public-access-block \\\n  --bucket org-cloudtrail-audit-logs \\\n  --public-access-block-configuration \\\n    BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\n# Enable version history (not WORM\u002Ftamper prevention)\naws s3api put-bucket-versioning \\\n  --bucket org-cloudtrail-audit-logs \\\n  --versioning-configuration Status=Enabled\n# Enable server-side encryption\naws s3api put-bucket-encryption \\\n  --bucket org-cloudtrail-audit-logs \\\n  --server-side-encryption-configuration '{\n    \"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"aws:kms\", \"KMSMasterKeyID\": \"alias\u002Fcloudtrail-key\"}}]\n  }'\n# Set lifecycle policy for log retention\naws s3api put-bucket-lifecycle-configuration \\\n  --bucket org-cloudtrail-audit-logs \\\n  --lifecycle-configuration '{\n    \"Rules\": [\n      {\n        \"ID\": \"TransitionToGlacier\",\n        \"Status\": \"Enabled\",\n        \"Filter\": {\"Prefix\": \"AWSLogs\u002F\"},\n        \"Transitions\": [\n          {\"Days\": 90, \"StorageClass\": \"GLACIER\"}\n        ]\n      },\n      {\n        \"ID\": \"ExpireOldLogs\",\n        \"Status\": \"Enabled\",\n        \"Filter\": {\"Prefix\": \"AWSLogs\u002F\"},\n        \"Expiration\": {\"Days\": 2555}\n      }\n    ]\n  }'\n# Create the organization trail\naws cloudtrail create-trail \\\n  --name org-audit-trail \\\n  --s3-bucket-name org-cloudtrail-audit-logs \\\n  --is-organization-trail \\\n  --is-multi-region-trail \\\n  --enable-log-file-validation \\\n  --kms-key-id arn:aws:kms:us-east-1:123456789012:alias\u002Fcloudtrail-key \\\n  --cloud-watch-logs-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:CloudTrail:* \\\n  --cloud-watch-logs-role-arn arn:aws:iam::123456789012:role\u002FCloudTrail-CWLogs-Role\n# Start logging\naws cloudtrail start-logging --name org-audit-trail\n```\n\nThe organization prefix must use the real organization ID and the trail ARN must use the management account ID. Log-file validation detects changes; it does not prevent deletion. Versioning alone is not immutable retention. Validate Object Lock\u002Flegal-hold design separately where required.\n\n## Event Selectors for Management and Data Events\n\n```bash\n# Configure advanced event selectors for granular control\naws cloudtrail put-event-selectors \\\n  --trail-name org-audit-trail \\\n  --advanced-event-selectors '[\n    {\n      \"Name\": \"AllManagementEvents\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Management\"]}\n      ]\n    },\n    {\n      \"Name\": \"S3DataEventsForSensitiveBuckets\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Data\"]},\n        {\"Field\": \"resources.type\", \"Equals\": [\"AWS::S3::Object\"]},\n        {\"Field\": \"resources.ARN\", \"StartsWith\": [\n          \"arn:aws:s3:::sensitive-data-bucket\u002F\",\n          \"arn:aws:s3:::pii-bucket\u002F\",\n          \"arn:aws:s3:::financial-data\u002F\"\n        ]}\n      ]\n    },\n    {\n      \"Name\": \"LambdaInvocations\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Data\"]},\n        {\"Field\": \"resources.type\", \"Equals\": [\"AWS::Lambda::Function\"]}\n      ]\n    },\n    {\n      \"Name\": \"DynamoDBDataEvents\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Data\"]},\n        {\"Field\": \"resources.type\", \"Equals\": [\"AWS::DynamoDB::Table\"]}\n      ]\n    }\n  ]'\n```\n\n## CloudWatch Alerts for Sensitive Activity\n\n```bash\n# Create metric filter for unauthorized API calls\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name UnauthorizedAPICalls \\\n  --filter-pattern '{ ($.errorCode = \"*UnauthorizedAccess*\") || ($.errorCode = \"AccessDenied*\") }' \\\n  --metric-transformations \\\n    metricName=UnauthorizedAPICalls,metricNamespace=CloudTrailMetrics,metricValue=1\n# Create alarm for unauthorized calls\naws cloudwatch put-metric-alarm \\\n  --alarm-name UnauthorizedAPICallsAlarm \\\n  --metric-name UnauthorizedAPICalls \\\n  --namespace CloudTrailMetrics \\\n  --statistic Sum \\\n  --period 300 \\\n  --threshold 5 \\\n  --comparison-operator GreaterThanOrEqualToThreshold \\\n  --evaluation-periods 1 \\\n  --alarm-actions arn:aws:sns:us-east-1:123456789012:security-alerts\n# Root account usage alarm\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name RootAccountUsage \\\n  --filter-pattern '{ ($.userIdentity.type = \"Root\") && ($.userIdentity.invokedBy NOT EXISTS) && ($.eventType != \"AwsServiceEvent\") }' \\\n  --metric-transformations \\\n    metricName=RootAccountUsage,metricNamespace=CloudTrailMetrics,metricValue=1\naws cloudwatch put-metric-alarm \\\n  --alarm-name RootAccountUsageAlarm \\\n  --metric-name RootAccountUsage \\\n  --namespace CloudTrailMetrics \\\n  --statistic Sum \\\n  --period 300 \\\n  --threshold 1 \\\n  --comparison-operator GreaterThanOrEqualToThreshold \\\n  --evaluation-periods 1 \\\n  --alarm-actions arn:aws:sns:us-east-1:123456789012:security-alerts\n# Console login without MFA\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name ConsoleLoginWithoutMFA \\\n  --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") }' \\\n  --metric-transformations \\\n    metricName=ConsoleLoginWithoutMFA,metricNamespace=CloudTrailMetrics,metricValue=1\n# IAM policy changes\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name IAMPolicyChanges \\\n  --filter-pattern '{ ($.eventName=CreatePolicy) || ($.eventName=DeletePolicy) || ($.eventName=AttachRolePolicy) || ($.eventName=DetachRolePolicy) || ($.eventName=AttachUserPolicy) || ($.eventName=PutUserPolicy) }' \\\n  --metric-transformations \\\n    metricName=IAMPolicyChanges,metricNamespace=CloudTrailMetrics,metricValue=1\n# Security group changes\naws logs put-metric-filter \\\n  --log-group-name CloudTrail \\\n  --filter-name SecurityGroupChanges \\\n  --filter-pattern '{ ($.eventName=AuthorizeSecurityGroupIngress) || ($.eventName=RevokeSecurityGroupIngress) || ($.eventName=CreateSecurityGroup) || ($.eventName=DeleteSecurityGroup) }' \\\n  --metric-transformations \\\n    metricName=SecurityGroupChanges,metricNamespace=CloudTrailMetrics,metricValue=1\n```\n\n## Athena Queries for CloudTrail Analysis\n\n```sql\n-- Create Athena table for CloudTrail logs\nCREATE EXTERNAL TABLE IF NOT EXISTS cloudtrail_logs (\n  eventVersion STRING,\n  userIdentity STRUCT\u003C\n    type: STRING,\n    principalId: STRING,\n    arn: STRING,\n    accountId: STRING,\n    invokedBy: STRING,\n    accessKeyId: STRING,\n    userName: STRING,\n    sessionContext: STRUCT\u003C\n      attributes: STRUCT\u003CmfaAuthenticated: STRING, creationDate: STRING>,\n      sessionIssuer: STRUCT\u003Ctype: STRING, principalId: STRING, arn: STRING, accountId: STRING, userName: STRING>\n    >\n  >,\n  eventTime STRING,\n  eventSource STRING,\n  eventName STRING,\n  awsRegion STRING,\n  sourceIPAddress STRING,\n  userAgent STRING,\n  errorCode STRING,\n  errorMessage STRING,\n  requestParameters STRING,\n  responseElements STRING,\n  additionalEventData STRING,\n  requestId STRING,\n  eventId STRING,\n  readOnly STRING,\n  resources ARRAY\u003CSTRUCT\u003Carn: STRING, accountId: STRING, type: STRING>>,\n  eventType STRING,\n  recipientAccountId STRING\n)\nPARTITIONED BY (region STRING, year STRING, month STRING, day STRING)\nROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'\nSTORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'\nOUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'\nLOCATION 's3:\u002F\u002Forg-cloudtrail-audit-logs\u002FAWSLogs\u002Fo-exampleorgid\u002F123456789012\u002FCloudTrail\u002F';\n-- Add a known delivered partition before querying (repeat for required account\u002Fdates).\nALTER TABLE cloudtrail_logs ADD IF NOT EXISTS\nPARTITION (region='us-east-1', year='2026', month='10', day='22')\nLOCATION 's3:\u002F\u002Forg-cloudtrail-audit-logs\u002FAWSLogs\u002Fo-exampleorgid\u002F123456789012\u002FCloudTrail\u002Fus-east-1\u002F2026\u002F10\u002F22\u002F';\n-- Find all delete operations in the last 7 days\nSELECT eventTime, userIdentity.arn, eventName, sourceIPAddress,\n       requestParameters\nFROM cloudtrail_logs\nWHERE eventName LIKE '%Delete%'\n  AND eventTime > date_format(date_add('day', -7, current_date), '%Y-%m-%dT%H:%i:%sZ')\nORDER BY eventTime DESC\nLIMIT 100;\n-- Identify console logins outside a synthetic exact-IP allowlist (not CIDR matching)\nSELECT eventTime, userIdentity.userName, sourceIPAddress,\n       additionalEventData\nFROM cloudtrail_logs\nWHERE eventName = 'ConsoleLogin'\n  AND sourceIPAddress NOT IN ('198.51.100.10', '203.0.113.20')\n  AND eventTime > date_format(date_add('day', -30, current_date), '%Y-%m-%dT%H:%i:%sZ')\nORDER BY eventTime DESC;\n-- Access key usage patterns per principal\nSELECT userIdentity.arn,\n       count(*) AS api_call_count,\n       count(DISTINCT eventName) AS unique_actions,\n       count(DISTINCT sourceIPAddress) AS unique_ips,\n       min(eventTime) AS first_seen,\n       max(eventTime) AS last_seen\nFROM cloudtrail_logs\nWHERE eventTime > date_format(date_add('day', -30, current_date), '%Y-%m-%dT%H:%i:%sZ')\nGROUP BY userIdentity.arn\nORDER BY api_call_count DESC\nLIMIT 50;\n-- Failed API calls indicating permission issues or reconnaissance\nSELECT eventTime, userIdentity.arn, eventName, errorCode, errorMessage,\n       sourceIPAddress\nFROM cloudtrail_logs\nWHERE errorCode IN ('AccessDenied', 'UnauthorizedAccess', 'Client.UnauthorizedAccess')\n  AND eventTime > date_format(date_add('day', -7, current_date), '%Y-%m-%dT%H:%i:%sZ')\nORDER BY eventTime DESC\nLIMIT 200;\n-- Track KMS key usage\nSELECT eventTime, userIdentity.arn, eventName, requestParameters,\n       resources[1].arn AS key_arn\nFROM cloudtrail_logs\nWHERE eventSource = 'kms.amazonaws.com'\n  AND eventName IN ('Decrypt', 'Encrypt', 'GenerateDataKey', 'DisableKey', 'ScheduleKeyDeletion')\n  AND eventTime > date_format(date_add('day', -7, current_date), '%Y-%m-%dT%H:%i:%sZ')\nORDER BY eventTime DESC;\n```\n\nFor production query volumes, register\u002Fproject all intended partitions and constrain region\u002Fyear\u002Fmonth\u002Fday to prune scan cost; eventTime alone does not prune these partitions. This DDL covers one organization\u002Faccount prefix, not every member account. Values such as AWS service names or IPv6 addresses need an explicit policy when classifying unusual source IPs.\n\n## CloudTrail Lake (Existing Eligible Customers Only)\n\nCloudTrail Lake closed to new customers on May 31, 2026. Verify existing eligibility and organization\u002Faccount event-store coverage before using this optional example; new customers should choose a supported CloudWatch or S3\u002FAthena design. Trails remain supported. See [AWS availability change](https:\u002F\u002Fdocs.aws.amazon.com\u002Fawscloudtrail\u002Flatest\u002Fuserguide\u002Fcloudtrail-lake-service-availability-change.html).\n\n```bash\n# Create an event data store for long-term queryable storage\naws cloudtrail create-event-data-store \\\n  --name org-audit-event-store \\\n  --multi-region-enabled \\\n  --organization-enabled \\\n  --retention-period 2555 \\\n  --advanced-event-selectors '[\n    {\n      \"Name\": \"AllManagementEvents\",\n      \"FieldSelectors\": [\n        {\"Field\": \"eventCategory\", \"Equals\": [\"Management\"]}\n      ]\n    }\n  ]'\n```\n\n```sql\n-- CloudTrail Lake SQL queries (run in console or via StartQuery API)\n-- Investigate a specific user's activity\nSELECT eventTime, eventName, eventSource, sourceIPAddress,\n       errorCode, requestParameters\nFROM EVENT_DATA_STORE_ID\nWHERE userIdentity.arn = 'arn:aws:iam::123456789012:user\u002Fsuspicious-user'\n  AND eventTime > '2024-01-01 00:00:00'\nORDER BY eventTime DESC;\n-- Cross-account activity summary\nSELECT recipientAccountId, userIdentity.arn,\n       count(*) AS event_count\nFROM EVENT_DATA_STORE_ID\nWHERE eventTime > '2024-01-01 00:00:00'\nGROUP BY recipientAccountId, userIdentity.arn\nORDER BY event_count DESC;\n```\n\n## Validate Trail Integrity\n\n```bash\n# Validate log file integrity for a date range\naws cloudtrail validate-logs \\\n  --trail-arn arn:aws:cloudtrail:us-east-1:123456789012:trail\u002Forg-audit-trail \\\n  --start-time \"2024-01-01T00:00:00Z\" \\\n  --end-time \"2024-01-31T23:59:59Z\"\n\n# Check trail status\naws cloudtrail get-trail-status --name org-audit-trail\n\n# Describe the trail configuration\naws cloudtrail describe-trails --trail-name-list org-audit-trail\n```\n\n## Terraform Configuration\n\n```hcl\nresource \"aws_cloudtrail\" \"org_trail\" {\n  name                          = \"org-audit-trail\"\n  s3_bucket_name                = aws_s3_bucket.cloudtrail.id\n  is_organization_trail         = true\n  is_multi_region_trail         = true\n  enable_log_file_validation    = true\n  kms_key_id                    = aws_kms_key.cloudtrail.arn\n  cloud_watch_logs_group_arn    = \"${aws_cloudwatch_log_group.cloudtrail.arn}:*\"\n  cloud_watch_logs_role_arn     = aws_iam_role.cloudtrail_cw.arn\n  include_global_service_events = true\n\n  advanced_event_selector {\n    name = \"AllManagementEvents\"\n    field_selector {\n      field  = \"eventCategory\"\n      equals = [\"Management\"]\n    }\n  }\n\n  advanced_event_selector {\n    name = \"SensitiveS3DataEvents\"\n    field_selector {\n      field  = \"eventCategory\"\n      equals = [\"Data\"]\n    }\n    field_selector {\n      field  = \"resources.type\"\n      equals = [\"AWS::S3::Object\"]\n    }\n    field_selector {\n      field       = \"resources.ARN\"\n      starts_with = [\"arn:aws:s3:::sensitive-data-bucket\u002F\"]\n    }\n  }\n\n  tags = {\n    Environment = \"production\"\n    Compliance  = \"soc2,hipaa\"\n  }\n}\n```\n\nThe Terraform fragment references externally defined bucket\u002Fkey\u002Flog-role resources and policies; it is not standalone. Plan and inspect changes before applying. For an organization-wide rollout, verify representative member-account\u002Fregion delivery and CloudWatch access as well as the management account. A metric filter without an alarm does not notify anyone; the example only creates two alarms and the remaining checklist alarms must be implemented and tested separately.\n\n## Setup Checklist\n\n```yaml\ncloudtrail_checklist:\n  trail_configuration:\n    - \"Organization trail enabled across all accounts\"\n    - \"Multi-region trail enabled\"\n    - \"Log file validation enabled\"\n    - \"KMS encryption configured with dedicated key\"\n    - \"CloudWatch Logs integration active\"\n    - \"S3 bucket policy restricts access to CloudTrail service only\"\n\n  s3_bucket_hardening:\n    - \"Public access blocked\"\n    - \"Versioning enabled\"\n    - \"Server-side encryption enabled\"\n    - \"Lifecycle policy set for retention and archival\"\n    - \"Access logging enabled on the bucket itself\"\n    - \"Object Lock enabled for WORM compliance (if required)\"\n\n  monitoring_and_alerting:\n    - \"Metric filters for unauthorized API calls\"\n    - \"Alarm on root account usage\"\n    - \"Alarm on console login without MFA\"\n    - \"Alarm on IAM policy changes\"\n    - \"Alarm on security group and NACL changes\"\n    - \"Alarm on CloudTrail configuration changes\"\n    - \"Alarm on S3 bucket policy changes\"\n\n  analysis:\n    - \"Athena table created for ad-hoc queries\"\n    - \"CloudTrail Lake event data store for long-term queries\"\n    - \"Regular review of high-risk API patterns\"\n    - \"Automated reports for compliance evidence\"\n\n  operational:\n    - \"Trail status health check automated\"\n    - \"Log delivery latency monitored\"\n    - \"Log file validation run periodically\"\n    - \"SNS notification for trail configuration changes\"\n```\n\n## Verification\n\nAfter the authorized change, inspect get-trail-status for delivery errors and delivered object\u002Fdigest timestamps. Use a harmless authorized management event in a test account, find its event ID in S3 and the selected query system, and test alarm routing without disclosing sensitive log bodies. Retain the before\u002Fafter configuration and unresolved regions\u002Faccounts. Compliance tags and a green trail status do not establish complete event coverage or certification.\n\n## Best Practices\n\n- Enable organization-wide trails from the management account for full coverage\n- Always enable log file validation to detect tampering\n- Encrypt logs with a customer-managed KMS key and restrict key usage\n- Use advanced event selectors to capture data events on sensitive resources without logging everything\n- Integrate with CloudWatch Logs for real-time metric filters and alarms\n- Set up Athena or CloudTrail Lake for efficient querying during investigations\n- Apply S3 lifecycle policies to transition old logs to Glacier and enforce retention\n- Monitor the trail itself (delivery errors, configuration changes) as a meta-control\n- Validate log integrity periodically as part of compliance evidence collection\n- Restrict access to the CloudTrail S3 bucket and KMS key with least-privilege IAM policies\n\n## Limitations\n\n- Guidance and checklists only; not legal advice and not a substitute for a qualified auditor.\n- Docs-only import: upstream templates and scripts not bundled.\n\n### Example\n\n```markdown\nMap this skill's control checklist to our current evidence and list gaps.\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n",{"name":5,"risk":31,"source":45,"license":14,"category":39,"metadata":46,"date_added":49,"description":7,"source_repo":50,"source_type":28,"compatibility":51,"license_source":52},"https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills",{"author":47,"version":48},"devops-skills","1.0","2026-09-20","BagelHole\u002FDevOps-Security-Agent-Skills","Checklist and framework guidance; no privileged tooling required. Apply controls through your own change process.","https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE","7bf2279c8a65758319526a721d5c4b75683aec9c","skills\u002Fantigravity-aws-cloudtrail",3,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections","https:\u002F\u002Fgithub.com\u002Fboisenoise","2026-11-11 14:20:43",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add boisenoise\u002Fskills-collections --skill aws-cloudtrail",{"tool":65,"command":66},"bunx","bunx skills add boisenoise\u002Fskills-collections --skill aws-cloudtrail",{"tool":68,"command":69},"pnpm","pnpm dlx skills add boisenoise\u002Fskills-collections --skill aws-cloudtrail","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-aws-cloudtrail\u002FSKILL.md",true,[],[74,102,129,155,174,197],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":79,"sourceHtmlUrl":80,"categories":81,"keywords":82,"publishedAt":40},"01M6WNH92BHVFXHGPDZCPJ0AG0","web-access","Use Treg for public web or platform data only when existing search, browser and connected tools cannot cover the task, with explicit cost and data boundaries.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FSKILL.md",[],[83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,23,22],"web","access","web access","official","development","browser","search","data","Tools","read","fetch","only","youtube","free tools","platform","critical","free","cover","normal",{"skillNo":103,"name":104,"nameZh":6,"description":105,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":106,"sourceHtmlUrl":107,"categories":108,"keywords":114,"publishedAt":40},"01M6WNF9XAYAB2CZDDJBAKNM93","treg","Use the Treg CLI or MCP catalog to discover, price and call authorized external tools with team-scoped credentials and a user-approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FSKILL.md",[109],{"categoryNo":110,"categoryName":111,"taxonomyType":112,"taxonomyTypeDesc":113},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[104,115,116,117,86,87,35,91,118,119,120,121,122,123,124,98,125,126,127,128,22],"MCP","cli","github","Budget","credentials","team","catalog","use","call","discover","external tools","with","scoped","blob",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":133,"sourceHtmlUrl":134,"categories":135,"keywords":141,"publishedAt":40},"01M6WN93MEAZ4E41DYAHJRPHQT","recruit","Turn a job description into an evidence-linked candidate shortlist through Treg, with job-related ranking and optional authorized business contact enrichment.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FSKILL.md",[136],{"categoryNo":137,"categoryName":138,"taxonomyType":139,"taxonomyTypeDesc":140},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[131,117,86,35,142,143,144,145,146,147,98,148,149,150,126,151,152,153,154,128,104,22],"https","email","enrichment","business","evidence","phone","ranking","post","job description","for","person","candidate","reason",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":159,"sourceHtmlUrl":160,"categories":161,"keywords":162,"publishedAt":40},"01M6WN8R5RXSMHM9B4D9FAFX42","rea-growth","Analyze a company’s public growth and content through Treg, distinguish observations from hypotheses, and produce an evidence-linked playbook within an approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FSKILL.md",[],[163,164,165,117,86,35,166,167,142,168,118,169,170,171,146,98,172,173,128,104,22],"growth","rea","rea growth","produce","content","playbook","marketing","analyze","public","observations","company",{"skillNo":175,"name":176,"nameZh":6,"description":177,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":178,"sourceHtmlUrl":179,"categories":180,"keywords":181,"publishedAt":40},"01M6WN2EVE3RQRGWAKBT4S7YT2","make-ugc","Create original AI UGC-style product videos through Treg: research hooks, approve a licensed presenter and voice, generate clips, add captions and report costs.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FSKILL.md",[],[182,183,117,184,86,185,35,186,187,188,189,190,98,191,192,193,194,195,196,128],"make","make ugc","research","create","Video","Captions","ads","short","hooks","head","style","niche","trending","talking-head","approve",{"skillNo":198,"name":199,"nameZh":6,"description":200,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":201,"sourceHtmlUrl":202,"categories":203,"keywords":204,"publishedAt":40},"01M6WN10ARAA63Y8K1YNGXJ2RM","lead-signals","Find and qualify public buying signals through Treg, rank fitting business accounts and optionally enrich authorized business contact information.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FSKILL.md",[],[205,206,207,117,86,35,208,209,145,210,211,98,212,213,214,215,216,217,218,128],"signals","lead","lead signals","how","find","ready","as","how to","qualify","people","information","enrich","changes","funding"]