Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.second.so/llms.txt

Use this file to discover all available pages before exploring further.

Second stores durable audit events in MongoDB so owners and admins can answer what changed in a workspace without reading prompts, source files, secrets, or raw app data. Audit logs are different from the existing realtime systems:
  • 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 require audit: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:
FieldPurpose
workspaceIdTenant boundary. Every query includes it.
occurredAt / observedAtWhen the action happened and when the platform stored it.
eventNameStable dot-delimited name such as member.role_changed.
categoryBroad area such as apps, members, integrations, or app_data.
actorUser, agent, worker, app, or system identity known by the server.
sourcePlatform, builder agent, app iframe, app agent, worker, or system provenance.
targetWorkspace object affected by the event.
outcome / severitySuccess, denial, failure, started, completed, plus importance.
metadataSmall sanitized facts needed for investigation.
changesChanged field names and before/after hashes when useful.
relatedIdsSafe IDs such as app, run, review, integration, or app-data document IDs.
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:
AreaExample events
Apps and builder runsapp.created, builder_run.created, builder_run.started, builder_run.completed, builder_run.failed, builder_message.submitted
Source snapshotsapp.source_snapshot.updated with hash, file count, byte size, and artifact flag only
App metadataapp.renamed, app.deleted, app.visibility_changed, app.teams_changed, app.collaborator_added, app.collaborator_removed, app.collaborators_changed
Review and publishingreview.requested, review.approved, review.changes_requested, review.superseded, app.published
Members and teamsmember.invited, member.invitation_revoked, member.role_changed, member.removed, team.created, team.renamed, team.deleted, member.team_added, member.team_removed
Integrationsintegration.requested, integration.configured, integration.secret_rotated, integration.reset, integration.deleted, oauth.provider_configured, oauth.provider_secret_rotated, oauth.connected, oauth.connect_failed, oauth.revoked, oauth.token_refreshed
Permission denialsaccess.denied for safe same-workspace authorization failures
App-agent governance and runsapp.agents_config.approved, app.agents_config.stale, app_agent_run.created, app_agent_run.started, app_agent_run.completed, app_agent_run.failed
Custom toolstool.custom.executed, tool.custom.denied, tool.custom.mocked, tool.custom.failed
App data writesapp_data.document.inserted, app_data.document.updated, app_data.document.upserted, app_data.document.deleted
Audit usageaudit.viewed through an explicit rate-limited POST
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
For app data writes, audit events store collection name, document ID, operation, source version, changed field names, and before/after hashes. They do not store the document body. For custom tools, audit events store the tool name, integration name/domain, mock-vs-live mode, outcome class, and HTTP status. They do not store headers, secret-injected URLs, request bodies, or response bodies. For OAuth, audit events store safe facts such as provider key, provider config ID, integration ID, connected account ID, requested tool name, outcome, and scope names. They do not store authorization codes, OAuth client secrets, refresh tokens, access tokens, Vault references, token endpoint request bodies, provider response bodies, email bodies, calendar event bodies, or request headers.

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 with audit: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 has workspaceId. 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.