6.2.2.24 PlatformAuditEvent
Immutable
Records are never updated after creation.
6.2.2.24.1 Purpose¶
Who did what, and when, in the Console and through every admin API: one immutable row per important action, written in the same transaction as the change it records, with the capability that allowed it and the fields that changed. Rows are copied to the locked audit log bucket, so the person who acted can never alter the record of it.
6.2.2.24.2 Questions it answers¶
- Who changed this agent, model profile, role, entitlement or release, and when?
- What did a given staff member do last week?
- Which capability allowed an action, and which request in the technical log was it?
- Who acted, for which Organization, on which one, such as a person of an insurer on a farm that delegated to it?
6.2.2.24.3 Fields¶
| Field | Type | Cardinality | Description |
|---|---|---|---|
id |
string (uuid) |
1..1 |
Key. |
actor |
MoonitoringUser | 0..1 |
The staff member who acted. Exactly one of actor, user and actor_system is set. |
action |
string |
1..1 |
Named like a capability, <system>.<resource>.<verb>, e.g. moochat.agent_models.update, releases.releases.approve. |
capability |
string |
0..1 |
The capability that allowed the action, as checked at that moment. Empty when the action needed none, as a join through a link: its target is the link, which records who created it and with which right. |
target_type |
string |
1..1 |
The entity name, e.g. AgentModelProfile. |
target_id |
string (uuid) |
1..1 |
|
before |
string (JSON) |
0..1 |
|
after |
string (JSON) |
0..1 |
The changed fields only; secrets and prompts are never copied here. |
request_id |
string |
1..1 |
The same id as in Cloud Logging, so the technical log and the audit row meet. |
occurred_at |
datetime |
1..1 |
|
user |
User | 0..1 |
The Organization user or ServiceAccount who acted, e.g. an owner who changes a role, a person who joins through a link, a member who requests a closure. |
organization |
Organization | 0..1 |
The Organization the action concerns, when it concerns one; it lets an Organization's owners read the audit of their own Organization. Through a delegation it is the subject, the farm the delegatee acted on. |
acting_organization |
Organization | 0..1 |
The Organization the user acted as, the token's active Organization. It differs from organization when they acted through a delegation: "Mario Rossi, for Assicurazioni X, on Cascina Uno". Empty for staff and for a system acting on its own. |
actor_system |
string |
0..1 |
The platform system that acted on its own, with no person asking, e.g. farm disabling the account of a client its sweeper retired; its name, as in the catalog of systems. Not the same as system (PlatformAuditEvent.system), the system that wrote the row.For the job of that name it is access-bootstrap-admin: its event, such as access.moonitoring_access.grant_administrator, has no actor and names in after the operator, the identity of the member of infra-admins who ran the job, so the Console shows who did it. |
system |
string |
1..1 |
The system that made the change and wrote the row, e.g. moochat; access keeps the rows of every system, so the same request_id can appear once per system. |
created_at |
datetime |
1..1 |
6.2.2.24.4 Relationships¶
References
PlatformAuditEvent.actor→ MoonitoringUser (0..1)PlatformAuditEvent.user→ User (0..1)PlatformAuditEvent.organization→ Organization (0..1)PlatformAuditEvent.acting_organization→ Organization (0..1)
Referenced by
AgentToolCall.audit_event(0..1)
6.2.2.24.5 Rules & constraints¶
- Who did what, and when, in the Console, through every admin API and in the administration of an Organization: one row per important action, written in the same transaction as the change it records.
- Kept in the Organizations section because it names Users and Organizations. Rows are never updated or deleted and are copied to the locked audit log bucket; the Console shows them per target and per actor.
- Every write capability of MoonitoringCapabilityEnum produces an event; a read never does. In an Organization, so do the changes of members, roles, groups, invitations, join links, delegations, ownership and closure, and every join through a link.
- Mechanism: the system that makes the change writes the row in its own database, in the same transaction, and publishes it as the event
platform_audit_event.recorded.v1through its outbox; access consumes, consolidates and serves the audit log read-only. A redelivered event is matched by (system,request_id). A lost audit event (dead letter) alerts the platform engineers: it is an incident. - One topic per system: <system>.audit.v1, in the system's own project, where only that system's backend and relay may publish. Pub/Sub carries no identity of the publisher, so one topic shared by every system could not prove where an event came from. access-consumer subscribes to the audit topic of every system and takes the system from the subscription the event arrived on, never from the event; intake refuses, to the dead letter, an event whose
data.systemis not that system or whose action does not start with "<system>.". - Access publishes its own rows to
access.audit.v1and skips them when it consumes, since it already holds them. A Pub/Sub Cloud Storage subscription on each audit topic writes every event to the locked audit log bucket, so the audit of every system, access included, is copied the same way.