- Workspace events are Redis invalidation hints for mounted UI.
- Builder and app-agent streams are ordered user-visible run streams.
- Audit events are append-only, queryable workspace records.
Permissions
Workspace-wide audit logs requireaudit:read. Owners and admins have this
permission by default; members do not.
Audit reads always go through requireWorkspaceContext, then check
audit:read, then query audit_events with workspaceId. Looking up an audit
event by ID also includes workspaceId, so an event from another workspace
returns 404.
Exports are not part of the open-source v1 implementation, so there is no
audit:export permission yet.
Event shape
Every audit event records:
The schema is intentionally close to OpenTelemetry-style log fields, but Second
keeps a first-party store so local and on-prem deployments work without an
external SIEM.
What is recorded
Open-source v1 records the core governance and platform events:
The audit settings page includes an event-explanation catalog with the same
coverage map. It also marks enterprise-later rows such as generated-app SDK
business events, exports, SIEM export, live audit streaming, advanced analytics,
saved views, legal hold, and retention controls.
Redaction
Audit metadata is sanitized before storage. The recorder strips control characters, caps metadata depth/size, truncates long strings and arrays, and redacts sensitive keys. Never store these in audit events:- source files, compiled artifacts, sourcemaps
- prompts, assistant messages, reasoning, full transcripts
- full app documents or full app-data documents
- integration secret values, OAuth tokens, API keys, cookies, sessions
- raw request headers, request bodies, or provider responses
- internal tokens, connection strings, private keys
Performance model
Audit history is not loaded on app lists, sidebar navigation, settings shells, chat routes, or access checks. The audit settings page uses bounded read APIs and manual refresh. Open-source v1 does not add an audit EventSource route. If live audit streaming is added later, it should use compact projections and must still authorize the connection withaudit:read.
Builder chat and app-agent streaming paths use nonblocking audit writes where
waiting on audit storage would make stream startup or completion feel slower.
The durable run/app mutation remains the source of truth if an audit insert
fails.
Tenant isolation
Every stored event hasworkspaceId. Every audit read includes workspaceId.
Target IDs are never used alone for lookup.
Browser-origin data is never trusted for actor, workspace, app, or source trust.
The server sets those fields from authenticated workspace context or from
validated internal worker context.