egressview

EgressView REST API Reference

Japanese / 日本語

EgressView exposes a private administration API for its web UI and local automation. The API is not yet a versioned public compatibility contract; review release notes before upgrading an external integration.

Base URL and authentication

API paths are rooted at /api, even when the web UI is served below a subpath. Protected requests accept the legacy X-Admin-Token, a scoped API identity token in the same header, or an HttpOnly browser session cookie. Cookie-authenticated mutations also require the matching X-CSRF-Token.

Scoped API identities are managed through GET / POST /api/auth/api-identities and POST /api/auth/api-identities/:id/revoke, all requiring auth.admin. Creation requires a label, a non-empty permission list, and expiresInMs between one minute and one year. The plaintext egv_... token is returned only in the 201 creation response; only its SHA-256 hash is stored. Identity-management responses use Cache-Control: no-store.

Mac and future endpoint Agents use a separate credential boundary. Enrolment takes three steps and no single one of them produces a credential. An administrator creates a six-character, 10-minute code with POST /api/agents/enrollment-tokens. The Agent applies with it at POST /api/agent/enrollment-requests, which returns a claim secret and a pending request — not a token. An administrator then approves it with POST /api/agents/enrollment-requests/:requestId/approve, after which the Agent collects its egva_... bearer exactly once from POST /api/agent/enrollment-requests/claim. A code is burned after five failed attempts, and pending requests expire in ten minutes. The bearer is stored in the macOS Keychain, while the Hub stores only a peppered hash. It grants only agent.ingest, cannot authenticate browser/admin/MCP routes, and is accepted by token rotation, ingest, and POST /api/agent/registration/revoke. The last route revokes only the identity authenticated by that bearer; it cannot target another Agent. Ingest accepts at most 200 observations in 512 KiB of uncompressed JSON, stores one batch transactionally, and returns the original ACK for retries of the same Agent/batch ID. Each Agent is limited to 30 requests/minute and the Hub to four concurrent ingest operations. Agent inventory, aggregate ingest metrics, and administrator-initiated revocation require auth.admin. All Agent responses are non-cacheable, enrollment codes are shown once, and HTTP is accepted only on a loopback development listener.

GET /api/auth/api-identities/self returns only the currently authenticated scoped identity and requires network.read; browser sessions and the legacy admin token are rejected. The remote MCP server uses it to fail closed unless its internal service identity grants exactly network.read and notes.write.

export EGRESSVIEW_URL='https://egressview.example.net'
export EGRESSVIEW_TOKEN='replace-with-your-admin-token'

curl --fail-with-body \
  -H "X-Admin-Token: $EGRESSVIEW_TOKEN" \
  "$EGRESSVIEW_URL/api/status"

Use HTTPS or a trusted VPN when crossing a network boundary. Never put a token in a URL, log, or source file. The JSON request-body limit is 64 KB.

Password login

POST /api/auth/login is public and exchanges the UI password for a revocable session token. A password may contain at most 256 characters. Five failed attempts from one client trigger a five-minute lockout within the ten-minute tracking window.

curl --fail-with-body \
  -H 'Content-Type: application/json' \
  -d '{"password":"replace-with-your-password"}' \
  "$EGRESSVIEW_URL/api/auth/login"
{"success":true,"token":"session-token","expiresAt":1784304000000}

POST /api/admin/verify is also public and verifies a token supplied in the request body. Authentication status/method discovery, the OIDC redirect/callback, and the code-protected POST /api/agent/enrollment-requests and .../claim entry points are public. The detail-free /healthz and /readyz checks are public; all other endpoints require their documented browser, API identity, or Agent credential.

Common behavior

Connections

List connection history

GET /api/connections

Query Description
from, to Optional epoch-millisecond range.
limit, offset Pagination. limit is clamped to 1,000. The unpaged compatibility form is capped at 50,000 rows and returns truncated; the graph uses /api/connections/summary.
sort lastSeen, src, dst, dport, proto, country, or org; default lastSeen.
sortDir asc or desc; default desc.
fSrc, fDst, fDport, fProto, fCountry, fOrg Server-side column filters. Append Mode with contains, startsWith, endsWith, or exact.
fSrcMac Exact source-MAC filter.
fThreat safe, warn, or danger.
curl --fail-with-body \
  -H "X-Admin-Token: $EGRESSVIEW_TOKEN" \
  "$EGRESSVIEW_URL/api/connections?from=1784217600000&limit=100&sort=lastSeen&sortDir=desc"

The response contains connections, total, limit, offset, and serverTime. Each connection can include source-device metadata, destination enrichment, firstSeen, lastSeen, observedBy router IDs, a compatibility source value derived from those routers, and an optional threat object.

