CloudTrail
Protocol: JSON 1.1 (X-Amz-Target: com.amazonaws.cloudtrail.v20131101.CloudTrail_20131101.*)
Endpoint: POST http://localhost:4566/
Floci emulates a CloudTrail trail's full life cycle and emits S3 data events to the trail's destination bucket as gzipped JSON log files at the AWS-shaped key path:
${prefix}AWSLogs/${accountId}/CloudTrail/${region}/yyyy/MM/dd/${accountId}_CloudTrail_${region}_${YYYYMMDDTHHMMZ}_${rand12}.json.gz
Supported Actions
| Action | Description |
|---|---|
CreateTrail |
Creates a trail and returns its ARN |
DescribeTrails |
Returns the settings for one or more trails |
DeleteTrail |
Deletes a trail |
UpdateTrail |
Updates the settings of an existing trail |
PutEventSelectors |
Configures the event selectors for a trail |
GetEventSelectors |
- |
StartLogging |
Starts logging for a trail |
StopLogging |
Stops logging for a trail |
GetTrailStatus |
Returns the logging status of a trail |
LookupEvents |
- |
Selector matching honors ReadWriteType (All, ReadOnly, WriteOnly)
and AWS::S3::Object data resource ARNs in any of these forms:
arn:aws:s3:::— every bucketarn:aws:s3:::bucket/— every key in the bucketarn:aws:s3:::bucket/prefix— keys with the given prefixarn:aws:s3:::bucket/prefix/key— exact key match
S3 Hook Coverage
Floci emits a CloudTrail data event whenever any of these S3 ops runs against a bucket matched by an active trail's selectors:
PutObject,GetObject,HeadObject,DeleteObject,ListObjects,GetObjectAcl
Both success and AwsException paths emit; the latter populates
errorCode / errorMessage (NoSuchKey, NoSuchBucketPolicy, etc.).
If floci.iam.enforcement-enabled is set, IAM-deny responses also emit
records with errorCode: "AccessDenied" for the same op set.
Configuration
| Variable | Default | Description |
|---|---|---|
FLOCI_SERVICES_CLOUDTRAIL_ENABLED |
true |
Enable or disable the service |
FLOCI_SERVICES_CLOUDTRAIL_FLUSH_INTERVAL_SECONDS |
60 |
How often the writer flushes buffered records into the destination bucket. Real CloudTrail delivers with ~5 minute latency; the local default is shorter for fast feedback loops. |
Example
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test
aws s3 mb s3://my-source
aws s3 mb s3://my-trail-logs
aws cloudtrail create-trail \
--name my-trail \
--s3-bucket-name my-trail-logs
aws cloudtrail put-event-selectors \
--trail-name my-trail \
--event-selectors '[{
"ReadWriteType": "All",
"IncludeManagementEvents": false,
"DataResources": [{
"Type": "AWS::S3::Object",
"Values": ["arn:aws:s3:::my-source/"]
}]
}]'
aws cloudtrail start-logging --name my-trail
# Drive some traffic
echo hello | aws s3 cp - s3://my-source/greeting.txt
aws s3 cp s3://my-source/greeting.txt -
# After ~60s, log files appear
aws s3 ls s3://my-trail-logs/AWSLogs/ --recursive