Перейти к содержимому

Snapshots, diff & drift

Every collection produces a snapshot — one immutable, content-hashed capture of a device’s config. Snapshots are what the tracker versions, diffs and watches for drift, and — because Taranac is your AAA server — what it can attribute to the operator who made the change.

Three versions on the rail: v1 the first capture, v2 pinned as the baseline, v3 the latest — drifted from the baseline — with the diff and the operator resolved from TACACS+ accounting.
TermWhat it is
SnapshotOne capture, stored with its content hash, size and capture time. Text is stored inline; a text capture past the store threshold and every binary config are stored hash-only — versioned by hash, with no stored body and no diff.
Version (v{n})A per-config sequence number — v1 is the oldest capture, v{n} the newest. It counts that config’s snapshots in capture order.
Content hashA SHA-256 of the stored body (for a binary config, of the captured bytes). It’s how the tracker decides whether a capture is a change or a duplicate.
BaselineThe one snapshot per config you declare “known-good.” Drift is measured against it.
DriftThe latest capture’s hash no longer matches the baseline’s hash.
Config statusA derived health value shown on the Configs list (below).
AAA activityWho logged in, which commands they ran, and the session accounting — in the window between two versions.

When a collection completes, Taranac hashes the config as it will be stored and compares it to the latest snapshot only:

  • Same hash → nothing is stored. The run records the target as unchanged; no new version is cut.
  • Different hash → a new snapshot is stored and the version number advances (changed).

Because comparison is against the latest snapshot (not the whole history), reverting a device to an older config is correctly recorded as a new change — the hash differs from the current latest, so a new version is cut. Version numbers are per config, so every tracked config has its own clean v1…v{n} timeline.

By default the stored body is the scrubbed one — volatile lines trimmed, secrets masked (see scrub sets). Since 1.2.6 that is no longer unconditional.

A scrub set carries a Mask secrets automatically switch. When the tracked config’s recipe points at a set that has it off, the set’s own rules become the entire policy — and with no rules at all, the configuration is stored exactly as the device returned it. Real secrets are then in the ordinary body, and they appear that way in the diff, in drift notifications and in exports, to anyone holding ncm_tracked_configs.view.

All three conditions have to hold for that: the recipe points at a scrub set, that set has Mask secrets automatically off, and the set’s rules don’t mask the value. A recipe with no scrub set — or no recipe at all — is always fully masked.

Separately, and much more narrowly, a recipe can keep a second, encrypted copy of the unscrubbed capture (Keep an unmasked copy of every capture, off by default). The ordinary body stays masked exactly as before; reading the copy is a distinct, audited action — see Revealing the raw body.

Any version can be pinned as the baseline — the config you consider correct. From then on, the tracker compares each new capture’s hash to the baseline’s:

  • Latest hash matches baseline → the config is in sync.
  • Latest hash differs → the config is drifted, and it’s flagged the instant the drifting capture lands.

There is exactly one baseline per config: pinning a new one moves the marker off the old version. A config with no baseline is never “drifted” — drift is defined only relative to a baseline you’ve set.

Beyond the baseline, a version can also carry a free-form tag — a short Label plus an optional Description — to mark releases or maintenance windows in the history. Add, edit or remove it from the pencil on that version in the Versions rail; a version holds at most one. A tag is organisational only: it pins nothing, moves no baseline and doesn’t affect drift. Its label is searchable in the compare-version picker, alongside a content-hash prefix.

The Configs list shows a derived status per tracked config. It is computed at read time in priority order (the first that applies wins):

StatusMeaning
DisabledThe config is disabled and is not collected.
Collector offlineA collector that serves this config’s addresses is offline.
FailingThe most recent scheduled collection failed (with a failure class — auth, transient or partial).
DriftedThe latest capture’s hash differs from the baseline’s.
Never collectedNothing has been captured yet.
OKCollected, and either matching the baseline or with no baseline set.

Open a config and pick a version on the Versions rail to see a side-by-side diff. By default a version is compared to the one before it; you can also compare against:

Compare modeDiffs the selected version against…
Previous (default)The capture immediately before it.
BaselineThe pinned baseline (shows the full drift).
Any version…Any other version you pick, from a searchable picker.

The diff renders as aligned Side by side rows or an Inline unified view, with long runs of unchanged lines collapsed (click to expand) and added / removed / modified counters. Alongside it the toolbar carries View full — the whole stored configuration instead of the diff — plus Download, Copy and Fullscreen.

Word wrap exists on both the diff and the full configuration view, and the setting is shared between them: flip it in one and the other follows. The full view is windowed, so a configuration of tens of thousands of lines opens immediately instead of freezing the tab.

Download and Copy always emit the stored body — never a revealed raw one, even after a reveal.

