Skip to content

List executors with RIPE Atlas-style addresses (API 1.16) - #396

Merged
vincent10400094 merged 2 commits into
mainfrom
feat/public-probe-addresses
Oct 6, 2026
Merged

vincent10400094 merged 2 commits into
mainfrom
feat/public-probe-addresses

Conversation

@vincent10400094

Copy link
Copy Markdown
Member

Summary

The public executor listing follows the RIPE Atlas probe model for addresses and privacy (API 1.16).

  • GET /executors adds is_public, address_v4, address_v6, prefix_v4, prefix_v6, asn_v4, asn_v6 and address_observations. The result admission snapshot records the same fields as provenance.vantage_point.addressing (result format 1.1, schema 1, additive).
  • Observed addresses only. An address is the peer of one of the executor's authenticated connections (certificate plus current control-session credentials): the control connection (via: control, preferred for its family, observed_at = last heartbeat of that session) or the existing ReflectAddress call (via: reflection, observed_at = receipt). The dispatcher records the TCP peer, never a request value; public_host and the hello source IP stay operator-only claims. Observations end with the control session, as connectivity proof already does, so a moved executor does not keep its old address.
  • Second family. No new RPC: executors call the existing ReflectAddress over each family every 10 minutes, resolving the host of dispatcher.addr and verifying the dispatcher certificate for that name (a resolved address that is not the dispatcher fails TLS). Families with a configured reflector are skipped, since their 30 s check already reflects. [connectivity] observe_addresses = false turns it off. It feeds the listing only, never the connectivity report or admission.
  • Prefix/ASN come from the existing offline ASN lookup (Add offline ASN and approximate location metadata #351): the control family reuses ip_metadata.observed.asn, the reflected family is looked up on receipt. No change to the lookup source, so feat/ris-asn-database slots in unchanged.
  • Privacy. [metadata] address_opt_out = true (protocol field VantagePointReport.address_opt_out = 13, read at registration like location_opt_out) makes the executor private: the public listing withholds both addresses and nothing else. Established operators still see them; the run owner sees them in provenance. is_public and location_opt_out are independent, as in RIPE Atlas (a private probe keeps its location public; location is the host's own choice). Rationale is in docs/vantage-points.md#privacy.
  • Compatibility. Additive wire fields; older clients ignore them. Older executors don't send the flag and are public (the requested default). This changes privacy for existing deployments: the control-connection source IP, operator-only until now, becomes public on dispatcher upgrade. The CHANGELOG and privacy note say to upgrade and set address_opt_out first to stay private. /executors/by-ip and /attribution/candidates are unchanged.
  • dbl nodes adds ADDRESS_V4 and ADDRESS_V6 columns (private when withheld, - when unknown, invalid values are not printed); --output json carries every field.

Example entry (other fields elided):

{
  "id": "eth-zurich-1",
  "is_public": true,
  "address_v4": "192.0.2.10",
  "address_v6": "2001:db8:10::7",
  "prefix_v4": "192.0.2.0/24",
  "prefix_v6": "2001:db8::/32",
  "asn_v4": 64500,
  "asn_v6": 64500,
  "address_observations": {
    "v4": {"source": "dispatcher-observed", "via": "control", "observed_at": 1791250000, "lookup_source": "database:GeoLite2-ASN@1790000000", "lookup_reason": ""},
    "v6": {"source": "dispatcher-observed", "via": "reflection", "observed_at": 1791249700, "lookup_source": "database:GeoLite2-ASN@1790000000", "lookup_reason": ""}
  }
}

Coordination

Testing

  • go test for internal/dispatcher/..., internal/executor/..., pkg/..., cmd/dbl (macOS-only failures in cmd/dbl executor-join, internal/executor/debuglet listener quota and the canary driver also fail on main locally; CI runs them on Linux).
  • New: control vs reflection preference, private hides only addresses, claimed source never published (internal/dispatcher/probe_addresses_test.go); real IPv6 reflection over [::1] through ReflectAddressAs and no carry-over to a replacement session; HTTP listing public/private/operator views validated against the OpenAPI contract (internal/dispatcher/transport/api/probe_addresses_test.go); config defaults; reflection targets; dbl nodes columns.
  • scripts/ci-generate.sh write-proto, gofmt, go vet.

🤖 Generated with Claude Code

vincent10400094 and others added 2 commits October 6, 2026 06:21
API 1.16 adds is_public, the last dispatcher-observed address_v4 and
address_v6, their prefix and ASN from the existing offline ASN lookup,
and address_observations (via control or reflection, observed_at and
the lookup source) to GET /executors, and records the same fields in
the result's admission snapshot.

Only addresses the dispatcher saw on the executor's authenticated
connections are listed: the control connection's peer, preferred for
its family, and the peer of the existing ReflectAddress call for the
other family. Executors now make that call over each family every ten
minutes, resolving dispatcher.addr and verifying the dispatcher's
certificate for its name; [connectivity] observe_addresses turns it
off, and a family with a configured reflector is not called twice.
Observations end with the control session, like connectivity proof.

[metadata] address_opt_out makes an executor private, as a RIPE Atlas
host can: the public listing withholds its addresses and nothing else.
It is independent of location_opt_out. Executors are public by
default, including older ones, so the privacy note and changelog say
how to stay private before the dispatcher is upgraded. dbl nodes adds
ADDRESS_V4 and ADDRESS_V6 columns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The compatibility canary pins the exact JSON shape of dbl nodes and
refused the new is_public, address, prefix, ASN and
address_observations fields. Allow them, null for an older
dispatcher, and check the observation records' shape.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vincent10400094
vincent10400094 force-pushed the feat/public-probe-addresses branch from 60d71b9 to 2624bf9 Compare October 6, 2026 04:21

@vincent10400094 vincent10400094 left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed rebased head 2624bf9. Address observations are authenticated dispatcher-peer observations, never executor-provided values; the public listing has an explicit address opt-out; and the API/CLI/docs cover the resulting visibility and operator access. All required CI checks pass on this head. GitHub does not permit author self-approval, so this comment records the completed review before the authorized administrator merge.

@vincent10400094
vincent10400094 merged commit 3c844a7 into main Oct 6, 2026
16 checks passed
@vincent10400094
vincent10400094 deleted the feat/public-probe-addresses branch October 6, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant