A SaaS product's audit log shows a customer record was viewed — what does that row prove?
answer
- the server acted, not a person
- account is a credential, not a human
- rendered is not read
- viewing implies no copy
- absence tells you about instrumentation
basics
~20 sIt proves the application returned that record to a session authenticated as that account. It does not prove a human read it, which human held the credential, or that the data was copied or kept.
solid answer
~50 sAn application audit row records what the server did, not what a person did. A `record.view` entry means the application authorised a request carried on a session bound to that account and returned the record. Everything past that is inference. It cannot say a human read anything: a list view that prefetches rows, a tab left open, or an API client paging through results all emit identical entries. It cannot say which human: the account is the subject, and shared credentials, an automation using that account's token, support impersonation and a stolen session all leave the account name unchanged. And viewing implies no retention — no screenshot, copy, or download follows from it. So in a case note write "the account rendered 11,000 records between 14:02 and 16:40", and keep the sentence about who and why in a separate, clearly-labelled inference.
code
json · 10 lines{
"ts": "2026-03-11T14:02:47Z",
"action": "record.view",
"actor": { "type": "user", "account": "[email protected]", "session_id": "sess_9f21c" },
"resource": { "type": "customer", "id": "cus_00418822" },
"source_ip": "203.0.113.44",
"user_agent": "Mozilla/5.0 (Macintosh; ...) Chrome/...",
"request_id": "req_a41b0"
...
}go deeper
Be ready to state plainly what one audit row establishes: the service returned that record to a session on that account. Practise saying that sentence without sliding into "the user read the data".
Explain how the row is produced — a server-side authorisation and response — and name the mechanisms that break the account-to-person link: shared credentials, API tokens, support impersonation, a stolen session.
Show how you word this in a report so observation and inference never merge, and how you pick the one extra artefact worth chasing before you make a stronger claim.
Own the consequence for the product: decide whether your own platform's logging could ever support a claim about a person, and whether that gap justifies changing what the service records.
## The row is a server-side observation An application audit log is written by the application, about itself. A row such as `record.view` is emitted at the moment the service decided a request was authorised and produced a response. That is a real, valuable observation: something asked for that record, over a session the platform associated with that account, at that time, from that source address. It is also the *entire* content of the row. Everything a reader wants to add — who, why, what happened next — is inference layered on top, and the discipline that keeps a finding defensible is refusing to let the two blur in a sentence. ## Rendered is not read The application knows it sent bytes. It does not know whether a human looked at them. Several very ordinary mechanisms produce a stream of view rows with no reader at all: - a search or list screen that fetches the full record for each result row to render a preview; - an API client or integration paging through a collection with the same credentials; - a browser tab left open on an auto-refreshing page; - a mobile client prefetching for offline use. If you need to distinguish a person browsing from a script, the discriminating fields are the client identity and the cadence: a browser user agent with a session cookie and irregular, human-scale gaps looks different from a token-authenticated client hitting a fixed interval from an infrastructure address. ## The account is not the person This is the claim that collapses most often under challenge. The log's subject is a *credential*, and the mapping from credential to human being is an assumption held outside the log: - credentials shared informally, or pasted into a runbook or a team vault; - an API token issued to that account and used by a job nobody remembers owning; - support tooling that impersonates or acts on behalf of a user, where the audit trail may name either identity depending on the product; - a session stolen through token theft, which changes nothing visible in the row; - a workstation left unlocked. None of these is exotic. Each is a live alternative explanation until an artefact that does *not* depend on the same session rules it out. ## Viewed is not taken A view row records that data was returned to a client. It says nothing about what the client then did. There may have been no copy, or a screenshot, or a full export by a completely different route. Conversely, an absence of export rows is not evidence that nothing was exported — it is evidence about what the platform instruments. If the product does not audit its bulk-export endpoint, an export leaves no trace, and "we see no download" is then a statement about the logging rather than about the estate. ## What absence in the log means The same directional rule applies everywhere in this domain. A log records the events its authors chose to record, in the paths the traffic actually took. If a record you know was exposed has no matching row, the honest reading is one of: it was reached by an uninstrumented path (a direct database query, an admin console, a cached page, a report generator), the row was written and then aged out of retention, or the collector dropped it. "It never happened" is the one reading the absence does not support on its own. ## Writing it so it survives A finding is worth what it survives — a challenge from the person named in it, a lawyer, or an internal panel. Three habits do most of the work: 1. **Name the subject precisely.** "The account `s.mercer@…`" rather than "Sam". If you later establish who held the credential, add that as its own supported statement. 2. **Use verbs the artefact licenses.** *Rendered*, *returned*, *was authorised for* — not *read*, *stole*, *exfiltrated*. 3. **Keep observation, inference and open question in separate lines.** "Observed: 11,000 `record.view` rows on that account between 14:02 and 16:40. Consistent with: a person paging manually, or a script using the account's API token. Would settle it: whether the requests carried a session cookie or a token, and the inter-request timing." That last line is what turns a weak report into a useful one. You are not being asked to know everything; you are being asked to be exact about which of the things you say are things you saw.
- What would move this from "the account rendered records" to "this person viewed them"?Evidence whose identity does not come from the same session: an endpoint artefact on a laptop physically assigned to that person, a building or VPN record placing them, an MFA approval on a device only they hold, or their own account of the day. Each of those can fail independently of the application session, which is exactly why they add something. Even together they make the claim strong, not certain.
- A record we know was exposed has no matching audit row. What does that absence mean?That the platform did not record it — not that it did not happen. The likely readings are an uninstrumented path such as a direct database query, an admin console or a report generator; a row that aged out of retention; or a pipeline that dropped it. Absence of a row is evidence about the logging, and it should be written that way.
- Does a view row prove the data was displayed on a screen at all?No. An API client fetching the record emits the same row. Separate the two by client identity and cadence: a session cookie plus a browser user agent and irregular human-scale gaps, versus a token-authenticated client at fixed intervals from an infrastructure address. If it was a token, the useful question becomes who owns the job and whether it was authorised.
It is a hotel door log: it shows a key card opened room 412, not who was holding the card or what they did inside.
saying these in an interview costs you the question
- Treats the account name as proof of which person acted
- Says the row proves someone read the customer data
- Assumes no audit row means the access never happened
- Concludes data was taken because records were viewed
- Calls the row proof rather than an observation