Skip to content

Releases: TaranacLabs/taranac

Taranac 1.2.2

Choose a tag to compare

@gurkin33 gurkin33 released this 06 Aug 05:23

Added

  • A directory no longer has to be Active Directory. The integration was
    built for AD and said so only in its code: bind by UPN, look accounts up by
    sAMAccountName, track them by objectGUID, filter on userAccountControl.
    Every one of those is false for OpenLDAP, FreeIPA and Google Workspace Secure
    LDAP, which is why connecting one of them could not be made to work by
    configuration alone. A directory now has a type — Active Directory,
    OpenLDAP, FreeIPA, Google Workspace or generic — and the type supplies both
    what the protocol can do there (MS-CHAPv2 and computer sync are Active
    Directory only) and the schema guesses you are free to overwrite (search
    filters, attribute maps, the examples under each field). The type is chosen
    once, when the configuration is created, and cannot be changed afterwards: each
    directory imports accounts by its own login attribute and tracks them by its
    own identifier, so switching would mean converting users already synchronised.
    Existing installations are untouched — a configuration with no type reads
    as Active Directory, and the Active Directory defaults are the previous
    literals character for character.
  • Directory accounts can authenticate with MS-CHAPv2. Devices that offer
    nothing else — MikroTik RouterOS sends only MS-CHAPv2 for an administrator
    login, has no PAP and no TACACS+ client — could not authenticate against
    Taranac at all, which also made the RouterOS RADIUS template shipped in 1.2.1
    unreachable. Local accounts are verified in Taranac itself; an Active Directory
    account is verified by a domain controller, because its password hash is
    unreadable by design. The same now works for 802.1X endpoints: a directory
    account authenticates over PEAP/MSCHAPv2 and over EAP-TTLS. Nothing to switch
    on — the branch is chosen by what the device sends, and a device that sends PAP
    never enters it.
  • The node joins the domain by itself. Add an LDAP configuration with the
    MS-CHAPv2 settings and the installation becomes a domain member using the
    account it already binds with — no computer object created by hand, no
    delegation requested from an Active Directory administrator (a domain's default
    machine-account quota is what makes this possible). The machine account name is
    derived so that a node re-joins its own object, and checked against the
    directory so two installations in one domain cannot overwrite each other. The
    automatic join happens once and never repeats.
  • An MS-CHAPv2 tab on the LDAP configuration — membership per node, the
    feature switch, and a join dialog that asks the directory about the credentials
    and the target organizational unit before spending them, so the commonest
    failures (wrong password, mis-ordered OU path) are named in under a second
    instead of coming back as net ads join's own diagnostics. At most one LDAP
    configuration may own the domain, and the refusal names the one that already
    does.
  • An alert when the domain trust breaks. Narrowly: MS-CHAPv2 is switched on
    and this node can no longer verify a domain password. A member with the feature
    deliberately switched off never pages anyone, and "never joined" is reported as
    an incomplete setup rather than a broken trust.
  • Domain authentication failures are diagnosed, not guessed. Twenty-four
    NT_STATUS codes and nine join failures each map to a cause and a next action —
    expired account, logon-hours policy, a dead controller, NTLM disabled by policy,
    clock skew, a broken machine-account trust — and each carries whether it counts
    as a credential attempt, so a rebooting domain controller no longer looks like
    password guessing.
  • A twelfth service, winbind, ships with every installation. It owns the
    node's Active Directory machine account. Without a domain configured it starts,
    reports "not joined" and does nothing — a service you must first install is a
    service nobody enables, and MS-CHAPv2 is needed exactly by the administrators
    who discover the need at the moment their login fails.
  • Certificate enrollment (EST) works end to end. It was previously
    unreachable by any supported route: the frontend proxied only /api/, so
    /.well-known/est/ returned the web UI's HTML to an enrolling client, and the
    only working path was the API's bare port with an internal-only certificate. EST
    and the revocation lists are now published through the front door on the
    installation's own certificate, and the CRL distribution point is filled in
    automatically.
  • An approval queue for certificate requests. Turning on "require approval"
    used to stop issuance rather than defer it — the request was stored as a
    certificate with serial "0" and placeholder dates, no approval screen existed,
    and every client poll appended another row. Requests are now their own records,
    deduplicated by the request's fingerprint across polls, with a queue in the UI,
    and an approval group that says who gets notified (deciding is nac_pki.edit,
    as it always was).
  • Approve a certificate request from an email link. Members of the approval
    group get the request by mail with what is being issued and to whom. The link
    never acts on being opened: mail scanners, Safe Links and messenger previews
    follow links by themselves, so the GET only shows a page and the decision needs
    a deliberate confirmation.
  • Certificate renewal cannot be fooled by a revoked certificate. A renewal is
    checked against the revocation list before it is granted, so a certificate that
    has been revoked can no longer be used to obtain its own replacement. Renewal
    authenticated by the client's own certificate needs a listener that verifies
    client certificates, which this release does not yet ship — until then a
    renewal authenticates the same way an enrollment does.
  • Master key rotation — ./taranac rotate-key. Runs on a stopped system in a
    single transaction: the operator presents the current key, names the new one, a
    backup is taken, every encrypted column is re-encrypted, the system starts
    again. It can also be rehearsed on a dev stack — a tool with nowhere to practise
    is a tool nobody has practised.
  • A backup that a disaster recovery can actually use. The archive now carries
    .env, the compose file and config/, because the database's secrets are
    ciphertext whose key lives outside it; restoring asks for the five keys that
    matter. pg_dump gained a timeout, so a hung dump no longer occupies the single
    scheduler slot forever while the dashboard shows the last good archive.
  • The username filter matches a substring, case-insensitively. Filtering the
    NAC Auth Log for ad_user1 found nothing when the account had authenticated as
    ad_user1@example.com or EXAMPLE\ad_user1. Applied to the NAC Auth Log, NAC
    Sessions and the AAA logs alike, with trigram indexes on the seven journal
    tables so it stays fast on a large archive (53 ms → 1.5 ms on a 60k-row
    partition).
  • A VLAN filter on authorization profiles — "which profiles drop an endpoint
    into VLAN 40" no longer means paging through the list.
  • EAP-TTLS accepts all three of its inner methods. Native EAP-TTLS/MSCHAPv2 —
    what a supplicant sends with no EAP inside the tunnel — failed for everyone,
    including a local account with the correct password.