Summary and security views

Export CSV or JSON

GET /api/connections/export requires format=csv|json and from; to defaults to the current time.

curl --fail-with-body \
  -H "X-Admin-Token: $EGRESSVIEW_TOKEN" \
  "$EGRESSVIEW_URL/api/connections/export?format=csv&from=1784217600000" \
  -o connections.csv

Exports stream in pages of 1,000, stop at 50,000 rows, and time out after 60 seconds. Inspect X-Export-Total, X-Export-Count, and X-Export-Truncated. CSV is UTF-8 with a BOM and applies spreadsheet-formula injection protection. JSON returns meta and connections.

Routers

EgressView supports up to 10 enabled or disabled Yamaha/Cisco records.

Create/detect bodies use kind (yamaha or cisco), displayName, ip, user, pass, and enabled. Yamaha also uses nat; Cisco may use enablePass. Omitting a password during update preserves the stored value.

Devices and notes

Backup and restore

Process health

AI provider configuration

AI insights always shows locally calculated facts. Only after an explicit user action, it sends aggregates — including destination IPs, hostnames, device names, and MAC addresses — to the configured AI provider. Credentials such as passwords are never sent.

Provider configuration is disabled by default. Anthropic and OpenAI use their fixed official API endpoints; only Ollama accepts a custom HTTP(S) endpoint. Bedrock uses a region and the Converse API, delegating authentication to the AWS SDK default credential chain (no key entry or storage). Bedrock support ships as a standard dependency (@aws-sdk/client-bedrock-runtime and @aws-sdk/client-bedrock); no extra install. See docs/setup-bedrock.md.

Restore is fail-closed: EgressView validates the source, confirms a safety backup, restores and reopens all database users, verifies the result, and rolls back on failure. Active browser sessions are revoked after a successful restore.

Endpoint catalog

All 101 implemented HTTP endpoints are listed below. Public means no browser or API token is required. Protected endpoints accept the documented legacy/scoped X-Admin-Token, browser HttpOnly session cookie, or Agent bearer; cookie-authenticated mutations additionally require X-CSRF-Token.

