The ported docs still framed alknet siblings (alknet-core/-call/-channels/
-http/-tls/-client) as live load-bearing context of this crate. With the
extraction complete and alknet headed for glue-level replacement, the docs
now speak as alkcall and cite the real sibling crates (alkhttp, alktls,
alktty, alktunnels, alktrader).
- ADR-054 (new): re-own the verifier-selection rule in-crate — three
remote roles (public X.509 endpoint / transport relay / hub),
ServerCertVerifier by PeerEntry presence, RemoteIdentity None
load-bearing. Provenance: alknet ADR-034 (never ported), demoted to
footnote. Resolves OQ-21's cross-repo authority gap.
- OQ-43 (new, deferred(scope)): composition-layer ownership and shape
after the alknet replacement — the named receiver for the
downstream-side deferrals (OQ-33 endpoint layer, OQ-41 QUIC-native
substrate, OQ-42 hub broker, OQ-19 persistence adapters, ADR-045 dial
seam). README layering diagram redrawn with the composition layer as
TBD-ownership instead of "alknet / alknode" in concrete.
- Spec docs reframed: titles, self-references, dial/TLS/from_jsonschema
homes, malformed legacy cite rows removed; dead relative research
paths qualified as source-repo paths.
- ADR amendments (append-only): 027 (alknet-http -> alkhttp), 031 (post-
extraction state), 044 (split landed as modules in alkcall), 045
(name normalization; citation-space note).
- Citation hygiene: unprefixed/colliding source-repo cites prefixed
("alknet ADR-NNN (provenance)") across 009/011/022/034/035/038/040/
043/044/045; stale OQ cites corrected (session registries OQ-04, batch
semantics OQ-03, verifier rule ADR-054); stale anchors fixed.
- README provenance note consolidated; citation conventions documented.
Verification: markdown link check (all local links resolve, all in-crate
ADR cites point at existing decisions/ files); table integrity check
(uniform row widths across open-questions.md and edited tables); residual
alknet-mention sweep (only provenance/historical/intentional framing
remains); architecture review subagent pass with zero remaining criticals.
Docs-only change — no code paths touched.
5.6 KiB
ADR-054: Outgoing-Only X.509 and the Three Remote Roles (Re-Owned In-Crate)
Status
Accepted (re-owns the verifier-selection rule for alkcall's surface; provenance: alknet ADR-034, not ported)
Context
alkcall's connection surface depends on a verifier-selection rule and a role taxonomy that were decided while this crate was a subdirectory of the alknet mono-repo. The deciding ADR (alknet ADR-034, "Outgoing-Only X.509 and Three Peer Roles") was never ported, so the rule's authority lives in a cross-repo link — a dependency on a document outside this crate for a constraint that binds this crate's public surface:
ConnectionCredentials.remote_identity: Nonesemantics (ADR-022 §7, (ADR-022 §7; alknet ADR-034 §2/§3, provenance):Noneis a load-bearing state — the public-X.509-endpoint path, not a missing field.- Client-side
ServerCertVerifierselection is byPeerEntrypresence, not by key type alone (OQ-14 #2). PeerEntryasymmetry: a pure-client connection to a public X.509 endpoint is not in the call-protocol peer graph on the client side (noPeerEntry, noPeerId, noPeerRef::Specificrouting).
The alknet mono-repo is being rewritten as a thin glue layer over this crate and its siblings; cross-repo ADR links will not survive that rewrite as authority. The rule must be owned here.
Decision
alkcall re-owns the rule in-crate. Three things are adopted:
1. Three remote roles
The single label "X.509 endpoint" conflated three structurally different remote roles:
- Public X.509 endpoint — a remote server reachable by domain
name, authenticated by a CA-issued X.509 cert. The local node is a
client of it (a third-party API, a public hub dialed over the
open internet, a peer that exposes domain + X.509 instead of an
Ed25519 raw key). The client authenticates to the server by bearer
token (
auth_tokenpayload field when riding the call protocol); the server authenticates to the client by CA verification (WebPKI), not fingerprint pinning. - Transport relay — a connectivity-assistance node
(iroh's DERP-equivalent) that forwards encrypted datagrams between
peers who cannot directly connect. It is infrastructure, not an
application peer: no registered operations, no peer graph
participation, no
PeerEntry. Its identity is the transport's concern, not this crate's. - Hub / hosting node — an application peer acting as a hub in a
hub-and-spoke topology. An ordinary
PeerEntryholding mixed fingerprints (Ed25519 raw key and/or X.509) — fingerprint pinning applies on both cert paths.
2. Verifier selection is by PeerEntry presence, not key type
The client-side ServerCertVerifier is selected by whether the local
node holds a PeerEntry for the remote:
Local PeerEntry for remote? |
Remote cert | Verifier | Peer graph? |
|---|---|---|---|
| yes | Ed25519 or X.509 | fingerprint pin | in (PeerId resolved from client-cert fingerprint — ADR-025 §5) |
| no | X.509 | WebPkiServerVerifier (CA) |
not in (no PeerId) |
| no | Ed25519 raw key | fail closed (no CA to fall back to) | not in |
3. remote_identity: None is load-bearing
Some(fingerprint) means "pin this" (known peer). None means "no
PeerEntry for this remote" — CA verification for X.509 remotes,
hard failure for Ed25519 raw-key remotes. An implementation must not
default remote_identity to a placeholder to satisfy the field, and
must not treat None as "skip verification."
4. Scope of the re-own
This ADR is the deciding authority for alkcall's surface
(ConnectionCredentials, RemoteIdentity, the ServerCertVerifier
selection the dial-composer implements, PeerEntry asymmetry in the
peer graph). It does not re-own alknet ADR-034's other content (ACME
issuance, cert rotation, the alktls config surface) — those remain
properties of the transport/composition layer (see OQ-43, composition
layer). alknet ADR-034 is demoted to provenance: historical origin of
this rule, cited as such.
Consequences
Positive:
- The constraint binding alkcall's public surface is decided in this crate's decision log; cross-repo link rot cannot strip the authority.
- OQ-21's "deciding ADR (alknet ADR-034, not ported)" caveat is
resolved — the surviving surfaces (
client-and-adapters.md§credentials, ADR-025'sPeerEntryasymmetry) now cite an in-crate ADR. - The alknet rewrite can proceed without a documentation dependency from this crate on the old repo's ADR numbering.
Negative:
- One more rule with a historical origin story in a different numbering space; the provenance note (README §References) is the single place that maps old to new.
References
- client-and-adapters.md — the working
spec carrying these semantics (§Credential sources for connections,
§Constraints "Pure-client X.509 connections",
remote_identityload-bearing rule) - ADR-022 §7 — transport-identity dimensions on the call protocol
- ADR-025 —
PeerEntryasymmetry,PeerIdsource, client-cert fingerprint →peer_idresolution - ADR-012 —
ConnectionCredentialsshape (the dial consumes it; verifier selection is applied there) - OQ-21 (resolved by this ADR), OQ-43 (composition-layer ownership — the transport/composition half mentioned in §4's scope carve-out)
- Provenance: alknet ADR-034, "Outgoing-Only X.509 and Three Peer
Roles" (
/workspace/@alkdev/alknet/docs/architecture/decisions/), retained as history, not authority