Signals reference

A signal is a named fact with evidence — a release-coupled rule that reads what the system measured and reports whether a specific condition holds for a subject. This page is the per-signal reference: what each v1 signal is, which subject it is about, and when it fires. The Signals page in the UI shows the current firings; this is where you look up what one means.

The rules themselves live in internal/signal/ and their design is fixed by ADR-0004. This reference is release-coupled: it describes the v1 rule set (seventeen rules) and is meant to be verified against the code, never to drift from it.


What a signal is — and is not

  • A named fact, not a score. A signal carries no severity. Severity ranks a static backlog; verge-asm's subject is change, so urgency comes from the transition that surfaced a signal, not from a number stapled to the rule. There is no high/medium/low, and there is no dial to add one — a port you can hide is a signal you can silence.
  • A rule that ships at release cadence. A condition qualifies as a signal only if its reference data changes at release cadence. Anything you would want to push updates to out of band — a growing corpus of indicators — is a signature database, and it is deliberately out of scope. Four v1 signals read a small piece of release-coupled reference data — a port list, a key-and-algorithm table, an expiry horizon, and a set of address ranges (each noted below); the other thirteen read none.
  • Pure and attributable. A signal is a pure function of its inputs and its rule. Hold the rule version constant and any change in the signal set is attributable to the world. Across a rule-version change the two sets are not compared at all, so a rule edit never masquerades as drift in your estate.

The four verdicts

Every rule returns one of four outcomes for each subject. Only three are rendered; the fourth removes the subject from the rule's view entirely.

VerdictMeaning
firedThe condition holds for this subject.
not-firedThe condition was evaluated and does not hold.
not-evaluableThe rule could not decide — the evidence is about our own sight (a Shadowed value) or there is no value at all (a Gap). Never counted as "did not fire."
outside-domainThe rule was never about this subject (e.g. a CNAME rule over a name that has no CNAME). Not rendered at all, so the "did not fire" column never swells with subjects the rule does not concern.

The census a signal presents is a current-state picture over its predicate domain — who is firing now — never a delta. The change surface lives in Messages.


Name signals

These read the resolution facets (resolution-walk, wildcard-discrimination) and are about a Name.

lame-delegation

Fires when a Name's delegated nameservers were all reached and none serves the zone — a lame delegation. not-evaluable while resolution is Shadowed or a Gap. This is one of two signals that also alert on clearing: a delegation that stops being lame may be an attacker claiming the orphaned name, so the change is reported as this changed, never resolved.

cname-target-name-error

Fires when a Name holds a CNAME whose target does not exist (NameError) — the dangling-CNAME setup behind classic subdomain takeover. outside-domain for names with no CNAME; not-evaluable where the name or its target is Shadowed or unreadable. Also alerts on clearing, for the same takeover reason as lame-delegation.

zone-declared-name-returns-name-error

Fires when your zone file declares a name that your resolver says does not exist (NameError) — the zone promises a record the world cannot see. outside-domain for names your zone does not declare; not-evaluable on Lame/Shadowed/Gap. Requires an uploaded zone file.

resolved-name-absent-from-zone

Fires when a name resolves inside your declared zone but your zone file does not contain it — a live name the authoritative export omits. outside-domain outside a declared zone; not-evaluable when Shadowed. Requires an uploaded zone file.

non-globally-reachable-address-resolved-from-internet

Fires when an internet-class resolution returns an address that is not globally reachable (loopback, link-local, RFC 1918 / ULA private space, or an IANA special-purpose range) — an internal address leaking into a public DNS answer. This is a vantage-scoped signal (ADR-0071): it is read only at the internet vantage and has no internal twin. outside-domain without an internet-class answer; not-evaluable when that answer is Shadowed. Its notion of globally reachable is release-coupled reference data — the IANA special-purpose address ranges (loopback, link-local, RFC 1918 / ULA, and the special-purpose registries), applied as fixed classification.


Endpoint signals

These are about an Endpoint and read its certificate and http-identity facets. Their evidence already presupposes something reached the endpoint, so — unlike the Service exposure signal — they carry no vantage gate.

The five certificate-detail rules all fire over an endpoint whose certificate was presented, and return not-evaluable when the certificate was presented but its attributes could not be read:

certificate-expired

Fires when the presented certificate is past not_after.

certificate-not-yet-valid

Fires when the presented certificate's not_before is in the future.

certificate-expiring

Fires when the presented certificate is within the expiry horizon N. N is a release-fixed parameter, not an operator dial: one third of the certificate's validity period, and one half where that period is 10 days or less. It is a curated, release-coupled value.

certificate-self-signed

Fires when the presented certificate is self-signed.

certificate-weak-key-or-signature

Fires when the presented certificate uses a weak key size or a deprecated signature algorithm. The key-size floor and deprecated-algorithm set are a curated table (see docs/research/weak-key-and-signature.md).

certificate-hostname-san-mismatch

Fires when the presented chain's SANs do not cover the endpoint's Name. outside-domain for a nameless endpoint; not-evaluable when the certificate details are unreadable.

plaintext-http-no-https

Fires when an endpoint that responded to HTTP presents no TLS anywhere — plaintext with no HTTPS counterpart. outside-domain where HTTP did not respond; not-evaluable where TLS was not measured. (Not gated on internet reach — gating it would smuggle severity back in as evaluability.)

redirect-does-not-upgrade-to-tls

Fires when an HTTP 3xx redirect's Location is not https (a relative Location keeps the plaintext scheme and fires). outside-domain for non-redirect responses.

redirect-to-host-outside-estate

Fires when an HTTP 3xx redirect points to a host outside your estate. A relative Location (no host) does not fire. outside-domain for non-redirect responses.

unauthenticated-request-answered

Fires when an unauthenticated GET / is answered with a 2xx rather than challenged. A 401/403 is not-fired (correctly challenged); any other status is outside-domain.


Service signals

These are about a Service (a (port, transport) on an address).

tls-1.0-accepted

Fires when a Service that completed a TLS handshake accepts TLS 1.0. outside-domain for services that completed no handshake; not-evaluable when the handshake completed but the accepted versions could not be read. Reads the tls-acceptance facet.

sensitive-port-reached-from-internet

Fires when a Service on verge-core's sensitive-port list is reached from the internet vantage. This is the product's flagship signal and the only v1 signal that reads Exposure — specifically the internet Reach leg. outside-domain for ports not on the sensitive list; not-evaluable where there is no internet-class value (no prober, or a Gap), because a claim about internet reach with nobody looking from outside is not a not-fired — it is unanswerable. The sensitive-port list is a curated table. See first-run.md → Exposure needs two legs.


Why a signal can read not-evaluable

not-evaluable is not an error — it is the system being honest that it cannot construct the claim rather than guessing. A certificate rule over an endpoint whose certificate was Shadowed, or the internet-exposure signal on an install with no prober, both read not-evaluable. This is the same discipline as Coverage: reading where the system stops is as much the job as reading where it fires. See using.md → Reading what it found.