Hane Platform
Audit log and usage
How the tamper-evident audit log works and how to search it, how usage, budgets, and model calls are counted, and how undelivered events are handled.
This page explains how Hane records operations and counts usage. It shows how to read the audit log and how to check budgets and model usage.
Audit log
Section titled “Audit log”Hane records operations in your organization in the audit log. This includes changes to members and roles, issuing and revoking API keys, activating definitions, approval decisions, executing outbound actions, and revealing contact values.
Why it cannot be rewritten
Section titled “Why it cannot be rewritten”- The audit log is append-only. There is no way to rewrite or delete records.
- Each record is chained to the hash of the previous one, and a signed checkpoint is written at each boundary. Replacing or removing a record in the middle breaks the chain.
- If the same event arrives twice, it is recorded once.
- Business processing and audit storage are separate; the business side has no permission to rewrite the audit log.
Who did what
Section titled “Who did what”Each record has the following fields.
| Field | Meaning |
|---|---|
type |
What happened (an event type such as platform.api_key.created) |
principal |
The principal: who asked for the operation |
actor |
The actor: what actually made the call (such as your app’s service account) |
engagement_id, operator_tenant_id |
For operations made through an operator engagement, the engagement and the operator’s organization |
subject |
What the operation acted on |
project_id, environment, request_id |
Where it happened and which request |
hash |
The hash chained to the previous record |
Because principal and actor are kept apart, you can trace which user was behind an operation even when your app called with a service account.
Searching
Section titled “Searching”GET /v1/audit/events searches records, newest first. It requires audit:read.
| Parameter | Filter |
|---|---|
type |
Prefix of the event type (for example data.) |
actor |
Actor |
engagement |
Only operations made through an operator engagement |
scope |
project for the current project only, organization for the whole organization |
since, until |
Time range |
cursor, limit |
Paging |
const page = await unwrap( client.GET("/v1/audit/events", { params: { query: { type: "platform.api_key", scope: "organization", limit: 50 } }, }),);GET /v1/audit/events/{seq} returns one record together with the stored body (chained to the previous record’s hash). The console’s “Audit log” page shows the same data.
When audit storage is unavailable
Section titled “When audit storage is unavailable”If too many records cannot reach audit storage, Hane stops high-impact operations. Issuing API keys, activating definitions, deleting documents, executing approved outbound actions, and similar operations are refused with 503 (AUDIT_UNAVAILABLE). Reads and safe operations, such as revoking API keys or the emergency stop, keep working. Once storage is back, Hane resends the pending records and resumes.
| API | Contents | Permission |
|---|---|---|
GET /v1/usage/daily |
Daily counts (public API requests, API Gateway calls, and so on) | usage:read |
GET /v1/usage/overview |
Dashboard numbers (active release, records per type, cases and tasks per status, number of schedules) | usage:read |
GET /v1/agents/budget |
Today’s (UTC) budget, with used and reserved amounts | agents:read |
GET /v1/agents/model-usage |
Model calls through the Model Gateway, totaled per day, agent, and model | agents:read |
The console’s “Usage and budgets” page shows the last 14 days of usage, today’s budget, and a table of model calls. When the share of a budget used passes alertAtPercent (80% by default), the page shows a warning and a usage.budget.alert event is recorded.
Budgets
Section titled “Budgets”Budgets are set per project and environment with a Budget in platform/v1alpha1.
| Field | When the limit is reached |
|---|---|
agentRunsPerDay |
No more agent runs start |
externalActionsPerDay |
No more email, SMS, or call proposals are accepted |
modelTokensPerDay |
Agents that use a model do not start, and running ones stop at the limit |
Days are counted in UTC. See Agents and AgentRuns for an example.
About costs
Section titled “About costs”Undelivered events
Section titled “Undelivered events”Business events reach the audit and notification processing through queues. Events that still fail after repeated delivery are listed in GET /v1/audit/dead-letters. After fixing the cause, requeue one with POST /v1/audit/dead-letters/{id}/retry (which requires audit:dead-letters.retry). Handlers drop duplicates by event ID, so requeuing twice gives the same result.