CloudTrail over data stores

Lesson 1 of 4 in Audit Logs and Privacy.

AWS CloudTrail records API activity, and it divides that activity in two. The split is the single most consequential fact in this lesson, because one half is on by default and the other is not.

A management event is a control-plane call: CreateTable, UpdateTable, GrantPermissions, CreateBucket, PutBucketPolicy, ModifyCluster. These describe configuration — what the platform is — and the first copy is delivered to a trail at no charge. If a schema changed, a grant was made, or a bucket policy was edited, a management event exists and nobody had to enable anything.

A data event is a data-plane call: GetObject, PutObject, DeleteObject, PutItem, GetItem, Invoke. These describe access — what actually happened to the data. Data events are not logged by default, and they carry a per-event charge. That default is the reason most organisations discover, at exactly the wrong moment, that the question "who read this file" has no answer and no retrospective fix.

Configuring them has two generations and the difference is examinable. A basic event selector supports exactly three resource types — AWS::S3::Object, AWS::Lambda::Function, AWS::DynamoDB::Table — can choose read-only, write-only or all, and names up to 250 resources across all selectors on the trail. What it cannot do is filter on eventName, and it cannot reach any other resource type, including objects in S3 directory buckets. So "log only DeleteObject on this one bucket" — the obvious cost-control request — is not expressible.

An advanced event selector builds an expression over fields: eventCategory, resources.type, resources.ARN with StartsWith and NotStartsWith for prefix matching, eventName, readOnly. That gives both reach — every resource type beyond the original three is available only here — and cost control, by narrowing to the prefixes and operations that answer your actual audit question. AWS's own guidance is worth repeating because it cuts against the instinct: for auditing purposes, record all data events, and use narrow selectors for operational monitoring. The selector that saves money is also the selector that loses the evidence you did not predict needing.

Two store-specific notes. DynamoDB data events are item-level, so they name the key of the item read or written, which is how "who changed this record" is answerable at all. And Amazon Redshift SQL is not an AWS API call — a SELECT inside the engine produces no CloudTrail event of any kind, which is why the warehouse needs its own logging and is the subject of the next lesson.

Now the question this domain is really about: who read this specific object?

On a governed lake the honest answer involves three events, and understanding why is worth more than memorising any one of them. Recall from the first module that Lake Formation does not hand the reader credentials for the data — it assumes the registration role and vends scoped credentials. So the S3 data event for the read is attributed to that role. Every analyst produces an identical-looking event, and the trail answers "something read this object" rather than "who".

Three mechanisms close the gap:

lakeformation:GetDataAccess is logged whenever an engine asks Lake Formation for credentials. Nobody calls it directly. It carries the requesting service, the Lake Formation principal, the table, and a role session name shaped AWSLF-<version>-<engine>-<account>-<suffix> — where the engine code is GL for a Glue ETL job, AT for Athena, RE for Redshift Spectrum. Each s3:GetObject data event corresponds to one GetDataAccess call, and the shared IAM role identifier is what lets you join the two. This is a management event, so it is captured without enabling data events — which makes it the cheapest useful audit surface on a governed lake.

SET_SOURCE_IDENTITY stamps the originating identity into the S3 events themselves. Set the parameter to TRUE in the data lake settings, add sts:SetSourceIdentity alongside sts:AssumeRole in the registration role's trust policy, and a source identity appears in the sessionContext of each s3:GetObject event. It needs S3 data events enabled — a separate switch and a separate charge.

Trusted identity propagation carries the Identity Center user through, so the event records the directory user id under userIdentity.onBehalfOf.userId and additionalEventData confirms the trusted-caller path. Resolve the id to a name with the Identity Store API. The same property makes S3 Access Grants interesting for direct object access: granting to a directory identity puts that user's identity in each S3 data event, which answers "who read this object" without a role per person.

The honest summary for an exam: by default, nothing answers it. Data events are off; with them on, a governed read names a role; naming the person needs source identity or identity propagation on top.

Management events, data events, and what each one can establish
PropertyManagement eventsData events

On by default?

Yes — the first copy to a trail is free

No, and charged per event

What they record

Control-plane calls: who changed the configuration

Data-plane calls: who touched the data

Typical data examples

glue:UpdateTable, lakeformation:GrantPermissions, s3:PutBucketPolicy, redshift:ModifyCluster

s3:GetObject, s3:DeleteObject, dynamodb:PutItem, lambda:Invoke

Configuration

Included on any trail; you can exclude AWS KMS and RDS Data API event sources to cut volume

Basic selectors cover S3 objects, Lambda functions and DynamoDB tables only; everything else needs advanced selectors

eventName filtering

Not applicable

Advanced selectors only — this is why basic selectors cannot express “log deletes only”

What they cannot tell you

Whether anyone actually read the data the configuration governs

What a query asked for, or the SQL text — a data event names an object, not an intent

The governed-lake twist

GetDataAccess lives here, which is why the cheapest useful audit on a lake needs no data events at all

Attributed to the Lake Formation registration role unless source identity is enabled

Key terms: Data event (data plane), Management event (control plane), Basic event selector, Advanced event selector, GetDataAccess (the Lake Formation audit event), SET_SOURCE_IDENTITY (Lake Formation)

Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.