Changed

  • The UI downloads only the languages it will show. All seven bundled
    languages (3.58 MB of translations) were part of the entry chunk, so an
    installation running only English still fetched about 3.2 MB it would never
    display. The other languages now load when one is selected.
  • The Security menu section is gone. Authentication & Sessions moved to
    System, and the Crypto page — which existed for a single button that broke
    installations — was removed along with it (see the rotation tool above).
  • The RBAC list no longer shows a Type column or a System/Custom filter. No
    role in a running system is ever a system role, so the column read "Custom" on
    every row and one filter option returned everything while the other returned
    nothing. On upgrade: a custom report dataset built on the config_rbac_roles
    template that had picked the is_system column fails validation on the next run
    and needs its columns re-picked; no seeded dataset uses it.
  • The RADIUS "authentication type" dropdown is gone. It offered PAP / CHAP /
    MS-CHAPv2, and nothing read the value — the handler authenticated with PAP
    regardless. It advertised a capability the product did not have, which is worse
    than no control at all. MS-CHAPv2 now works off what the device actually sends,
    with nothing for an operator to choose.
  • EAP-TEAP is gone from the log filter and the policy schema, having never
    been implemented, and EAP-TTLS — which is fully supported — is finally rendered
    and filterable in the log views and the session drawer.
  • Syslog forwarding has a ceiling and reports what it drops. The forward
    window was unbounded, so after any downtime the whole missed range was loaded at
    once and sent one message per record; on a large installation that is not a
    slowdown but an outage, at the moment the system comes back.
  • The dashboard stops polling while its browser tab is hidden.

Fixed

  • Re-authentication no longer loses a session's identity, and a session the
    NAS keeps reporting is no longer archived behind the operator's back. An 802.1X
    re-authentication closes one session and opens the next milliseconds apart on
    the same port, which is what made the active session show LAB\anonymous.
  • A CoA "session not found" no longer kills a live session. The switch's 503
    answers "did I find a session matching your identifiers", not "is anybody on the
    network" — it usually means the port re-authenticated in place. Taranac used to
    archive the session and tell the operator the disconnect had succe...
Read more

Taranac 1.2.1

Choose a tag to compare

@gurkin33 gurkin33 released this 30 Jul 21:06

