Skip to main content

Audit API

Table of Contents

Top

upsquad/audit/v1/audit.proto

ActorIdentity

ActorIdentity is the resolved actor for an audit event.

FieldTypeLabelDescription
agent_idstringagent_id mirrors event.agent_id for client convenience.
namestringname is the agent's human-readable name (agents.name).
team_idstringteam_id is the agent's team UUID (agents.team_id).
clearanceint32clearance is the agent's clearance level (agents.clearance, 1..5).

AuditEvent

AuditEvent represents a single row from the agent_audit_log table.

FieldTypeLabelDescription
event_idstringevent_id is the primary key (UUID).
timestampgoogle.protobuf.Timestamptimestamp is when the event was created.
agent_idstringagent_id is the agent that performed the action.
session_idstringsession_id is the session in which the action occurred.
action_typestringaction_type is the type of action (e.g. "tool_call", "llm_call").
input_hashstringinput_hash is the hash of the action input.
output_hashstringoutput_hash is the hash of the action output.
detailstringdetail is the JSONB detail column serialised as a JSON string.
duration_msint32duration_ms is the action duration in milliseconds.
token_usagestringtoken_usage is the JSONB token usage column serialised as a JSON string.

DeleteViewRequest

DeleteViewRequest soft-deletes a saved view by id.

FieldTypeLabelDescription
idstringid is the saved-view UUID to delete. Must match an undeleted row in the calling auditor's tenant. NotFound otherwise.

DeleteViewResponse

DeleteViewResponse is intentionally empty — the soft-delete is the success signal.

ExplainEventRequest

ExplainEventRequest selects a single audit event by id. org_id is taken from the gateway-injected metadata; request-body org_id is ignored. GAP-15.

FieldTypeLabelDescription
event_idstringevent_id is the agent_audit_log row id to explain. Required.
related_windowint32related_window caps the number of preceding + following session events returned in related_events. Clamped to [1, 25]; default 10 (5 before + 5 after, when available).

ExplainEventResponse

ExplainEventResponse bundles the structured breakdown of an audit event for the redesigned drawer. Every field is server-rendered: the client portal does no further enrichment beyond presentation. GAP-15.

FieldTypeLabelDescription
eventAuditEventevent is the verbatim audit row (matches the AuditEvent message returned by ListAuditEvents).
actorActorIdentityactor is the resolved agent identity (name, team, clearance) for event.agent_id. Nil for gateway-plane events whose agent_id is empty.
resourceResourceRefresource is the affected target inferred from the event detail (tool name, model id, etc.). Nil when the event has no obvious target (e.g. session_started).
payload_prettystringpayload_pretty is event.detail re-marshalled with sorted keys and 2-space indentation for direct rendering in the drawer's <pre> panel. Empty when detail is empty.
related_eventsAuditEventrepeatedrelated_events is the preceding + following slice of the same session ordered by created_at ASC. Includes the requested event itself for client-side highlight by event_id. Capped by ExplainEventRequest.related_window.
narrativestringnarrative is a deterministic one-line plain-English summary of the event (e.g. "An AI agent on the Customer Support team called tool Stripe.refundCreate. The action was scoped to standard clearance and the system returned ALLOWED."). Server-rendered so every client gets the same wording. Always non-empty.
narrative_sourceNarrativeSourcenarrative_source documents how the narrative was produced. Today only DETERMINISTIC is emitted; the field exists so a future wave can swap in an LLM-cached narrative without a wire break.

ListAuditEventsRequest

ListAuditEventsRequest carries optional filters and pagination for querying the agent_audit_log table. All filters are optional; omitting a filter means "match all" for that dimension. Results are returned newest-first.

FieldTypeLabelDescription
start_timegoogle.protobuf.Timestampoptionalstart_time lower-bounds the created_at filter (inclusive).
end_timegoogle.protobuf.Timestampoptionalend_time upper-bounds the created_at filter (exclusive).
agent_idstringoptionalagent_id filters events to a single agent.
action_typestringoptionalaction_type filters events by action type (e.g. "tool_call", "llm_call").
pageint32page is the 1-based page number. Defaults to 1.
page_sizeint32page_size is the number of events per page. Max 100, default 50.
verdictstringrepeatedverdict filters events by UI-level verdict bucket. Accepted values: "PASS"
clearanceint32repeatedclearance filters events to those produced by agents whose clearance level is in the given set (1..5). Multiple values are OR-ed; an empty list is treated as "match all". Events with NULL agent_id (gateway-plane config events) are excluded when this filter is non-empty.
querystringquery is a free-text needle matched case-insensitively against agent_id, session_id, action_type, and the JSONB detail blob. An empty string is treated as "match all".

