Help us shape the future of Go! Take the 2026 Go Developer Survey

trackingdomain

package
v0.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package trackingdomain verifies a Sending domain's Tracking domain (ADR 0038): a live DNS check that track.<domain> is a CNAME to the Instance's edge host, and the state that check keeps (pending -> dns_verified), and the HTTPS probe that moves a verified host to serving. The periodic job calls Check for every row.

The resolver and the clock are injected, so nothing here reads the network or the wall clock. A host is unique across the Instance among rows in dns_verified or serving; the partial unique index on the domain enforces it, and Check reports a lost race as ErrHostTaken by catching the violation, never by looking first. The state moves through a lifecycle table (ADR 0046) whose write is a compare-and-swap from the state Check read; a check that lost it returns lifecycle.ErrInvalidTransition and stores nothing.

Index

Constants

View Source
const ProbePath = "/.well-known/sphericon-tracking"

ProbePath is the well-known path a Tracking host serves for the serving check (ADR 0038): GET https://<host>/.well-known/sphericon-tracking answers 200 with ProbeValue(secret, host) as the plain-text body. The probe succeeds only when the body equals the value for the host it asked, so an answer from another host, a parked page or a proxy that is not ours does not pass.

Variables

View Source
var ErrHostTaken = errors.New("tracking host is verified by another workspace")

ErrHostTaken means another Workspace holds the host in dns_verified or serving: this claim stays pending however correct its DNS is.

Functions

func ProbeValue

func ProbeValue(secret, host string) string

ProbeValue is the body ProbePath answers for host: a hex HMAC-SHA256 of the lowercase host under secret (the Instance JWT secret), so it is tied to the domain and cannot be guessed or copied from another host. Both sides compute it; nothing is stored.

Types

type CNAMELookup

type CNAMELookup func(ctx context.Context, host string) (string, error)

CNAMELookup resolves the canonical name of a host. net.Resolver.LookupCNAME satisfies it; a host with no CNAME answers itself or a not-found error.

type Doer

type Doer interface {
	Do(req *http.Request) (*http.Response, error)
}

Doer is the HTTP client the probe uses: the SSRF-guarded one in production.

type Verifier

type Verifier struct {
	Lookup CNAMELookup
	Target string
	Now    func() time.Time
	HTTP   Doer
	Secret string
	Events *events.Bus
}

Verifier checks Tracking domains against Target, the edge host the CNAME must reach. With HTTP and Secret set it also proves serving: a host reaches serving only when the HTTPS probe answers ProbeValue(Secret, host). Without HTTP no host ever becomes serving.

func (*Verifier) Check

Check re-verifies one Sending domain's Tracking domain from live DNS and, once the CNAME is right, the HTTPS probe, and stores the outcome: the check time always, and the state when it changes, with a TrackingDomainChanged event in the same transaction. DNS gone sends the state back to pending; a CNAME at Target with a failing probe is dns_verified (a serving host falls back to it); a passing probe is serving. A resolver failure other than not-found returns its error and changes nothing. It returns the resulting state, with ErrHostTaken when the host is held elsewhere; the row then carries the reason host_taken until a later check stores its outcome without losing the claim (the reason is cleared on every stored outcome, including an absent CNAME).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL