Files
wild-central/docs/registrations.md
Paul Payne 98385449b4 feat: Service cards with inline toggles + updated docs
Service cards now have:
- Public/Private toggle (switches reach)
- Subdomains toggle (include *.domain)
- TLS badge (passthrough vs terminate, read-only for now)
- Inline status details (DNS, Proxy, TLS status)
- Deregister button
- Add Service form with toggles instead of dropdowns

The card speaks the user's language (public/private, subdomains on/off)
not implementation details (tcp-passthrough vs http, reach: internal).

Also updated docs/registrations.md:
- Added "User-facing concepts" section mapping API fields to toggles
- Added batch deregister endpoint
- Added backend.health field
- Cleaner examples

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-07-09 23:50:05 +00:00

4.5 KiB

Service Registrations

Wild Central provides DNS, proxy routing, TLS, and DDNS for services on the LAN. External consumers (Wild Cloud, Wild Works) register their domains with Central's API, and Central handles the networking.

Registration API

POST   /api/v1/services              Register a domain
GET    /api/v1/services              List all registrations
GET    /api/v1/services/{domain}     Get registration details
PATCH  /api/v1/services/{domain}     Update a registration
DELETE /api/v1/services/{domain}     Remove a registration
DELETE /api/v1/services/deregister?source=X&backend=Y   Batch cleanup

The domain is the unique key. One registration per domain.

Fields

Field Type Required Default Description
domain string yes FQDN to route. Unique key.
source string no "manual" Who registered this: wild-cloud, wild-works, manual.
backend.address string yes Target host:port (e.g., 192.168.8.240:443).
backend.type string yes tcp-passthrough or http.
backend.health string no Health check path for L7 services (e.g., /health).
subdomains bool no false If true, also routes *.domain traffic to this backend.
reach string yes internal or public.
tls string no inferred passthrough or terminate. Defaults based on backend type.

User-facing concepts

The API fields map to three user-visible controls:

Public / Private

reach: "public" or reach: "internal"

  • Private (internal): Domain resolves only on the LAN. No public DNS record. Accessible only from your local network or VPN.
  • Public: Domain resolves on the LAN AND has a public DNS A record. Accessible from the internet through Central's HAProxy.

Subdomains

subdomains: true or subdomains: false

  • Off (default): Only the exact domain is routed (payne.io routes, but foo.payne.io does not).
  • On: Both the domain and all subdomains are routed (cloud.payne.io AND matrix.cloud.payne.io, vaultwarden.cloud.payne.io, etc.).

TLS handling

tls: "passthrough" or tls: "terminate"

  • Passthrough: Central forwards encrypted traffic directly to the backend. The backend handles its own TLS certificates (e.g., a k8s cluster with traefik). Maps to backend.type: "tcp-passthrough".
  • Terminate: Central provisions a TLS certificate and handles HTTPS. Traffic is decrypted at Central and proxied as HTTP to the backend. Maps to backend.type: "http".

What Central does per registration

When a service is registered, Central automatically:

Effect Passthrough Terminate
LAN DNS address=/<domain>/<backend-IP> — direct to backend address=/<domain>/<central-IP> — through Central
LAN DNS (private) Also local=/<domain>/ — prevents upstream forwarding Same
Public DNS DDNS A record if public Same
Proxy L4 SNI passthrough. Subdomains adds *.domain matching. L7 HTTP reverse proxy by Host header.
TLS Backend handles — Central passes through Central provisions cert via Let's Encrypt

Examples

k8s cluster (passthrough, public, with subdomains)

{
  "domain": "cloud.payne.io",
  "source": "wild-cloud",
  "backend": {"address": "192.168.8.240:443", "type": "tcp-passthrough"},
  "subdomains": true,
  "reach": "public"
}

Central creates: LAN DNS → 192.168.8.240, public DNS A record, HAProxy L4 SNI + wildcard *.cloud.payne.io, TLS passthrough.

Internal web app (terminate, private)

{
  "domain": "wild-cloud.payne.io",
  "source": "wild-cloud",
  "backend": {"address": "127.0.0.1:5055", "type": "http"},
  "reach": "internal"
}

Central creates: LAN DNS → Central IP (with local=/), HAProxy L7 reverse proxy, TLS cert via certbot. No public DNS.

Custom domain (passthrough, public, exact match)

{
  "domain": "payne.io",
  "source": "wild-cloud",
  "backend": {"address": "192.168.8.240:443", "type": "tcp-passthrough"},
  "subdomains": false,
  "reach": "public"
}

Central creates: LAN DNS → 192.168.8.240, public DNS A record, HAProxy L4 SNI exact match only. No wildcard.

What is NOT a registration

Central's own services come from config, not the registration API:

  • Central's UI domain (cloud.central.domain)
  • VPN (cloud.vpn.*)
  • Firewall rules (cloud.nftables.*)
  • DHCP (cloud.dnsmasq.dhcp.*)
  • CrowdSec, certbot credentials, DDNS provider config