ListAuditEventsResponse

ListAuditEventsResponse carries a page of audit events plus total count.

FieldTypeLabelDescription
eventsAuditEventrepeatedevents is the list of audit events for the requested page.
total_countint32total_count is the total number of events matching the filters.

ListSavedViewsRequest

ListSavedViewsRequest is owner-scoped by construction; no filters yet.

ListSavedViewsResponse

ListSavedViewsResponse carries the calling auditor's saved view rail, sorted by last_used_at DESC NULLS LAST, then created_at DESC.

FieldTypeLabelDescription
viewsSavedViewrepeatedviews is the calling auditor's saved view rail. Empty when the auditor has not persisted any views yet.

OrgDateScope

OrgDateScope verifies every chained session for org in [since, until). Empty since / until disables that bound.

FieldTypeLabelDescription
org_idstringorg_id is populated from gateway claims (see SessionScope.org_id).
sincegoogle.protobuf.Timestampsince lower-bounds the walk (inclusive). Empty = no lower bound.
untilgoogle.protobuf.Timestampuntil upper-bounds the walk (exclusive). Empty = no upper bound.

ResourceRef

ResourceRef is a best-effort reference to the target the action touched. Inferred from event.detail; not authoritative.

FieldTypeLabelDescription
kindstringkind is a short string ("tool", "model", "approval", "session", "config", "subagent"). Empty when no target was inferable.
namestringname is the human-readable identifier ("github.create_pr", "claude-sonnet-4-20250514", session id, …). Empty when not inferable.

SaveViewRequest

SaveViewRequest persists a new saved view for the calling auditor.

FieldTypeLabelDescription
namestringname is the human-friendly label (1-120 chars after trim). The (owner, name) pair must be unique within the tenant; collision is mapped to AlreadyExists.
filtersListAuditEventsRequestfilters is the ListAuditEventsRequest shape to persist.

SaveViewResponse

SaveViewResponse returns the persisted view — including the server-generated id, created_at, and updated_at.

FieldTypeLabelDescription
viewSavedViewview is the persisted saved view, including the server-generated id, created_at, and updated_at.

SavedView

SavedView is one row of the audit_saved_views ledger surfaced to the client portal saved-views rail. See migration 088.

FieldTypeLabelDescription
idstringid is the saved-view UUID.
namestringname is the human-friendly label (max 120 chars).
filtersListAuditEventsRequestfilters is the verbatim ListAuditEventsRequest filter shape that gets re-applied when the view is recalled.
owner_member_idstringowner_member_id is the member id that created the view. The service populates this from the authenticated context — request-body values are ignored.
created_atgoogle.protobuf.Timestampcreated_at is when the view was first persisted.
updated_atgoogle.protobuf.Timestampupdated_at is when the view was last mutated (saved or recalled).
last_used_atgoogle.protobuf.Timestampoptionallast_used_at is when the view was most recently materialised back into a ListAuditEvents call. Empty for freshly created views.

SessionScope

SessionScope verifies the chain for a single (org, session).

FieldTypeLabelDescription
org_idstringorg_id is populated from gateway claims; request-body value is ignored and the claims value always takes precedence.
session_idstringsession_id is the session whose chain to verify.

TaskScope

TaskScope verifies a single Task's coordinator_audit_log chain (#1248).

FieldTypeLabelDescription
org_idstringorg_id is populated from gateway claims; the request-body value is ignored and the claims value always takes precedence (tenant isolation, mirroring SessionScope.org_id).
task_idstringtask_id is the Task whose coordinator_audit_log chain to verify.

VerifyChainRequest

VerifyChainRequest selects the scope to verify. Exactly one of the scope oneof variants must be set.

FieldTypeLabelDescription
sessionSessionScopesession verifies a single (org, session) chain.
org_rangeOrgDateScopeorg_range verifies every chained session in an org across a date range.
taskTaskScopetask verifies a single Task's coordinator_audit_log chain — the Coordinator's per-Task hash-chained audit surface (ADR-0015, migration 093), separate from agent_audit_log (session/org). Added for #1248 (D1 audit track): the platform's audit surface now spans two chains and VerifyChain must cover both.

VerifyChainResponse

VerifyChainResponse reports the outcome of a verifier walk.

FieldTypeLabelDescription
okboolok is true only when every chain_epoch>=1 row in scope linked correctly (prev_hash / row_hash / content invariants all held).
total_rowsint32total_rows is the count of chained rows inspected.
broken_at_rowint32broken_at_row is 1-based within the failing session; 0 when ok.
broken_row_idstringbroken_row_id is the id of the first offending row; empty when ok.
session_idstringsession_id echoes the failing session (session scope) or the first broken session (org scope). Empty when ok.
verified_atgoogle.protobuf.Timestampverified_at is the wall-clock time the walk completed.
sessions_verifiedint32sessions_verified is the number of chained sessions walked (org scope).
sessions_brokenint32sessions_broken is the number of sessions that broke (org scope).
broken_reasonstringbroken_reason is a human-readable reason for the first break; empty when ok.

NarrativeSource

NarrativeSource documents how ExplainEventResponse.narrative was produced.

NameNumberDescription
NARRATIVE_SOURCE_UNSPECIFIED0UNSPECIFIED: zero value reserved for unset / unknown. The handler never emits this — every response carries an explicit source.
NARRATIVE_SOURCE_DETERMINISTIC1DETERMINISTIC: server template applied to event fields. No external call. Stable wording across calls.
NARRATIVE_SOURCE_LLM_CACHED2LLM_CACHED: pre-computed via the platform LLM gateway and persisted alongside the row. Reserved for a follow-up wave; not emitted today.

AuditService

AuditService exposes the tenant-facing audit-log read surface: a paginated event list and the hash-chain verifier. Both RPCs are gated at the gateway by COMPLIANCE_AUDITOR clearance (L4 Director) and RLS-scoped to the caller's org. See LLD §5.

Method NameRequest TypeResponse TypeDescription
ListAuditEventsListAuditEventsRequestListAuditEventsResponseListAuditEvents returns a paginated list of audit log entries for the calling tenant, with optional time-range and attribute filters. org_id is injected by the gateway from verified JWT claims — callers MUST NOT supply it in the request body.
VerifyChainVerifyChainRequestVerifyChainResponseVerifyChain walks the audit-log hash chain for the requested scope and reports integrity. Scopes: a single session, or an org over a date range. See docs/lld/wave1-item4-audit-hash-chain.md.
ListSavedViewsListSavedViewsRequestListSavedViewsResponseListSavedViews returns the calling auditor's saved view rail, sorted by recently-used (last_used_at DESC NULLS LAST, then created_at). GAP-14 (#1080). Owner-scoped: an auditor only sees views they created. Soft-deleted views are excluded.
SaveViewSaveViewRequestSaveViewResponseSaveView persists a new saved view scoped to the calling auditor. The (owner, name) pair must be unique within the tenant — the service maps the conflict to AlreadyExists. GAP-14.
DeleteViewDeleteViewRequestDeleteViewResponseDeleteView soft-deletes a saved view. The owner can always delete their own view; deletion of someone else's view is rejected PermissionDenied (the AuditService clearance gate already restricts this RPC to COMPLIANCE_AUDITOR + above; a per-row owner check on top of that prevents two L4 auditors from clobbering each other's rails). GAP-14.
ExplainEventExplainEventRequestExplainEventResponseExplainEvent returns a structured breakdown of a single audit event for the redesigned drawer (audit-log.jsx EventDrawer). The response bundles: actor identity (resolved from agents row), full event payload pretty-printed, the related-event chain (preceding + following events sharing the same session), and a deterministic one-line plain-English summary suitable for the drawer's "Plain-English explanation" panel. RLS-scoped via gateway-injected org_id; clearance-gated to COMPLIANCE_AUDITOR + above. GAP-15 (#1081).

Scalar Value Types

.proto TypeNotesC++JavaPythonGoC#PHPRuby
doubledoubledoublefloatfloat64doublefloatFloat
floatfloatfloatfloatfloat32floatfloatFloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intintint32intintegerBignum or Fixnum (as required)
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/longint64longinteger/stringBignum
uint32Uses variable-length encoding.uint32intint/longuint32uintintegerBignum or Fixnum (as required)
uint64Uses variable-length encoding.uint64longint/longuint64ulonginteger/stringBignum or Fixnum (as required)
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intintint32intintegerBignum or Fixnum (as required)
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/longint64longinteger/stringBignum
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intintuint32uintintegerBignum or Fixnum (as required)
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/longuint64ulonginteger/stringBignum
sfixed32Always four bytes.int32intintint32intintegerBignum or Fixnum (as required)
sfixed64Always eight bytes.int64longint/longint64longinteger/stringBignum
boolboolbooleanbooleanboolboolbooleanTrueClass/FalseClass
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicodestringstringstringString (UTF-8)
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr[]byteByteStringstringString (ASCII-8BIT)