Skip to content

Releases: yo1t/egressview

v2.0.1 — the update path, followed on a real machine

Choose a tag to compare

@yo1t yo1t released this 16 Aug 13:48
531b190

EgressView 2.0.1 = Hub 1.10.0 (unchanged) + Agent for Mac 0.3.8.

Everything here is the Mac agent. Most of it comes from following the in-app update path on a real machine for the first time, which broke four times in a row — and every one of those faults had passing tests.

What was wrong with updating

  • Verification could never succeed. The agent shelled out to spctl, which inherits the sandbox and cannot reach syspolicyd. Every check failed with "internal error in Code Signing subsystem", which reads like a problem with the package and was not. Verification is now done in process.
  • The app could not be replaced while running. The drag to Applications failed with "the item is in use", an error that says nothing about what to do. The agent now offers to quit at the moment the installer opens, and says that nothing is recorded until the new copy is running.
  • An update to an older version was offered. A package downloaded earlier stayed on disk after the app was updated some other way, and the menu was only rebuilt when the monitoring status changed — so clearing it did not remove it from the menu.
  • The downloaded application could not be launched at all. This one was not a bug. macOS marks everything a sandboxed application writes and refuses to launch an app taken from it. No amount of verifying the bytes changes that, and stripping the quarantine attribute would be defeating the control rather than satisfying it.

So the agent no longer downloads its own updates. The check is unchanged and the address it offers still comes from a manifest signed with the release key — that signature is what makes the address ours. The bytes are fetched by the browser and checked by macOS at first launch, as for any other download.

Installing still means quitting the agent and replacing it by hand. That is not a finished feature, and it is recorded as unfinished rather than as done. A proper .pkg installer is the decided fix.

Also in the Mac agent

  • Threat rows open a detail pane showing the full address as well as the name, which value was actually on the list — a parent domain, sometimes, rather than the destination itself — what kind of indicator it was, and when it started. It ends by saying what the finding does and does not mean: a feed listing is not proof of harm.
  • Data volume joins the threats table, reading "N or more" where connections are still open, because byte counts arrive when a connection closes.
  • Controls that do nothing on a tab are disabled rather than left looking live.
  • The threat detail pane no longer resizes when a row is selected, which used to move the table under the pointer that had just clicked it.

Upgrading

Nothing to do on the Hub. Agents on 0.3.0 or newer will offer 0.3.8 when they next check.

Full detail in the changelog.

v2.0.0 — the Mac agent becomes something you can look at

Choose a tag to compare

@yo1t yo1t released this 16 Aug 10:52

EgressView 2.0.0 = Hub 1.10.0 + Agent for Mac 0.3.0. The release number belongs to the pack; each component keeps its own. Nothing in the Hub breaks, which is why it is 1.10.0 and not 2.0.0.

The Mac agent stopped being a source of rows and became something you can look at. It draws where this Mac's traffic goes, which application sent it, when, and whether the destination appears on a threat feed — and it does the last one without telling anyone which addresses it asked about.

Threat information, checked on your Mac

Asking a service "is this address dangerous?" tells that service exactly which addresses worry you. So the indicators travel to the Mac and the questions never leave it.

  • Hub-connected agents get the whole indicator set from their Hub over the new GET /api/agent/threat-intel — around 9,500 entries, ~580 KiB, ETag/304.
  • Standalone agents may download the same four public lists themselves, opt-in and off by default. These are plain downloads, not lookup services: no key, and no destination of yours is sent.
  • The choice between the two is never automatic. A Hub-enrolled agent is not offered the setting at all, so an hour of Hub downtime cannot start contacting third parties with nobody having touched anything.

Seeing your traffic

A globe with great-circle arcs leaving this Mac, a flow diagram from application to destination, and a timeline — sharing one period, so "which app caused that spike, and where was it going" is answerable. CSV export of the whole selected period. A connection log that sorts and filters by column, with country, data volume and port.

Saying what it does not know

