Activity
The audit trail, what it records, what is redacted, how long it is kept, and the two trails behind one store.
Activity
Settings → Activity is the organization's own read view over the audit trail: who did what, when, and to what, inside this organization.
A standalone system, one-directional
The audit trail is not a table in the product database. It is a separate
system (activity-ingestor, activity-api, its own PostgreSQL, its own
Kafka topic) that the backend writes to through an outbox and never reads
from. That boundary is what lets an audit outage never surface as a failure
in the rest of the product: a state-changing request commits its business
change and queues an audit event in the same local transaction, and the
event reaches the store asynchronously from there.
What gets recorded
Four tiers, not a curated subset:
| Tier | Examples |
|---|---|
| Organization actions | member.invited, member.role_changed, monitor.created, service_account.created, api_key.revoked |
| Auth and identity | login, login_failed, logout, mfa_enabled, password_changed (ingested from Zitadel's own event log, not the backend) |
| Platform actions | Anything the up0 platform team does that touches your organization (a suspension, a support data access); visible here for transparency |
| Sensitive reads | Viewing or exporting this very activity list is itself recorded |
Every event carries who (actor_type, actor_id), what happened
(category, action), what it touched (target_type, target_id), when,
and whether it succeeded. Filter by any of these plus a free-text search over
the event's own metadata, then export to JSONL or CSV. Exporting is itself
audited as a data-access event.

No history before auditing began for your organization
The trail cannot be backfilled. An empty result for a period before this system existed for your organization means nothing was captured then, not that something was captured and lost.
The two trails
One append-only store, two scoped read paths: your organization sees only
its own events (visibility = org); the up0 platform team's separate view is
a strict superset covering every organization plus platform-only actions.
When a platform action targets your organization specifically and you are
entitled to know about it (support reading your data, a suspension), it
appears in your trail too, for transparency.
What is redacted
Secrets (tokens, passwords, API keys) are stripped before an event ever
leaves the backend, and the ingestor separately rejects (to a dead-letter
queue) any event whose payload still matches a secret-shaped pattern.
Identifiers (UUIDs like event_id, org_id, actor_id) are explicitly
exempted from that redaction rule, so an event stays traceable without
exposing what it should not.
Retention
Retention is enforced by dropping whole months of data at a time (a metadata-only operation, not a row-by-row scan), on a schedule that is longer for higher-tier plans. Export your own copy before a retention window closes if you need to keep it longer than that.
Owner-only, and why
Reading /settings/activity requires the Owner role. Authorization comes
from a short-lived (five-minute) claim the backend mints for the caller, not
from anything encoded in the Zitadel login token itself: a real access
token from this deployment's Zitadel was verified to carry no organization
or role claim at all, so the backend has to vouch for "this caller is the
Owner of this org" separately, for every read.
Not deployed on this walk's cluster
This page was walked on the local kind cluster, where the audit-trail
services (activity-api, activity-ingestor, their own PostgreSQL and
Kafka topic) are not part of the deployed set; kind runs the up0
umbrella chart's product services only. The page itself renders correctly
and the filter and export controls work; the events panel stays in its
loading state because there is no activity-api to answer it, which is an
environment gap rather than a product one. docs/v2/testing/m18-audit-trail.md
records the dedicated audit-trail/docker-compose.yml stack this system
needs, and its 22 test cases are what a fully wired environment is checked
against.