Added

  • Wider vendor coverage for device administration. RADIUS admin-auth
    templates go from 8 to 15 and TACACS+ from 12 to 16, adding MikroTik RouterOS,
    Arista EOS, Aruba CX, Nokia SR OS, H3C/Comware, Ruckus/Brocade ICX and Extreme
    EXOS. The NAC vendor dictionary gains Extreme EXOS and Ruckus ICX as 802.1X
    authenticators (both with CoA port bounce), and the mislabelled "Aruba" entry
    is split into Aruba AOS-CX / Controllers and a distinct HP ProCurve. New
    built-in vendors now also reach an existing install on upgrade, without
    overwriting anything you edited.
  • Readable FortiGate command accounting. FortiGate reports only a category
    word (Config, Show, Diagnose, Execute) in the command field and puts the actual
    command elsewhere, so command accounting from a FortiGate was near-useless.
    Records from a FortiGate now show the real command, in both the log views and
    the syslog export.
  • Oversized device configurations are tracked instead of failing. A text
    configuration larger than a configurable threshold is now recorded as a
    version — its change is still detected and dated — without storing the body.
    The configuration page and the version timeline say so plainly, rather than
    showing an empty diff. Large binary artefacts and very large text captures
    also no longer fail the whole collection.
  • Capture limits are now settings. Three system settings replace hard-coded
    ceilings — the size past which text is stored by hash only, the largest text a
    capture will buffer, and the largest binary it will download — so an install
    that legitimately needs more can raise them.
  • Word wrap in the full configuration view. The diff had a word-wrap control
    and the full-text view did not; it now has the same one, and the preference
    carries across both views.
  • Taranac Push MFA is available again. The provider card is configurable and
    enrollable once more, marked "Soon" while the mobile app rolls out.
  • LDAP configurations show up under an RBAC model's "Used By". A model
    referenced by an LDAP configuration's default role or a group override was
    invisible to the where-used view and could be deleted, leaving a dangling
    reference. It is now listed and deletion is blocked until the reference is
    removed, matching how groups already behave.

Changed

  • Large configurations open instantly. Viewing the full text of a
    configuration with tens of thousands of lines used to freeze the tab; the view
    is now windowed and opens immediately at any size.
  • Much lighter page loads across the UI. Forms and detail pages no longer
    pull whole catalogues just to show the name of something you already selected —
    users, groups, TACACS+ and RADIUS profiles, NCM credentials, sources, recipes
    and configurations, LDAP RBAC assignments and the report builder all read those
    names from the payload and pick through a server-searched drawer instead.
    Opening an NCM configuration drops from about 27 requests and 37 MB to about 5
    requests and 2.5 MB. This also removes a silent limit: those catalogue fetches
    capped out at 100 entries, so past that the picker quietly hid the rest.
  • A too-large capture is reported as such, not retried. It used to be
    classified as a transient error, which spent the full retry budget — three
    extra device logins per configuration, every sweep — and told the operator a
    size problem was a network problem. It now fails immediately and names the
    setting to raise.

Fixed

  • Daemon configuration is re-checked against the current version at startup.
    The reload skip-gate added in 1.2.0 watches for data changes, so after an
    upgrade that changed how a configuration is generated the new configuration was
    not deployed until some unrelated data change or a manual Reload. Each daemon
    now reconciles its on-disk configuration once per boot.
  • "Sources" is highlighted in the NCM sidebar. It was the one NCM settings
    page routed outside /ncm/settings, so the section never expanded for it on a
    page refresh. Old bookmarks redirect to the new path.
  • The PKI certificates page no longer loads twice. Selecting a CA fired two
    identical requests for the certificate list.

Taranac 1.2.0

Choose a tag to compare

@gurkin33 gurkin33 released this 27 Jul 12:33

Added

  • Reports. A new reporting surface across AAA, NAC, and audit data. Save
    dataset presets over the built-in report templates, compose them into
    multi-page reports, and schedule periodic e-mail delivery of a report or
    dataset. Every view exports to CSV, XLSX, and PDF, with bar/line/pie/multiline
    charts and a catalogue of ready-made presets. PDF rendering is handled by a new
    internal rendering service. Reports and datasets support a read-only view,
    so you can grant look-but-don't-edit access.
  • Reports on the dashboard. A dashboard widget surfaces your saved reports at
    a glance.
  • Backend-driven password policy. Password length and complexity rules are
    enforced consistently everywhere a password is set or changed — the same rules
    in the web UI and on every login path.
  • MFA push-expiry audit. An MFA_PUSH_EXPIRED event is now recorded when a
    push approval request expires unanswered.