This release fixes several faults that share one shape: the screen said nothing while something was wrong.

  • The agent reported "Network monitoring active" while recording nothing. Four updates in a row stopped collection silently. Status now means traffic has actually arrived, and the app asks macOS every minute which copy of the extension it is running.
  • The agent now records when it was really watching, shows what share of a period it could not see, and separates time the Mac was asleep — which is not a fault — from time it should have been recording and was not.
  • Connections already open when monitoring starts are never observed. The charts say so rather than presenting a complete picture.
  • An empty threat list is never shown as "nothing found" unless something was actually checked.

Also fixed

  • The connection log ignored the name/address setting and always showed addresses.
  • Export CSV did nothing when pressed — an accessory application has nothing to put a modal panel in front of.
  • The agent used a fifth of a CPU core with its window open; it now loads only what the visible tab shows.

Upgrading

The Hub needs no migration from 1.9.0. The agent's own database migrates on launch (schema 4 → 7), append-only, preserving history. Threat information needs Hub 1.10.0 or newer; against an older Hub the agent says so rather than showing "no threats".

Full detail in the changelog.

EgressView Agent 0.2.1

Choose a tag to compare

@yo1t yo1t released this 14 Aug 10:35
359fefc

Highlights

  • Preserve observations whose local source port is unavailable instead of discarding them.
  • Separate contract-rejection and queue-overflow diagnostics.
  • Register launch at login while monitoring is active unless explicitly disabled.
  • Add the standard macOS About panel for checking the Agent version and build.

The attached DMG is signed with Developer ID, notarized by Apple, and distributed through the signed EgressView update manifest.

EgressView Agent 0.2.0

Choose a tag to compare

@yo1t yo1t released this 14 Aug 08:02
370a6da

EgressView Agent 0.2.0 is the first signed and notarized macOS release.

Highlights:

  • Network monitoring through the approved Network Extension
  • Local SwiftUI history, overview, and settings
  • Opt-in delivery to an EgressView Hub with offline queueing
  • Signed automatic-update checks through dl.egressview.com
  • Japanese and English UI

SHA-256 (egressview-agent-0.2.0.dmg):
ceeec65f2efe3ab1ccfe45d1f66f6516b47005a63044c37d6fc06e752619df05

The DMG is notarized by Apple and accepted by Gatekeeper.

v1.9.0 — endpoint visibility on macOS

Choose a tag to compare

@yo1t yo1t released this 12 Aug 22:09
e2efa41

A router shows what left the house but not which application sent it. This release closes that gap.

macOS Agent

egressview-agent-0.1.16.dmg is attached, notarised by Apple. It reports the process behind each outbound connection from a Mac, so a destination you do not recognise arrives with the name of the program that reached for it. Metadata only — never payloads, and it blocks nothing.

A machine becomes an agent only when an administrator approves it: it applies with a six-character code, and the host name in that application is claimed by the client, which the approval screen says plainly. Flows an agent reports are checked against the threat feeds, enriched, and recorded in the Detection Log exactly like flows a router saw.

It requires this release or newer. 1.8.0 has no agent endpoint at all. Install steps are in the agent guide.

An agent covers one Mac, not your network — the router is still what shows you the devices nobody can install software on.

The Detection Log no longer freezes the interface

Selecting a Mac in the Detection Log ran a correlated query with no supporting index. SQLite is synchronous, so that one request held the event loop: the site returned 504s and collection stopped until the process was restarted. The same query now takes about 1.1 seconds instead of over 30, and a watchdog restarts the process if anything else ever holds the loop for two minutes.

Upgrading

This upgrade runs database migrations (schema 12 → 16), unlike 1.8.0. They are append-only and fail-closed: free space is checked, a verified backup is taken, and the resulting database is validated before startup continues. Existing history is preserved. A restart is all that is required.

Full detail in the changelog.

Verifying this release

The archive is signed with the AWS KMS release key egressview-release-2026, whose private half cannot be exported. Verification needs neither an AWS account nor network accessopenssl and the published public key are enough:

