Skip to content

Audit log

The audit log is an append-only record of state mutations. Every operator action and notable system event appends a row; nothing updates or deletes one.

Read it from the Audit surface in the TUI and GUI, or query it:

GET /api/audit?limit=50&offset=0

limit is clamped to 1–500 and offset to >= 0. Rows are returned newest first.

Each entry carries:

FieldMeaning
actorThe verified operator login, workflow/system for internal events, or unknown when unauthenticated
actionDotted action name, e.g. config.patch
targetWhat was acted on — a key list, issue reference, credential id, and so on
created_atTimestamp

Operator and API mutations include (not exhaustive):

  • config.patch — target is the comma-joined list of applied keys.
  • credential.upsert / credential.delete.
  • health_check.create / health_check.update / health_check.delete.
  • skill.create / skill.update / skill.delete.
  • operator.backlog.create / update / delete / attach / detach / promote.
  • operator.board.archive / operator.board.unarchive.
  • operator.chat and operator.chat.delete / operator.chat.new / operator.chat.clear.
  • operator.message and operator.chat.file when Chat or the message composer files work.
  • workflow.terminate, workflow.optimize.trigger, workflow.github_sync.trigger.
  • workflow.self_heal.failed, workflow.harness_converge.failed, workflow.optimize_performance.failed, workflow.pentest.failed, and other workflow failures.

Workflow state transitions are also durable, but the per-run chronological record lives in the workflow step log, not the audit log.

The operator identity comes from X-Auth-User (verified session or oauth2-proxy) or X-Forwarded-User, then STEELFRAME_OPERATOR on the agent host, then unknown. When operator auth is enabled, the middleware overwrites X-Auth-User with the verified login, so handlers and audit rows cannot see a spoofed identity.

That identity also becomes the footer on GitHub issues the agent files, so an issue reads “submitted by you”, not unknown.

  • The JSON endpoint currently lists all entries; it does not expose action/actor filters even though the DB query supports them.
  • Audit writes are best-effort for some flows: when a secondary audit write fails after a successful mutation, the API reports the mutation as applied (for example, config persisted) and surfaces the audit failure separately.