Changed

  • "Must change password" is enforced at device login. A local account flagged
    to change its password is now denied TACACS+/RADIUS/NAC sign-in until the
    password is changed, instead of only being blocked in the web UI.
  • Faster configuration reloads on large deployments. The TACACS+/RADIUS/NAC
    config auto-reload skips a full regeneration when nothing config-relevant has
    changed, and generation no longer blocks the control-plane event loop — a large
    reduction in idle CPU on big device inventories.
  • Correct timezone for scheduled jobs across nodes. The system timezone is
    resolved without stale caching, so scheduled reports and jobs fire at the right
    local time on every node.
  • Faster selection in picker drawers. Choosing members, groups, devices,
    endpoints, or datasets in a selection drawer now takes effect on click, instead
    of requiring a separate "apply" step.

Fixed

  • TACACS+ logging can no longer be wedged by one bad batch. A single poison
    log batch is dropped instead of stalling the entire authentication-log writer.
  • Fresh-install backups. Creating a backup on a new install no longer fails
    with a 500 (the backups volume is initialised with correct ownership at boot).
  • Auth settings form. Nested fields and zeroed values now persist correctly.

Taranac 1.1.2

Choose a tag to compare

@gurkin33 gurkin33 released this 23 Jul 12:08

Added

  • Matched policy rule in TACACS+ log detail. The authentication and
    authorization log detail views now show the UUID of the policy rule that
    matched, alongside its name — a stable identifier for correlation.

Changed

  • Precise LDAP sign-in failure reasons. A failed LDAP/Active Directory login
    now reports the specific cause — wrong password, account locked, disabled,
    expired, or "must change password" — instead of a generic "invalid credentials".

Fixed

  • Non-shell vendor authorization profiles now deploy correctly. TACACS+
    profiles built on a non-shell template (Juniper junos-exec, FortiGate, Palo
    Alto, …) were reduced to a generic shell / privilege-15 block in the deployed
    daemon config and the Policy Tester preview, even though the per-profile config
    preview was correct. The daemon config now renders every vendor service and raw
    attribute, matching the preview.
  • Correct privilege level for a just-created user's first login. A user created
    moments earlier could authenticate but be granted a default privilege level on
    that first session, because the (separately handled) authorization step didn't
    yet know the new user. Authorization now loads the user the same way login does,
    so the privilege level from the matched policy rule applies immediately.
  • TOTP replay protection now holds across the whole server. A one-time MFA code
    can no longer be reused within its short validity window by directing the retry
    at a different worker process or cluster node; used codes are now tracked in a
    shared store rather than per process.
  • New-IP login alert email shows the browser. The "sign-in from a new IP"
    notification always rendered an empty Browser row; it now reports the client's
    browser (or "Unknown" for header-less API callers).

Taranac 1.1.1

Choose a tag to compare

@gurkin33 gurkin33 released this 18 Jul 08:19

[1.1.1] — 2026-07-18

Added

  • CEF (ArcSight) syslog format. Audit and AAA events can now be emitted in
    CEF (Common Event Format) for direct ingestion by ArcSight, Sentinel and other
    SIEMs, alongside the existing RFC 3164 / RFC 5424 formats. Events carry the
    canonical rt event-time field so they are timestamped correctly regardless of
    the collector's timezone.

Changed

  • SCP/SFTP sources: remote path moved to the recipe. The file path an SCP or
    SFTP source fetches now lives on a file recipe (a new recipe kind), matching
    how HTTP recipes carry their request — the source describes the connection, the
    recipe describes what to fetch. Existing SCP/SFTP sources are migrated
    automatically on upgrade.

Fixed

  • Just-in-time credentials shared across concurrent collections. Collecting
    from a second device under the same just-in-time credential no longer fails while
    another collection holds it. The minted password is now an account-scoped "warm"
    lease: every collection borrows the same live password and works in parallel, and
    it is rotated once idle (or as soon as a collector-exposed run drains) — never out
    from under an in-flight login.
  • Backups persist across updates. The backups directory is now stored on a
    named volume, so backups survive container recreation and image updates instead
    of being silently lost.