Area Method and path Access
Authentication POST /api/auth/login Public
Authentication POST /api/admin/verify Public
Authentication GET /api/auth/status Public
Authentication GET /api/auth/methods Public
Authentication GET /api/auth/oidc/start Public
Authentication GET /api/auth/oidc/callback Public
Authentication POST /api/auth/logout Protected
Authentication GET /api/auth/sessions Protected
Authentication POST /api/auth/sessions/:id/revoke Protected
Authentication POST /api/auth/sessions/revoke-all Protected
Authentication POST /api/auth/change-password Protected
Authentication POST /api/admin/regenerate-token Protected
Authentication GET /api/auth/security-config Protected
Authentication POST /api/auth/security-config Protected
Authentication POST /api/auth/oidc/test Protected
Authentication GET /api/auth/api-identities Protected
Authentication POST /api/auth/api-identities Protected
Authentication POST /api/auth/api-identities/:id/revoke Protected
Authentication GET /api/auth/audit-events Protected
Agent POST /api/agents/enrollment-tokens Protected; auth.admin, returns the code once
Agent POST /api/agent/enrollment-requests Public; applies with a six-character code. Returns no token
Agent POST /api/agent/enrollment-requests/claim Public; collects the token once, after approval
Agent GET /api/agents/transport auth.admin; reports whether agent traffic is encrypted and what plaintext would expose
Agent POST /api/agents/transport auth.admin; records the operator’s acceptance of unencrypted agent traffic
Agent GET /api/agents/enrollment-requests auth.admin; pending requests awaiting a decision
Agent POST /api/agents/enrollment-requests/:requestId/approve auth.admin; approves and mints the token
Agent POST /api/agents/enrollment-requests/:requestId/reject auth.admin; rejects the request
Agent GET /api/agents Protected; auth.admin, never returns credential hashes
Agent GET /api/agents/ingest-metrics Protected; auth.admin, aggregate counters and limits only
Agent POST /api/agents/:agentId/revoke Protected; auth.admin
Agent POST /api/agent/token/rotate Agent bearer; agent.ingest only
Agent POST /api/agent/registration/revoke Agent bearer; revokes only the authenticated Agent
Agent POST /api/agent/ingest Agent bearer; agent.ingest, max 200 observations and 512 KiB uncompressed JSON
Agent GET /api/agent/capabilities Agent bearer; accepted schema versions and batch limits, so an agent can pick a version both sides speak
Agent GET /api/agent/geo-cache Agent bearer; the whole location cache, so an agent can place its own destinations on a map without telling the Hub which ones it cares about. ETag/304 supported
Agent GET /api/agent/threat-intel Agent bearer; every threat indicator, so an agent can match its own destinations locally without telling anyone which ones it is asking about. available: false when the Hub runs without feeds, which an agent must not read as “no threats found”. ETag/304 supported
Router setup POST /api/nonce Protected
Router setup POST /api/yamaha/detect Protected
Router setup POST /api/cisco/detect Protected
Router setup POST /api/login Protected, legacy setup flow
Routers GET /api/routers Protected
Routers POST /api/routers/detect Protected
Routers POST /api/routers Protected
Routers PUT /api/routers/:id Protected
Routers DELETE /api/routers/:id Protected
Connections GET /api/connections Protected
Connections GET /api/connections/memory Protected
Connections GET /api/connections/summary Protected
Connections GET /api/connections/new-nodes Protected
Connections GET /api/connections/threat-connections Protected
Connections GET /api/connections/threat-counts Protected
Connections GET /api/connections/export Protected
Devices GET /api/devices Protected
Devices GET /api/devices/merge-candidates Protected
Devices POST /api/devices/merge Protected
Devices POST /api/devices/reject Protected
Devices POST /api/devices/archive Protected
Devices POST /api/devices/unarchive Protected
Notes GET /api/notes Protected
Notes POST /api/notes Protected
Notes POST /api/notes/draft Protected
Backup GET /api/backup/list Protected
Backup POST /api/backup/create Protected
Backup GET /api/backup/download/:name Protected
Backup POST /api/backup/restore Protected
Backup POST /api/backup/upload Protected
Backup POST /api/backup/config Protected
Backup POST /api/backup/prune Protected
Backup GET /api/backup/prune/:jobId Protected
Backup DELETE /api/backup/prune/:jobId Protected
Process health GET /healthz Public; minimal liveness only
Process health GET /readyz Public; minimal readiness only
General configuration GET /api/status Protected
General configuration POST /api/config/general Protected
Data sources GET /api/config/datasources Protected
Data sources POST /api/config/datasources Protected
Slack GET /api/config/slack Protected
Slack POST /api/config/slack Protected
Notifications GET /api/config/detection-notifications Protected
Notifications POST /api/config/detection-notifications Protected
Manual threat investigation GET /api/config/manual-threat Protected; returns key-set flags, never key values
Manual threat investigation POST /api/config/manual-threat Protected; saves API keys, cache, and provider cooldown
Manual threat investigation POST /api/threat/manual-lookup Protected; explicitly sends one public IP to selected providers
AI configuration GET /api/config/ai Protected; returns key-set flags, never key values
AI configuration POST /api/config/ai Protected; saves provider, models, endpoint, and cloud keys
AI configuration POST /api/ai/models Protected; discovers Bedrock model/profile IDs without inference
AI configuration POST /api/ai/pricing/check Protected; checks embedded pricing coverage without provider access
AI configuration POST /api/ai/guardrails Protected; discovers Bedrock guardrails without inference (fail-open)
AI configuration POST /api/ai/test Protected; retrieves model IDs without sending network data
AI insights GET /api/ai/facts Protected; local facts and prior-period comparison only
AI insights GET /api/ai/usage/monthly Protected; current and previous local-month token usage and approximate USD cost
AI insights GET /api/ai/pricing/diagnostics Protected; selected-model status and grouped unpriced usage
AI insights POST /api/ai/analyze Protected; manually analyzes aggregates (incl. destination IPs, hostnames, device names, MAC); cloud requires double consent
AI notifications GET /api/ai/notification-config Protected; returns schedule, trigger, destination, and runtime status
AI notifications POST /api/ai/notification-config Protected; saves validated scheduling and automation consent settings
AI notifications GET /api/ai/notification-events Protected; returns up to 200 append-only delivery records
AI notifications POST /api/ai/notification-test Protected; tests UI/Slack delivery without invoking AI
AI notifications POST /api/ai/notification-run-now Protected; explicitly runs the configured analysis range
AI chat POST /api/ai/chat Protected; appends the question first and stores an answer or failure row
AI chat GET /api/ai/conversations Protected; conversation list and storage usage
AI chat GET /api/ai/conversations/:id Protected; message history preserved across restarts
AI chat DELETE /api/ai/conversations/:id Protected; explicit conversation-level deletion
Slack POST /api/slack/test Protected
Slack POST /api/slack/verify Protected
Slack POST /api/slack/lookup-user Protected
Detection log GET /api/notification-log Protected
Beacons GET /api/beacons Protected
Beacons GET /api/beacons/config Protected
Beacons POST /api/beacons/config Protected
Beacons POST /api/beacons/:id/dismiss Protected