Skip to content
NebulaCtrldocs

Audit log

The audit events NebulaCtrl records, their fields, how to filter and export them from the Activity page or the API, and what is never written to them.

The control plane writes an audit event for each state-changing action. The Activity page and the API read those events. This page lists the fields, the guarantees, the filters and every action the control plane records.

Quick reference

ConsoleActivity, in the organization's navigation
APIGET /api/v1/activity (listActivity) and GET /api/v1/activity/export (exportActivity)
Who can readEvery role, including viewer. A project-limited API token sees only events of its projects.
ExportCSV only
RetentionKept as long as the organization exists
EditableNo. Events are append-only.

An audit event

FieldMeaning
idThe event's identifier.
atWhen it was recorded, in UTC.
actorTypeuser, token, agent or system.
actorIdThe user's or token's id, the id of the cluster that sent the event, system, or updater for the outcome of a control plane update.
actionWhat happened, such as member.role_changed.
targetA JSON object of ids and names the action touched.
before, afterJSON snapshots, present only for actions that change something.

The console shows the actor by name: the member's name, NAME token or API token, CLUSTER agent, or system. An event with no actor is recorded as system.

Guarantees and limits

  • Append-only. A database trigger rejects every update and every delete of an event. The only exception is the cascade that deletes an organization's events together with the organization.
  • Best effort in places. Most events are written after the action completes. If the write fails, the action still happened, and the control plane logs audit event was not recorded; the action it describes still happened. Events written together with a change, such as organization creation, team changes, SCIM changes and change set transitions, roll back with it.
  • Not in any organization's feed. user.signed_in and user.provisioned belong to no organization.
  • No secrets. Events name which variable, token or credential changed and never its value.
  • One exception. database.queried records the full query text.
  • Outside the record. Changes made directly in the database or inside a cluster.

Filter the Activity page

ControlEffect
Kindall, deploys, config, access or clusters. The API takes kind=deploy, config, access or cluster.
Search boxFilter by actor, target or action matches the action, the actor id and the readable fields of the target. The API parameter is q.
ProjectEvents of one project, directly or through its environments, services and releases. The API parameter is projectId.
Time rangeLast 24h, Last 7 days, Last 30 days or All time. The API takes from and to as RFC 3339 timestamps.
Actor chipSelect an actor's name in a row to filter by them; the chip clears the filter. The API parameter is actorId.

The API also filters by action. Pages hold 50 events by default and at most 200, and the response carries nextCursor and an exact total. The page groups events by UTC day and folds runs of identical actions by one actor into one row.

Select a row to see its action, actor, time, target, and the Before and After values when they exist.

Export

Select Export CSV on the Activity page, or call GET /api/v1/activity/export. The export applies the same filters, ignores paging and walks the whole matching ledger in batches of 500. The file is named activity.csv by the API, and activity-TIMESTAMP.csv by the console.

The header row is:

id,at,actorType,actorId,action,target,before,after

at is RFC 3339 with nanoseconds in UTC. target, before and after are JSON text. If the export fails partway, the file is truncated, and the rows already sent are correct.

Events by kind

The Kind filter groups events by the prefix of their action. Events with the prefixes mesh., template., tailnet., preview., project_config. and backup., and three organization.* security events, fall under no kind. They appear under all, with the chip other; Under no kind lists them.

Deploys

ActionRecorded when
release.created, release.promotedA release is created, or promoted to another environment.
deployment.started, deployment.rolled_back, deployment.cancelled, deployment.supersededA deployment starts, rolls back, is cancelled, or is replaced by a newer one.
approval.requested, approval.decided, approval.expiredA production approval is requested, decided, or expires.
build.queued, build.cancelled, build.superseded, build.release_failedA build is queued, cancelled, replaced, or fails to produce a release.
change_set.submitted, .applied, .failed, .rejected, .discarded, .item_staged, .item_removedA change set moves through its states, or an edit is staged or removed.
service.suspended, service.resumedA service is suspended or resumed.
process.restarted, pod.restartedA process or a pod is restarted.

Configuration