sha256  626fe1bf0808489d043f2e32e060de7e9de0b9b4fdcfbfdb0643d85a6b62d992
key fp  SHA256:6288265bd746d230a3637e3a520e2335f48dc939a4d76d7b05c44ea5baf3eccc

Compare that fingerprint against release-signing/trusted-fingerprints.json before trusting the archive. Procedure: release signing.

v1.8.0 — first signed release

Choose a tag to compare

@yo1t yo1t released this 06 Aug 13:43
2763595

EgressView v1.8.0 is the first signed release.

Signed distribution

The portable distribution is signed with an AWS KMS Ed25519 key whose private half cannot be exported. Verification needs nothing but openssl and the published public key — no AWS account, no network access, no additional tooling.

Signing key fingerprint (egressview-release-2026, active):

SHA256:6288265bd746d230a3637e3a520e2335f48dc939a4d76d7b05c44ea5baf3eccc

The same fingerprint is published in SECURITY.md, both project site pages, both distribution guides, and a DNS TXT record. Compare against at least two before trusting an artifact.

Verify a download:

V=1.8.0
A=egressview-offline-$V.tar.gz
shasum -a 256 -c "$A.sha256"
openssl pkeyutl -verify -rawin -pubin -inkey "$A.pub.pem" -sigfile "$A.sig" -in "$A.sha256"

The signature covers the checksum file, and the checksum file covers the archive.

Highlights

  • Per-detection notification switches. Threat detection and new-node detection each gained independent Slack and history toggles. Previously both were raised unconditionally, the Slack send was gated only by the global Slack toggle, and the history callback sat outside that gate — so quietening new-node alerts meant turning Slack off for everything, and the in-app history could not be silenced at all.
  • AWS KMS release signing. npm run offline:bundle -- --kms-key-id … signs a build. The verifier is unchanged from previous releases.
  • better-sqlite3 13.0.3, SQLite 3.53.4. Lifts the pin placed in 1.7.0.
  • Install scripts disabled. Dependencies no longer run code at install time, and native modules come from bundled prebuilt binaries instead of compiling. See the upgrade note below.
  • Parser fuzzing and Node 26 in CI. A seeded fuzzing suite covers the 19 functions that parse router CLI output, syslog, and conntrack tables; CI runs unit tests on Node 22, 24, and 26.

Upgrading from 1.7.0

No schema change and no migration — a restart is enough.

One install-time change matters: because install scripts are now disabled, a platform without a bundled prebuilt binary for better-sqlite3 needs Python, a C++ toolchain, and npm ci --ignore-scripts=false. Prebuilds cover darwin, linux, linuxmusl, and win32 on arm64 and x64, which is every supported deployment target.

Full changelog: https://github.com/yo1t/egressview/blob/v1.8.0/CHANGELOG.md
Verification guide: https://github.com/yo1t/egressview/blob/v1.8.0/docs/offline-distribution.md

v1.7.0

Choose a tag to compare

@yo1t yo1t released this 02 Aug 11:06
da6679d

v1.7.0 shifts the remote MCP work from building the security model to operating it,
and completes the offline/portable deployment track.

  • Offline mode (EGRESSVIEW_OFFLINE_MODE) decides and disables internet-dependent
    features before startup; cloud SDK clients are never constructed
  • D3 / TopoJSON / world-atlas self-hosted at pinned versions; CSP admits no external origin
  • Public MCP: OAuth 2.1 resource server, scoped service identities, rate limits,
    concurrency cap, and an append-only pseudonymized audit trail with a keyed client hash
  • Portable source distribution with CycloneDX SBOM and offline portability gates
  • Schema stays at v12 — no migration required

Breaking: HTTP token mode now requires a dedicated MCP_TOKEN and no longer falls
back to EGRESSVIEW_TOKEN. Private HTTP MCP users must set it before upgrading.


Release signing status

