Skip to main content

Exploring Endpoints

Clicking a listener on the dashboards home opens its endpoints view — the working surface of API Discovery. This is where you browse the actual operations the listener serves, filter them down, read their two-axis risk, and drill into any one of them.

An operation is a unique (method, host, normalized_path) — the OpenAPI notion of an operation. Each is one api_inventory document.

Source toggle: Confirmed vs Attack surface​

The Catalog toggle switches the data source between the two halves of the confirmed-vs-attack-surface split:

  • Confirmed — the real API catalog: operations that matched a real Envoy route. This is the clean inventory you export and build policies from.
  • Attack surface — probe / scanner noise that matched no route (/.env, /cgi-bin probes, SPA-fallback 200s). Deliberately kept separate so it never pollutes the real catalog. Current-risk overlay is not computed here — risk on probe noise is meaningless.

At a glance — how each observed request lands in one half or the other:

Layout toggle: Flat vs Group by path​

For the confirmed catalog, the View toggle changes how operations are laid out:

  • Flat — one row per operation (GET /users/{id} and POST /users/{id} are separate rows). Best for a precise, per-operation audit.
  • Group by path — a path rollup: one row per normalized path, with all its methods folded in and per-path aggregates (operation_count, total_seen, worst threat/exposure). Expand a row to see the per-operation breakdown (method, protocol, calls, auth posture, threat/exposure, last seen, deep-link). Best for a high-level surface review and for selecting whole paths to suggest a Shield policy. Grouping applies to the confirmed source only.

Maturity gate​

Route-aware confirmation promotes an endpoint to confirmed on a single matching request — so a one-off scanner hit against a real route can slip into the clean catalog. The Maturity toggle closes that gap:

  • All — every confirmed operation.
  • Mature ≥5 — hides operations seen fewer than 5 times (min_seen=5), dropping one-off noise. Confirmed views only.

Use Mature for the high-confidence catalog; use All when you want to see everything, including brand-new endpoints that haven't accumulated traffic yet.

Filters​

The collapsible Filters panel narrows the list. Filters live in the URL (shareable, restored by back/forward) and apply on Apply:

FilterNotes
MethodMulti-select: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, CONNECT, TRACE.
ProtocolMulti-select: http/1.0, http/1.1, http/2, http/3, tcp, grpc.
Risk FlagMulti-select over the full risk-flag catalog.
PII CategoryMulti-select: email, phone, ssn, credit_card, iban.
Endpoint CategoryMulti-select: admin / auth / account / payment / data-export / api-docs / metadata-leak.
HostPrefix match on the Host header (Mongo ^value regex, case-sensitive).
Path prefixPrefix match on the normalized templated path (e.g. /api/v1/).
Risk score rangeDual slider, 0–255, over max_risk_score (the Threat axis).
Last seenDate range, with Today / Last 7 days / Last 30 days presets.

Geo & raw cross-filters (ClickHouse-backed)​

Four more filters pivot the catalog by where traffic came from. They resolve endpoints that served matching traffic within a time window (default last 7 days) and require ClickHouse:

FilterNotes
CountryISO-3166 α-2 (e.g. TR, US, DE).
ASNAutonomous System Number of the source network (e.g. 12735).
Source IPExact IPv4/IPv6 — the Envoy downstream IP, not X-Forwarded-For. Only matches when the collector keeps raw source IPs (StoreRawSourceIP=true); otherwise returns nothing.
User-AgentExact UA string. Only matches when the collector keeps raw UAs (StoreRawUserAgent=true).
Status range is per-event, not per-endpoint

There is no status-code filter in the inventory list — inventory rows store status_dist as an aggregate object, not a per-request status. Filter by status inside an endpoint's Events tab instead.

Columns​

The flat table shows, per operation:

ColumnMeaning
Method / Path / HostThe operation identity. Path links to the detail page.
Callsseen_count — total requests observed since first_seen (a running counter, not windowed).
Errors5xx sum ÷ calls. Coloured ≥1% red, ≥0.1% amber.
Latency MaxSlowest single request (latency_max_ms), rendered in seconds when ≥1s.
ThreatThe threat-axis flags + max_risk_score badge — active attack/abuse. Shows the current (last-7d) max when ClickHouse is available; a moon = dormant (hover for lifetime max), a green ↓ = improved below the all-time peak.
ExposureThe posture-axis flags + max_posture_score badge — standing config hygiene.
Last SeenRelative time, with a freshness dot (green if within the hour).