ActionRecorded when
project.created, .updated, .deletedA project changes.
environment.created, .updated, .bound, .cluster_bound, .deletedAn environment changes, or is bound to a cluster, by a person or automatically.
service.created, .updated, .deleted, service.production_approval_changedA service changes, or its production approval rule does.
process.created, .updated, .deletedA process changes.
volume.created, volume.deletedA volume is created or deleted.
variable.set, .deleted, .revealed, .unmanagedA variable is set, deleted or revealed, or stops being owned by nebula.toml.
external_resource.created, .updated, .deleted, .linkedAn external resource changes, or is linked to services.
domain.created, .exposure_updated, .dns_settings_updated, .certificate_method_updated, .deletedA domain changes.
domain.checked, domain.dns_synced, domain.dns_adoptedA domain is checked, its DNS records are synced, or existing records are adopted.
domain.certificate_issued, domain.certificate_renewedA certificate is issued or renewed.
git_connection.created, .deletedA Git connection changes.
registry_credential.created, .deletedA registry credential changes.
object_store.created, .updated, .deletedAn object store changes.
cloudflare_connection.created, .updated, .deletedA Cloudflare connection changes.
notification_channel.created, .updated, .deletedA notification channel changes. The event records whether the secret was replaced, not the secret.
database.created, database.queried, database.pitr_enabled, database.pitr_disabled, database.reader_promoted, database.archive_deletedA database service is created, queried, has point-in-time recovery switched, has a reader promoted, or has its archive deleted.
volume_backup.created, .deleted, .downloaded, .succeeded, .failedA volume backup is taken, deleted, downloaded, or finishes.
volume_restore.created, .succeeded, .failedA volume restore starts or finishes.
volume_backup_schedule.put, volume_backup_schedule.deletedA backup schedule is set or removed.
organization.updatedThe organization's name or default cluster changes.

Access

ActionRecorded when
user.signed_in, user.provisionedA person signs in, or signs in for the first time. Recorded outside any organization.
session.revokedA session ends, by sign-out or revocation.
organization.created, .deleted, .transferredAn organization is created, deleted, or changes owner.
member.role_changed, member.removed, member.leftA member's role changes, or they are removed or leave.
invitation.created, .revoked, .acceptedAn invitation is created, revoked, or accepted by link.
api_token.created, api_token.revokedAn API token is created or revoked.
team.created, .updated, .deleted, team.members_set, team.member_addedA team changes.
scim.token_rotated, scim.token_disabledThe SCIM token is rotated or turned off.
scim.user_provisioned, .user_updated, .user_deleted, .user_bound, .user_deprovisionedThe identity provider provisions, updates, deletes, binds or deprovisions a user. The last records how many tokens and sessions ended.

Clusters

ActionRecorded when
cluster.created, .updated, .deleted, .enrolledA cluster changes, or its agent enrolls.
cluster.enrollment_token_regeneratedThe install credentials are regenerated.
cluster.join_token_created, cluster.join_token_revokedA node join token is created or revoked.
cluster.high_availability_started, cluster.cnpg_install_started, cluster.tailscale_connect_startedOne of those installs is started.
cluster.ssh_key_created, cluster.ssh_install_started, .ssh_install_confirmed, .ssh_install_finishedAn SSH install runs. The events carry the host, port, user and host-key fingerprint, never a key.
cluster.agent.update, cluster.agent.rollbackAn agent update or rollback starts, with the images it moves between.
cluster.cordoned, cluster.uncordonedA cluster stops or resumes accepting new workloads.
node.cordoned, node.uncordoned, node.drainedA node is cordoned, uncordoned or drained.
control_plane.update.requested, .cancelled, .finishedA control plane update is requested, cancelled, or ends. The last is written by the updater or by the control plane when it gives up on a silent updater.

Under no kind

ActionRecorded when
organization.policy_updatedThe change policy or deploy freeze changes.
organization.security_updatedRequire two-factor for everyone changes.
organization.join_token_ttl_updatedThe default join token lifetime changes.
mesh.peer_registered, mesh.peer_revokedA machine joins the mesh, or a peer is revoked.
mesh.grant_created, mesh.grant_deletedCross-environment network access is granted or removed.
preview.settings_updated, preview.created, preview.deletedPreview settings change, or a preview environment is created or deleted.
project_config.set, project_config.removedA project's config repository is set or removed.
tailnet.device_removed, tailnet.device_removal_failedA Tailscale device is cleaned up, or cleanup fails.
template.created, .updated, .deleted, template.installedA template changes, or is installed.
backup.objects_deletedBackup objects are removed when an environment is deleted.

See also

On this page