v1.7.0
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_MODEfor 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,
andMCP_TRUST_PROXYnames the proxies allowed to set it — otherwise the
socket address is used, so a caller cannot forgeX-Forwarded-Forto 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_TOKENand no longer falls
back to the full-accessEGRESSVIEW_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.readandnotes.write
permissions. Read-only tokens cannot discover or callset_device_note, and
insufficient write scope returns a step-up-compatible403challenge. - OAuth MCP API calls now require a dedicated, expiring
egv_...service
identity with onlynetwork.readandnotes.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 legacy2025-11-25initialize flow and the
stateless2026-07-28discover 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 becomesoperator, and a domain-only match becomes
read-onlyviewer. 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.