This release is not signed by a project key. release-signing/trusted-fingerprints.json
contains no enrolled key, so per docs/release-signing.md this
release must not be described as signed by the project key. No artifact here carries a
signature. Signing method selection is tracked separately.


Added

  • Added EGRESSVIEW_OFFLINE_MODE for air-gapped and egress-filtered
    deployments. Internet-dependent features are decided and disabled before
    startup rather than attempted and timed out: RDAP, GeoIP, threat feeds, the
    OUI vendor database, manual threat lookup, Google OIDC, and the
    Anthropic/OpenAI/Bedrock providers. Cloud provider SDK clients are never
    constructed, so no credential resolution or connection setup occurs. Router
    SSH collection, SQLite, the web UI, and stdio/private HTTP MCP are
    unaffected. Internal DNS/PTR and a self-hosted Ollama endpoint stay disabled
    until explicitly configured with a loopback or private IP address.
    The API and settings report which features are off and why.
  • Self-hosted D3 7.9.0, TopoJSON client 3.1.0, and world-atlas 2.0.2 at pinned
    versions and removed every external origin from the CSP and HTML. The map and
    graph now render with no CDN request, which also removes a third-party
    dependency from every ordinary page load.
  • Added a mandatory offline portability gate for Linux hosts and a generic
    Debian container. It denies and audits external DNS/socket attempts while
    exercising Web startup/restart, Cisco and conntrack fixtures, SQLite
    backup/restore, stdio MCP, authenticated private HTTP MCP, and MCP audit.
  • Added a signed portable source distribution with a CycloneDX SBOM, exact
    dependency lock, per-file manifest, SHA-256 checksum, Ed25519 signature,
    credential/runtime-data exclusion gate, and atomic install/upgrade/rollback.
    Install and upgrade may use the npm registry; runtime remains offline.
  • Added a staged OAuth Resource Server mode for remote MCP testing:
    RFC 9728 metadata and challenges, authorization-server discovery, RS256
    JWKS validation, exact issuer/audience/expiry/scope checks, bounded caches,
    unknown-key refresh, and fail-closed provider errors.
  • Added a fail-closed pre-publication gate for staged MCP deployments. It
    verifies unpublished DNS, TLS and OAuth metadata, invalid/expired/audience
    rejection, read/write scope separation, rate limiting, audit correlation,
    and continuing local router collection. It never publishes DNS or changes
    infrastructure; a pass only permits a separate manual DNS review.
  • Added a cloud-neutral deployment-profile contract for local stdio, private
    HTTP, private OAuth, and public OAuth. Conflicting transport/auth settings now
    fail before MCP startup, with English/Japanese threat, TLS, identity, and
    outbound-dependency matrices documenting the staged air-gapped path.

