> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thoras.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Audit Trail

> See who changed scaling behavior, and what changed, from the api-server logs

The api-server logs an audit event for every privileged action it takes:
changing a target's scale mode, pausing or resuming scaling cluster-wide,
cleaning up a removed target, and enrolling new targets. Each event records who
took the action, what changed, and whether it succeeded.

## What's recorded

| Action | Trigger |
| - | - |
| `ast.mode.update` | Changing a target's horizontal or vertical scale mode |
| `system.scaling.update` | Pausing or resuming [autonomous scaling](/guides/pause-scaling) cluster-wide |
| `ast.cleanup` | Cleaning up a removed target's metrics |
| `ast.enroll_candidates` | Enrolling workloads in a namespace (all of them, if none are named) |
| `ast.enroll_all` | Enrolling all namespaces |

Both successful and failed attempts are recorded. A dry-run or count-only
enrollment preview isn't, since nothing is actually changed.

Not every dashboard-reachable change goes through this list yet — cost-savings
settings is the one left out of this first pass.

## Who's recorded

The dashboard forwards the identity of the person who took the action, but only
when [dashboard authentication](/guides/dashboard-auth) can establish one:

| Auth mode | Actor recorded |
| - | - |
| `oidc` | The user's email |
| `htpasswd` | The shared username |
| `auth.enabled: false`, or any direct API call | `unknown` |

If per-person attribution matters to you, use `oidc` mode. `htpasswd` and
disabled auth both share one identity across everyone with dashboard access.

<Note>
  The actor is an attribution hint, not authentication. Anyone holding your
  `apiClientSecret` can call the API directly and set it themselves. It's useful
  for distinguishing a change made through the dashboard from one made by a
  script or another integration, not for proving who made it.
</Note>

## Reading the log

```bash theme={null}
kubectl logs -n thoras deploy/thoras-api-server-v2 | grep "audit event"
```

Each line carries these fields:

| Field | Meaning |
| - | - |
| `actor`, `actor_source` | Who took the action, and how that was determined |
| `action` | One of the values above |
| `target_kind`, `target_namespace`, `target_name` | What was acted on |
| `old_value` | The state before the action, for actions that have one; not every action does |
| `new_value` | The result, set only on success. Absent on a failed attempt — `details.requested` has what was asked for instead |
| `outcome` | `success` or `failure` |
| `error` | Present only on failure |
| `persisted` | Whether this event also made it into the database (see below); `false` means only this log line exists |
| `details` | Extra context specific to the action — a count, a request ID, or what was asked for versus what changed |

Pod logs are subject to your cluster's log retention, so ship api-server logs to
your log aggregator if you need to keep this history longer than that.

## Is there a durable copy?

Yes — every event is also written to a database table before this log line is
emitted, so a log rotation doesn't lose the history. That table isn't a
supported, documented interface yet: there's no API or dashboard view onto it,
its schema isn't stable across releases, and support for querying it directly
isn't something we can commit to today. Treat the log line above as the
supported way to read this trail; `persisted: false` on a line means even the
database copy is missing for that one event, so the log was all there was.