CaseWhat you get instead
Binary configAn artifact card with size, capture time and content hash. Binary snapshots are hash-only: no diff, and no bytes to download.
Oversized textA distinct card — the version is tracked, the body was not stored, and raising the threshold is what changes that. The diff is refused outright rather than reporting the whole file as deleted.
Very large textPast roughly 10,000 lines the side-by-side view is dropped and only the unified diff is rendered; past roughly 20,000 lines no inline diff is rendered at all and the panel points you at Download / Copy to compare in your own tools.

The oversized threshold is ncm.text_store_max_bytes, one of three capture-size limits — see the settings reference.

When the config’s recipe kept an unmasked copy, a version that carries one shows two extra buttons in the diff toolbar: Reveal raw and Download raw.

Both require ncm_tracked_configs.reveal_raw (Reveal raw config) — a separate, high-privilege action that permission to view tracked configs does not imply — and both are written to the activity log before the copy is decrypted, so an access that reaches the stored ciphertext and then fails is recorded just as a successful one is. Saving to a file is audited exactly like reading on screen.

Revealing swaps the panel for the raw text under a standing banner — “Showing the unscrubbed raw body — this reveal is audited.” — and the reveal is per version: move to another version on the rail and it is dropped, so one version’s cleartext can never be shown under another’s identity.

This is what a standalone backup tool can’t do. Open the diff and choose View AAA activity: Taranac shows who touched that device in the window between the two versions being compared(previous capture time → this capture time]. (For the very first version, it looks back 24 hours.) The drawer has three tabs:

TabShowsSource
AuthenticationWho logged in, from where, and whether it succeeded.TACACS+ and RADIUS
AuthorizationWhich commands were run, permit/deny.TACACS+ only
AccountingSession start/stop and elapsed time.TACACS+ and RADIUS

The honest limit: per-command attribution needs TACACS+ command authorization. A RADIUS-only device still gives you who-logged-in and session accounting — it just can’t tell you the individual commands, because RADIUS device administration doesn’t record them. (802.1X / MAB network-access sessions are excluded — this is device-admin activity only.)

Correlation is by device address: the activity is matched to the config’s addresses against the AAA logs’ NAS-IP. That’s a heuristic on the same network identity, so keep a tracked config’s addresses accurate for the attribution to line up. A user filter and per-tab counts let you narrow to one operator quickly.

Captures happen inside a collection run, listed under Configuration Tracker → Collection Runs:

  • Scheduled — a leader-driven periodic sweep collects every enabled config; the sweep interval is the collection cadence (there’s no per-config schedule).
  • On demand — an operator’s Collect now on a single config.

A run’s status is running, completed, or interrupted (an interrupted run is one whose lease expired mid-flight — e.g. an HA failover — and is never resumed). Each target in a run gets a per-device result: ok (first capture), changed, unchanged or failed.

The Collection Runs journal in the Taranac admin UI The Collection Runs journal: scheduled sweeps and on-demand collects, each with its per-device tally of collected / changed / unchanged / failed. Failed results carry a failure classauth (never retried, to avoid tripping device lockouts), transient (retried with backoff) or partial (holds the last-good). When a config’s scheduled collections fail repeatedly, Taranac escalates a collection-failed alert.

Prove nothing changed overnight. Sort the Configs list by status; anything not OK stands out. For a clean config, the version rail shows no new version since the baseline.

Investigate an unexpected change. Open the drifted config, diff the latest version against the baseline to see the full delta, then View AAA activity to see who logged in and what they ran in that window.

Roll back and record it. Restore the device to a known-good config out-of-band, then Collect now. The revert is captured as a new version (hash differs from the drifted latest), and pinning the restored version as the baseline clears the drift.

You want to…Do this
See what changed between two capturesSide-by-side diff, Previous mode
See everything that drifted from known-goodDiff against Baseline
Compare two arbitrary versionsDiff in Any version… mode
Read the whole configuration, not just the deltaView full on the diff toolbar
Read a real password on a version that kept oneReveal raw — needs Reveal raw config, and is audited
Find out who made a changeView AAA activity on the diff
Define what “correct” means for a devicePin baseline on the good version
Mark a version for your own reasonsAdd a tag from the pencil on the version
Force a fresh capture nowCollect now

Snapshot facts:

FieldNotes
VersionPer-config sequence number, oldest = v1.
Content hashSHA-256 of the stored body; the only de-dup and drift signal.
Content kindtext (stored inline) or binary (hash-only, no diff, no download).
OversizedA text capture past ncm.text_store_max_bytes: version recorded, body not stored, diff refused.
SizeThe real captured size — reported even when the body wasn’t stored.
Captured atWhen the snapshot was taken.
AttributionThe AAA-derived “who changed it,” computed at capture.
LabelsThe baseline anchor, plus an optional user tag (label + description).
Raw bodyPresent only when the recipe kept an unmasked copy; encrypted; revealable only with ncm_tracked_configs.reveal_raw.

Compare modes: prev (default) · baseline · snapshot. Run triggers: scheduled · on_demand. Run statuses: running · completed · interrupted. Per-device results: ok · changed · unchanged · failed (classes auth · transient · partial).