Security and Reliability

  • Public MCP audit rows now carry a keyed hash of the client address. It is the
    only identifier available when a request fails before authentication, where
    subject and client id are necessarily null, so a flood from one source can
    finally be told apart from ordinary retries. The raw address is never stored,
    and MCP_TRUST_PROXY names the proxies allowed to set it — otherwise the
    socket address is used, so a caller cannot forge X-Forwarded-For to poison
    the trail. Existing audit databases gain the column in place; historical rows
    stay null rather than being backfilled with a guess.
  • HTTP token mode now requires a dedicated MCP_TOKEN and no longer falls
    back to the full-access EGRESSVIEW_TOKEN. Existing private HTTP users must
    set a separate endpoint token before upgrading; stdio mode is unchanged.
  • OAuth provider scopes now map to the shared network.read and notes.write
    permissions. Read-only tokens cannot discover or call set_device_note, and
    insufficient write scope returns a step-up-compatible 403 challenge.
  • OAuth MCP API calls now require a dedicated, expiring egv_... service
    identity with only network.read and notes.write; the browser/admin token
    is rejected and never used as a fallback.
  • Public OAuth MCP now applies global, per-subject, and per-client rate limits,
    a concurrency cap, bounded request bodies and deadlines, and a dedicated
    append-only HMAC-pseudonymized audit trail.
  • Migrated the MCP server to the stable SDK v2 package split. One server
    factory now supports both the legacy 2025-11-25 initialize flow and the
    stateless 2026-07-28 discover flow with the same 11 tools.
  • Extended the DNS-unpublished publication gate with dual-era discovery,
    identical tool-inventory checks, standard modern protocol-error probes, and
    versioned real-client evidence. Server-side probes still require both
    protocol revisions; client releases may use either supported revision.
    Cognito evidence can record Copilot's random-loopback callback limitation
    without claiming that client is compatible.
  • Made refresh replay evidence provider-neutral: the gate accepts either
    immediate replay rejection with family continuity or replay-triggered family
    revocation, while requiring access tokens to expire within 15 minutes.
  • Hardened private HTTP MCP with the same fail-closed audit, rate/concurrency
    limits, bounded bodies, deadlines, and scoped service identity used by OAuth.
    HTTP remains loopback-only by default; non-loopback bind requires an explicit
    deployment profile and a separate approval setting.
  • Added least-privilege browser roles. Local login remains admin, an explicitly
    allowed Google email becomes operator, and a domain-only match becomes
    read-only viewer. Authentication allowlists no longer imply administrator
    access.
  • Existing local sessions remain administrators during migration. Existing
    OIDC and unknown sessions are revoked once and must reauthenticate so their
    role is derived from a newly verified allowlist match.
  • Kept provider-billed AI execution admin-only. Operators may update device
    notes but cannot run AI, change settings or credentials, restore backups, or
    manage authentication.

EgressView v1.6.0

Choose a tag to compare

@yo1t yo1t released this 26 Jul 02:33
7a00b1f

Security and Reliability

  • Google OIDC domain allowlists now warn that every matching user becomes a full administrator. EgressView authenticates users but does not separate permissions yet, so any account passing the allowlist can read all captured traffic, change router credentials, rotate secrets, and restore backups. A domain allowlist extends that to everyone in the domain, including accounts created after it was configured. The warning appears in the server log at startup, in Settings while any domain is present — saved or still being typed — and again in a confirmation prompt when an enabled configuration with a domain allowlist is saved. Existing configurations keep working unchanged; EgressView never disables an allowlist for you, because silently locking out remote users would be worse than the risk being reported. Prefer an explicit email allowlist until role-based access control ships.
  • Settings now describes the local administrator accurately for the configuration in use: the ordinary sign-in path while Google OIDC is disabled, and the emergency fallback that survives an IdP outage once OIDC is enabled. The account itself is unchanged and remains always available. Wording switches on the saved OIDC setting alone — EgressView does not infer whether it is reachable from the internet, because a port forward or unknown reverse proxy would defeat that guess.
  • Completed strict Zod request validation across all 13 endpoint-bearing route modules, rejecting unknown fields, wrong-typed scalars, and oversized values while preserving existing SSRF checks, defaults, limits, and error shapes.
  • Made every device-note write path fail closed, restoring the previous runtime snapshot and suppressing success notifications on failure.
  • Backup cleanup always protects at least two normal generations and the latest migration generation, never removes corrupt or unverified files, and reverifies the plan immediately before deletion.
  • Restored saved ASUS polling automatically after service restarts and coalesced overlapping polls.
  • Moved verified backup cleanup to a single-concurrency worker job with progress, cancellation, and timeout so multi-gigabyte integrity checks no longer block collection or HTTP.

Added

  • Unauthenticated, minimal /healthz liveness and /readyz bootstrap-readiness endpoints for monitoring and deployment gates.
  • Request correlation on every HTTP response through X-Request-Id, with safe caller-provided IDs, UUID fallbacks, and correlated slow/error logs.
  • Unified inventory and capacity diagnostics for normal and pre-migration SQLite backups, plus dry-run and confirmed cleanup with configurable storage limits.
  • AI list prices moved into a validated, versioned catalog with effective dates and source URLs; added GPT-5.5 pricing, broader OpenAI coverage, and explicit partial-total labels.
  • Production Bedrock guidance for least-privilege IAM, invocation logging, PrivateLink, and SDK retry strategy.