Taranac 1.1.0

Choose a tag to compare

@gurkin33 gurkin33 released this 17 Jul 13:48

[1.1.0] — 2026-07-17

Added

  • Configuration Tracker. Track the running configuration of your network
    devices over time. Point a tracked config at a device (SSH/Telnet, SCP/SFTP
    for binary blobs, or HTTP/HTTPS for API-driven gear), pick a recipe (which
    commands to run + scrub sets that mask secrets and strip volatile lines
    before storage), and Taranac captures a snapshot on a schedule or on demand.
    Every capture is versioned with a per-config version number and content-hash
    dedup, rendered in a side-by-side diff; tag any version pin / baseline /
    golden / approved
    or with your own label. A config-status column surfaces
    drift at a glance, and starter recipes + scrub sets ship for a range of vendors.
  • Collectors. Collection runs through a collector — the unit of deployment
    that owns the devices it can reach. The built-in embedded collector needs no
    setup; for segmented or remote networks, deploy a standalone collector that
    dials out to the core (enroll with a reveal-once token, Ed25519-signed, with
    run-scoped just-in-time credentials and its own outbox) so there's no inbound
    path to secure. Collector health, enrollment, source IP and release/contract
    compatibility are visible in the UI, with two dashboard widgets and TOFU
    SSH host-key pinning.
  • Credentials vault + just-in-time credentials. Device logins are stored
    encrypted and can be minted just-in-time for a single privileged collection run,
    then rotated — the long-lived secret never leaves the vault.
  • References — "where used". Before you delete a group, network object,
    device, profile or credential (and more), Taranac shows where it's
    referenced
    and blocks the delete with an itemised list instead of failing
    opaquely or silently cascading. Deliberate delete-semantics span the Identity,
    Network, AAA, NAC and NCM domains.
  • Bulk onboarding. Turn an address list into tracked configs in one pass, with
    an optional per-batch collector.
  • Config change alerts. Subscribe recipient groups to a tracked config and get
    email on drift, collector-offline or failing collection, with per-config digests.
  • Network Object fqdn type. Address objects — and collection sources — can
    now target a hostname, not just an IP / subnet / range.
  • Update notifications. An opt-in, signed version check surfaces a "new release
    available" status on the dashboard and in Settings — no telemetry, you choose
    when to check.
  • Localized date/time pickers across forms and log filters, with time-of-day
    range filtering on logs; multilingual notification email rendered per the
    configured language.

Changed

  • Reworked the Configuration Tracker list and config-detail pages (inline
    version tagging, resizable split-pane diff, cleaner timeline); Collectors
    moved into Settings.
  • Tracker and collector screens are fully localized (English, German, Spanish,
    French, Portuguese offered; Russian and Ukrainian opt-in).
  • Daemon forensic logs now rotate with a monthly, size-aware archive view.

Fixed

  • Config change-notification email and collect-now report the per-config
    version, not an internal global sequence.
  • Snapshots dedup on content hash; a lapsed just-in-time credential lease
    self-heals; collect-now no longer blanks the page on refresh; percent-encoded
    secrets are masked in collector transport errors.
  • NAC "last seen" comparison fixed for string-typed timestamps.
  • Breadcrumbs restored on nine pages; date/time pickers gained a working clear
    button.
  • Version display no longer drifts. The version shown in the dashboard, API
    and UI (footer / login / error pages) is now baked into the images at build
    time from a single source, so it always matches the deployed release. Previously
    a stale APP_VERSION carried over in an upgraded .env could make the app
    report an old version; that knob is gone — the image tag is the one version.

Taranac 1.0.8

Choose a tag to compare

@gurkin33 gurkin33 released this 06 Jul 18:07

Taranac 1.0.8

  • Secure etcd by default for HAha-convert / ha-join set up peer + one-way client TLS with no extra flags; opt down with --plaintext. Ships a secure-by-default witness template (.env.witness.example).
  • Restore hardening — configuration restore is robust across upgrades (backups taken on older versions restore cleanly); daemon-config regeneration no longer aborts a restore.
  • taranac-mfa backup/restore — standalone tooling for the MFA service database.
  • Quality — full automated gate before publish: 1792 passing (unit → e2e → sustained-rate load under HA failover), 70% backend coverage. See TESTING.md.

