Audit logs
Every call made against your project is recorded: who made it, what they asked for, whether they were allowed, and what changed. This is the record you need when answering “who deleted that device”, when demonstrating compliance, and when working out why a configuration is not what you thought it was.
In the dashboard this appears as Event Logs.
Two records per change
Auditing produces two related kinds of record, and knowing which one answers your question saves a lot of scrolling.
| Record | Answers |
|---|---|
| Activity log | Somebody made a call. Who, which method, from where, allowed or denied. One per API call. |
| Resource change log | A resource changed. The before and after state of one resource. |
The relationship is one-to-many: a single API call can modify several resources, so one activity log may have several resource change logs beneath it. They are tied together by a request ID that appears on both, which is what lets you go from “this device was modified” to “because this person called this method”.
That correlation is the main thing to know. Investigating an unexpected change means finding the resource change log, taking its request ID, and looking up the activity log that shares it.
What an activity log records
| Field | Contents |
|---|---|
| Scope | The project, organization, or service the activity belongs to. |
| Authentication | Which principal made the call — a user, a service account, or a device. |
| Authorization | Which permissions were granted or denied. |
| Service and method | Which API was called. |
| Request metadata | Where the call came from. |
| Resource | The primary resource involved. |
| Category | What kind of activity it was. See below. |
Because devices authenticate as service accounts, they appear here as principals in their own right — so the audit trail covers what your fleet did, not only what your people did.
Categories
Category is the most useful filter, because it separates the handful of records that represent real change from the very many that do not.
| Category | Meaning |
|---|---|
Creation |
A resource was created. |
Deletion |
A resource was deleted. |
SpecUpdate |
Configuration fields changed. Usually what you want. |
StateUpdate |
Reported state changed, not configuration. |
MetaUpdate |
Only metadata such as annotations changed. |
Operation |
Something that is neither read nor write — an SSH connection, for instance. |
Read |
A read: get, list, batch get, or watch. |
Rejected |
Refused for lack of permission or authentication. Worth watching. |
ClientError |
Failed on a client error, such as validation. |
ServerError |
Failed because of a server-side problem. |
Internal |
A change the platform made to itself, such as a controller expanding a group’s role binding onto its members. |
Two of these deserve attention.
SpecUpdate is the category for “somebody changed something”. Filtering to
it removes the noise of devices reporting status — which is by far the highest
volume of audit activity in any real fleet — and leaves deliberate
configuration changes.
Rejected records attempts that were refused. A cluster of them is worth
understanding: it is either a misconfigured integration retrying, or someone
probing for access they do not have. Neither is visible if you only look at
what succeeded.
Internal explains changes that appear to have no author. When a role
binding materializes on a group member, no person did it — a controller did,
in response to something a person did earlier.
Before and after
A resource change log carries the state of the resource before and after the change, which is what makes it possible to answer not just “was this modified” but “what was it previously”. In the dashboard this is the change diff.
This is the fastest route to recovering a configuration someone changed by accident: the previous value is in the record, so it can be put back.
Transactions
Change logs also carry transaction information, including a state, and this affects how you read them.
A change may be recorded as pre-committed before it is known to have succeeded, and is followed by a further record saying whether it was committed or rolled back. If the platform retried the transaction there may be several pre-committed records for one change.
So a pre-committed record is not evidence that a change took effect. Look for the committed record, and where several records share a transaction, the last one describes what actually happened.
Retention
Audit records are not kept forever — retention is governed by policy, alongside metrics and logs. If you have a compliance requirement for a particular retention period, confirm the policy on your project meets it, and export elsewhere if you need to keep records longer than the platform holds them.
Check it before you need it, since the records you wish you had are always the ones that have already aged out.
Practical use
Investigating an unexpected change. Filter to SpecUpdate on the resource
in question, read the before and after, then use the request ID to find who
made the call.
Reviewing access. Filter to Rejected to see what is being refused, and
look at the authentication field to see which principals are trying.
Understanding fleet behavior. Filter by a device’s service account to see what one device has been doing.
Establishing a timeline. Filter by principal and time range to reconstruct a sequence of actions in order.
Auditing covers API activity. Actions taken on a device outside the platform — someone logging in over SSH locally and editing a file by hand — are not API calls and so are not in this record.
This is a good reason to keep configuration flowing through the platform rather than by hand on devices: what goes through the API is auditable, and what does not, is not.
Next steps
- Logs — application and system logs from devices, which are a different thing from the audit trail.
- Accounts & access — the roles and bindings whose use is being recorded here.