The two axes are the heart of the model — see Risk Scoring. A Scoring guide popover on the toolbar summarizes the threat-vs-exposure matrix (Clean / boring-but-open / solid-but-under-attack / open-&-under-attack). Sorting is always on the lifetime score even when the badge shows current.

Header actions on this view: Export OpenAPI (YAML/JSON — see OpenAPI Export) and, when path-groups are selected, Suggest Shield Policy (see Suggest Policy).

Endpoint detail​

Every path links to a deep-linkable detail page with four tabs.

Overview​

MongoDB-sourced aggregates for the operation:

  • KPIs — Total Calls, Max Latency, Threat / Exposure (the two lifetime max scores, T and E), Auth Posture, and response-size KPIs (Total Egress, Largest Response, derived Avg Response — the oversized_response canary lives here).
  • Current-vs-ever posture card — "is this endpoint STILL bad?" — the windowed current posture next to the monotonic lifetime KPIs, so a remediated endpoint reads as improved rather than stuck at its all-time worst.
  • Latency distribution — fixed buckets: <5ms, 5–25ms, 25–100ms, 100–500ms, 500ms–2s, ≥2s.
  • Status distribution — a donut over status classes (2xx/3xx/4xx/5xx/1xx).
  • Categorisation — the observed metadata: threat flags, exposure flags, PII categories, endpoint categories, auth schemes (with an Anonymously reachable warning when none + noauth_observed), Envoy clusters, routes, content-types, and caller Origins.
  • How to fix this endpoint — a consolidated remediation action plan grouping the endpoint's flags by the single Envoy change that closes several at once, each linking into its risk-flag guide.
  • Consumers (hashed) and Sample events — the retained consumer_hash values and sample_event_ids (drill into them via Inspect sample requests, which opens the Events tab in sample mode over a 7-day window).

Events​

The raw per-request log from ClickHouse (up to 500/page over a window, max 7 days): time, status, duration, method, path, host, cluster, source (raw IP or hash), User-Agent (raw or hash), risk (flags + score), and request id. Filter by method, status range, request id, risk flag, and min risk score. An expand row reveals node/stream/protocol, request/response bytes, route, auth, consumer hash, TLS (version/SNI/peer subject), gRPC status/message, and — with Full fields on — headers and enrichment tags. Requires ClickHouse; degrades gracefully with a clear message when it's offline.

Analytics​

Time-series rollups (1m / 1h / 1d buckets): stacked request volume by status class, latency percentiles (p50/p95/p99), error and client-error rate, throughput (response bytes), and unique-consumer / unique-source-IP counts, plus max risk over time.

Insights (geo & threat)​

Top source countries, ASNs, and cities; the User-Agent breakdown; and threat-intel hits — each optionally with a time-series stack. Raw UA / IP dimensions are an explicit toggle (they cost extra ClickHouse scans). Requires ClickHouse.

Admin actions​

On the detail header, Admins/Owners get an Actions menu:

  • Reset counters & risk — zero this endpoint's counters and monotonic scores; the collector re-accumulates from the next event.
  • Delete endpoint — remove the inventory row. If traffic still hits it, the collector recreates it on the next request — so delete is only permanent for genuinely dead endpoints.

Both are also available in bulk at the project level from the Listeners tab.

Endpoint categories​

The collector tags each operation with one or more semantic categories (matched by regex on the normalized path), surfaced as chips and as a filter:

CategoryMatches paths like
admin_endpoint/admin, /console, /management, /dashboard
auth_endpoint/login, /signin, /oauth, /sso, /saml, /token, /password
account_management/users/{id}/email, /users/{id}/password, /users/{id}/profile
payment_endpoint/checkout, /payment, /billing, /charge, /refund, /invoice
data_export/export, /download, /dump, /backup, /bulk
api_docs/swagger, /openapi, /api-docs, /redoc, /graphiql
metadata_leak/.env, /.git, /.aws, /.ssh, /server-status (note: generic config paths are deliberately excluded to avoid flagging legitimate routes like /api/v1/config)

One endpoint can carry several (/admin/export matches both admin_endpoint and data_export). These categories also drive detectors — brute_force_suspect keys off auth_endpoint, payment_abuse_suspect off payment_endpoint.