Install / upgrade: README.md · INSTALL.md. HA: HA.md.

Bundle: taranac-bundle-1.0.8.tar.gz (or the stable-named taranac-bundle.tar.gz). Verify with SHA256SUMS.

v1.0.7 — HA foundation + full observability + version single-source

Choose a tag to compare

@gurkin33 gurkin33 released this 05 Jul 05:23

Release candidate for 1.0.7 (marked pre-release pending a live 3-host HA validation). Gate 1578 passed / 0 failed; version-baking proven live (baked 1.0.7 overrides a stale env APP_VERSION=1.0.3).

Highlights (cumulative over the 1.0.6-rc line):

  • etcd client-TLS (one-way, opt-in) + unified OOB cluster secret set + shared mfa key → Push decrypts on every node.
  • taranac-mfa write-routing (#26): Push ENROLL now works on any node (libpq multi-host → primary); /readyz probes node-local so a replica serving reads is never evicted during quorum loss.
  • Dashboard per-node observability: Workers show 'leader-only — idle on replica' (#24); Services node×service health matrix with a freshness guard (#25).
  • Per-node alert scoping (#22) + leader-only email:delivery (#23) — no more alert flap.
  • Version single source of truth: bump only deploy/dist/VERSION → baked into every image at build (backend app_version + frontend VITE_APP_VERSION); APP_VERSION dropped as an operator var (no more drift). One operator knob: TARANAC_VERSION.
  • Carried: node attribution (#9), Telegram-any-node (#10), authoritative cluster status (#11/#18), peer-TLS opt-in (#20), edge/boot-migrate update robustness (#19).

Images: ghcr.io/taranaclabs/taranac/*:1.0.7

v1.0.6-rc2 — foundation + full per-node observability

Choose a tag to compare

@gurkin33 gurkin33 released this 04 Jul 17:21

Foundation-complete + dashboard per-node observability. Pre-release; gate 1578 passed / 0 failed.

New in rc2 (on top of 1.0.6-rc1):

  • Workers UI is HA-honest (#24): a leader-only worker viewed on a REPLICA now shows 'Leader-only — idle (runs on the primary)' instead of a misleading 'Active'; per_node workers stay active everywhere; a page-level Primary/Replica badge under HA.
  • Dashboard Services per-node (#25): a node×service health matrix (tacacs/radius/nac up|down|stale|unknown) so you see the daemons are healthy on EVERY node. Mechanism = replicated heartbeat (30s) with a strict freshness guard (row age + Patroni node-down → stale), so a dead node never shows a stale 'healthy'.

Carried from 1.0.6-rc1: etcd client-TLS + unified secret set + shared mfa key; peer-TLS opt-in; per-node alert scoping; node attribution; Telegram-any-node; HA observability. Migration 0012. Images: ghcr.io/taranaclabs/taranac/*:1.0.6-rc2

v1.0.6-rc1 — HA foundation complete

Pre-release

Choose a tag to compare

@gurkin33 gurkin33 released this 04 Jul 08:26

The HA foundation is feature-complete. Pre-release; gate 1567 passed / 0 failed.

New in 1.0.6 (on top of 1.0.5-rc2):

  • etcd client-TLS (one-way, opt-in ETCD_CLIENT_SCHEME=https, default off/http byte-identical): Patroni↔etcd encrypted + server-verified against a shared CA. Provisioned via a new unified OOB 'cluster secret set' (ha-etcd-ca.sh + ha-convert/ha-join --client-tls); CA private key stays on the seed, never distributed. Validated: dcs-spike 25/25, tier2 12/12 over https-client through a SIGKILL crash.
  • Shared mfa enckey (#13): taranac-mfa Push tokens now decrypt on ANY node (provisioned via the same secret set; DMZ-standalone still self-generates, D4-safe).
  • Per-node alert scoping (#22): a healthy peer no longer resolves a sick node's daemon alert (no more flap); email:delivery reconcile is leader-only (#23).

Carried from 1.0.5-rc2: PatroniClient host fix (#18), edge self-heal + boot_migrate resilience (#19), etcd peer-TLS opt-in (#20), node attribution (#9), Telegram-any-node (#10), HA observability (#11).

Docs: ha.md §7.3 (client-TLS + rolling migration), §12 (secret set). Images: ghcr.io/taranaclabs/taranac/*:1.0.6-rc1