Documentation

  • Documented the domain allowlist risk and the migration path to an explicit email allowlist in both authentication guides, both READMEs, and the project site.

Verification

  • 1,539 unit tests passed.
  • 69 browser smoke tests passed.
  • Node 22/24, ASH security scan, release safety checks, build, npm audit, and secret scan passed.
  • Deployed to EC2 production with the staged rollout, readiness gate, and automatic rollback: schema 9, integrity OK, 285,150 connections preserved, /healthz and /readyz returning 200, Yamaha and Cisco collection active, 0 ERROR and 0 FATAL after start.

EgressView v1.5.1

Choose a tag to compare

@yo1t yo1t released this 19 Jul 15:30
22081b8

Fixed

  • Restored the connected-device list across AI Insights and all other tabs.
  • Populated the shared device panel from bounded summary data without waiting for hidden graph rendering or the initial Socket.IO snapshot.
  • Added desktop, mobile, socket-unavailable, and deployed subpath regression coverage.

Documentation

  • Added separate English and Japanese AI Insights screenshots with IP and MAC addresses redacted.
  • Promoted the language-specific images to the first README and GitHub Pages screenshot and social preview.
  • Refreshed the English and Japanese quality reports.

Verification

  • 1,406 unit tests passed.
  • 63 browser smoke tests passed; 1 conditional test skipped.
  • Node 22/24, ASH, release safety, Pages build, npm audit, secret scan, and package dry-run passed.
  • Desktop and mobile checks passed against the EC2 production /egressview path with live Yamaha and Cisco data.

EgressView v1.5.0

Choose a tag to compare

@yo1t yo1t released this 19 Jul 13:58
dc05987

Highlights

EgressView v1.5.0 makes AI Insights the leftmost start page. Live network posture remains local, while analysis and chat run only when explicitly requested through Ollama, Anthropic, OpenAI, or Amazon Bedrock.

  • Live collection health, connections, devices, destinations, threats, and previous-period comparisons
  • Bounded manual analysis and chat with append-only conversation history
  • Monthly input/output token totals and estimated USD cost, plus provider/model/token/cost metadata per answer
  • Bedrock foundation-model, inference-profile, region, and Guardrail discovery through the AWS SDK default credential chain
  • Bounded five-minute live graph detail, longer enrichment cache lifetimes, stale-work throttling, batched poll persistence, and runtime CPU diagnostics

Monthly AI usage is shown at the bottom of the Insights page so current posture, analysis, and chat remain the primary workflow.

Privacy and pricing

Cloud AI providers remain explicit opt-in and require consent both in saved settings and for each request. Credentials and router-management details are excluded from AI context. Cost values are estimates based on the embedded pricing version; unknown models remain explicitly unpriced, and add-on charges such as Bedrock Guardrails are not included.

Upgrade notes

Existing databases migrate automatically from schema v6 to v7. Startup creates and verifies a full pre-migration backup before changing the database, and stops safely if free-space, WAL checkpoint, copy, or integrity verification fails.

Allow at least approximately twice the current database file size in free disk space before the first v1.5.0 startup. Existing v1-v6 migrations remain available.

Amazon Bedrock may require one-time foundation-model access or an AWS Marketplace subscription for the selected model. See the English and Japanese Bedrock setup guides for IAM and credential-chain examples.

Verification

  • 1,406 unit tests passed on Node.js 22 and 24
  • 60 Playwright browser smoke tests passed; 1 environment-dependent test skipped
  • Coverage: 77.85% lines, 79.20% branches, 73.94% functions
  • ASH, npm audit, secret scan, release safety, package dry-run, and GitHub Pages build passed

Full Changelog: v1.4.0...v1.5.0