@@ -0,0 +1,88 @@
|
||||
# ADR 0002: publisher trust, discovery, compatibility, and fallback
|
||||
|
||||
- Status: Accepted
|
||||
- Date: 2026-07-16
|
||||
- Tracking: #2
|
||||
|
||||
## Context
|
||||
|
||||
Dedicated servers can protect provisioned credentials. Public game binaries
|
||||
cannot. Discovery also needs rules that prevent accidental cross-game joins and
|
||||
make the meaning of a successful authorization precise.
|
||||
|
||||
## Decision
|
||||
|
||||
### Publisher trust modes
|
||||
|
||||
Each `GameId` and `EnvironmentId` is provisioned policy, never caller-created
|
||||
free text. V1 supports two visibly distinct publisher modes:
|
||||
|
||||
1. **Managed dedicated host.** A provisioned workload principal authenticates
|
||||
with a rotatable credential held outside the game binary. It is scoped to
|
||||
allowed games, environments, regions, and listing limits. Public or unlisted
|
||||
discovery may be enabled by policy.
|
||||
2. **Player-hosted session.** A short-lived publisher grant is minted by a
|
||||
game-owned backend and is scoped to one game, environment, host, and expiry.
|
||||
Rendezvous does not interpret it as player identity. If a game has no grant
|
||||
issuer, it may opt into anonymous unlisted hosting with strict address and
|
||||
concurrency limits; anonymous sessions can be joined only through an opaque
|
||||
share code and never appear in public browsing.
|
||||
|
||||
A reusable credential embedded in a downloadable client is not authentication
|
||||
and is rejected as a provisioning design. Responses and metrics expose the
|
||||
publisher trust mode so operators and games can apply different policy without
|
||||
claiming anonymous hosts are authenticated identities.
|
||||
|
||||
### Discovery and metadata
|
||||
|
||||
- `Public` listings can appear only in tenant-scoped compatible browsing.
|
||||
- `Unlisted` listings never appear in browse results and require a random,
|
||||
unguessable share code. Unlisted does not mean private; join authorization and
|
||||
host admission still apply.
|
||||
- Browser responses contain display data only. They exclude raw endpoints,
|
||||
internal IDs, lease credentials, punch capabilities, and connection tickets.
|
||||
- Metadata is treated as hostile data. It is schema/budget validated, stored and
|
||||
returned as data, and never rendered as markup by the SDK or TestClient.
|
||||
|
||||
### Compatibility and address families
|
||||
|
||||
- `NetworkProtocolVersion` must match exactly in v1. `BuildVersion` is bounded
|
||||
display/diagnostic text and never overrides protocol compatibility.
|
||||
- `GameId` and `EnvironmentId` must match exactly. Region is a browse filter and
|
||||
preference, not a compatibility escape hatch.
|
||||
- IPv4 direct connection and NAT punching are required for v1.
|
||||
- Contracts carry an address-family discriminator. IPv6 direct connections may
|
||||
use observed global IPv6 endpoints when both peers support them, but IPv6 NAT
|
||||
traversal is not a v1 release requirement.
|
||||
- Public candidates are derived only from the authenticated UDP packet's source.
|
||||
For same-LAN attempts, that packet may additionally claim at most one private
|
||||
unicast candidate per supported address family. A local claim is scoped to the
|
||||
capability and is introduced only to the opposite role in the same authorized
|
||||
attempt after both roles contribute. Loopback, link-local, multicast,
|
||||
unspecified, documentation, and otherwise invalid destinations are rejected.
|
||||
The SDK bounds probes per introduced candidate and lets callers disable local
|
||||
candidates. HTTP-supplied endpoint claims are never introduced.
|
||||
|
||||
### Authorization and fallback
|
||||
|
||||
Join authorization means only that Rendezvous permits a scoped connection
|
||||
attempt. It does not reserve a game slot and does not authenticate a player to
|
||||
the game. The host validates and consumes the connection ticket, then applies
|
||||
its own capacity, ban, identity, and gameplay rules.
|
||||
|
||||
The SDK returns a typed outcome including success, cancellation, timeout,
|
||||
incompatibility, stale host, service rejection, host rejection, and transport
|
||||
failure. A game may provision an optional dedicated fallback endpoint. The SDK
|
||||
reports it but never connects without an explicit caller decision.
|
||||
|
||||
Gameplay relay is not part of v1. It remains a separate future service whose
|
||||
need is evaluated from privacy-safe measured direct-connection failures.
|
||||
|
||||
## Consequences
|
||||
|
||||
- A player-hosted game needs a game-owned grant issuer for public discovery.
|
||||
- Anonymous player hosting is useful for direct invitations but makes no user
|
||||
identity claim and receives the strictest quotas.
|
||||
- Games remain responsible for presenting unsafe user-authored text safely.
|
||||
- The exact-match v1 rule favors predictable interoperation over flexible
|
||||
version ranges; a later compatibility scheme must be versioned explicitly.
|
||||
Reference in New Issue
Block a user