Files
cgalo5758 8e3c68c6be Make UI surfaces honestly reflect system state
- Add deployment-name branding to titles, mastheads, and OG tags
- Share one grant delivery-state query with lineage across grants
  surfaces
- Show pool status/usage, org owners, and config readiness
- Make billing views projection-aware with recency and sync vocabulary
- Guard FedWiki creation without domains and render route-aware 404s
2026-08-23 01:45:52 -05:00

6.5 KiB

domain-authorization Specification

Purpose

Decide, per exact fully-qualified domain name, whether the deployment may serve (and mint a TLS certificate for) that name — the console-side answer to a TLS proxy's on-demand ask contract, backed by registered placements rather than filesystem state.

Requirements

Requirement: Serving-authorization endpoint

The system SHALL expose an unauthenticated endpoint GET /domains/ask accepting a domain query parameter, implementing the on-demand-TLS ask contract: it SHALL respond 200 with an empty body if and only if a servable placement exists at exactly that fully-qualified domain name, and a non-200 status otherwise — except that when domains-ask-fallback-url is configured, a name entirely unknown to the registry MAY be authorized by the fallback answerer (see "Registry misses may be forwarded to a configured legacy answerer"). Before lookup the system SHALL normalize the queried name by lowercasing and stripping a single trailing dot. The check SHALL be an exact-match indexed lookup against domains.placements; the endpoint SHALL NOT perform hierarchical (ancestor or wildcard) matching — a claim without a placement at the queried name SHALL NOT authorize serving. A request with a missing or empty domain parameter SHALL receive a non-200 response.

Scenario: Servable placement is authorized

  • WHEN /domains/ask?domain=alice.example.test is requested and a placement exists at alice.example.test with servable = true
  • THEN the response status SHALL be 200

Scenario: Read-only site is still served

  • WHEN the placement at the queried domain backs a read-only site (the provider keeps it servable = true)
  • THEN the response status SHALL be 200

Scenario: Archived site is refused

  • WHEN the placement at the queried domain has servable = false (e.g. its site is archived)
  • THEN the response status SHALL be non-200

Scenario: Unknown domain is refused

  • WHEN no placement exists at the queried domain and no fallback is configured
  • THEN the response status SHALL be non-200

Scenario: Claimed but unplaced name is not authorized

  • WHEN a live claim exists at alice.example.test with no placement at blog.alice.example.test, and the query is for blog.alice.example.test
  • THEN the response status SHALL be non-200

Scenario: Query is normalized before lookup

  • WHEN the query is Alice.Example.Test. and a servable placement exists at alice.example.test
  • THEN the response status SHALL be 200

Scenario: Missing domain parameter

  • WHEN /domains/ask is requested without a domain parameter
  • THEN the response status SHALL be non-200

Requirement: Authorization is delegated through a provider-neutral seam

The /domains/ask handler SHALL delegate to a narrow authorizer interface owned by the core server, and SHALL NOT query provider storage directly. The domains registry SHALL supply the authorizer implementation backed by domains.placements, and the route (with its authentication and CSRF exemptions) SHALL be registered by core, not by a provider integration. Replacing the authorizer implementation SHALL NOT change the endpoint's HTTP contract.

Scenario: Registry-backed authorizer answers the contract

  • WHEN the server boots
  • THEN /domains/ask SHALL answer according to domains.placements servability as specified above, with no provider integration involved in the lookup

Scenario: Contract is implementation-independent

  • WHEN the authorizer implementation is substituted
  • THEN the request/response contract of /domains/ask SHALL remain unchanged

Requirement: Registry misses may be forwarded to a configured legacy answerer

The endpoint SHALL forward registry misses to a configured legacy answerer when the configuration key domains-ask-fallback-url is set (default empty = disabled). A "miss" SHALL mean no placement row exists at the queried name: a placement with servable = false SHALL be refused locally and SHALL NOT consult the fallback (an archived name must not be resurrected by the legacy answerer). The forwarded request SHALL be built with URL-library query encoding (never string concatenation of the attacker-controllable parameter), setting domain to the normalized name, sent with a short timeout; the endpoint SHALL respond 200 if and only if the fallback answers 200. Names failing FQDN shape validation SHALL be refused without any outbound request. Registry hits SHALL NOT consult the fallback. Fallback errors or timeouts SHALL be treated as refusal (fail-closed). This is a migration-window seam (strangler pattern for deployments moving off filesystem-based answerers); the general availability posture remains that a console outage stops new certificate issuance while existing certificates keep serving.

Scenario: Miss forwarded to the fallback

  • WHEN the fallback URL is configured, no placement exists at the queried name, and the legacy answerer responds 200 for it
  • THEN /domains/ask SHALL respond 200

Scenario: Fallback refusal and errors fail closed

  • WHEN the fallback answers non-200, times out, or is unreachable for a registry-miss query
  • THEN /domains/ask SHALL respond non-200

Scenario: Unservable placement never falls through

  • WHEN the fallback URL is configured and a placement exists at the queried name with servable = false
  • THEN /domains/ask SHALL respond non-200 without consulting the fallback

Scenario: Disabled by default

  • WHEN domains-ask-fallback-url is unset and no placement exists at the queried name
  • THEN /domains/ask SHALL respond non-200 without attempting any outbound request

Requirement: Malformed public ask requests render a styled error page

The public domain-ask endpoint SHALL answer malformed browser requests (such as a missing domain parameter) with a styled, human-readable error page — a short plain-language statement of what was missing and what the visitor can do — instead of an unstyled plaintext string. The HTTP status and the machine-facing contract for programmatic callers are unchanged; only the browser-facing rendering is specified here.

Scenario: Missing parameter renders a styled page

  • WHEN a visitor's browser requests the public ask endpoint without the required domain parameter
  • THEN the response renders a styled page stating in plain language that the link is missing its domain and what to do next
  • AND the response does not consist of a bare internal parameter name on an unstyled page