Changes: Accept ADR 0002 for pinned Stanza with mandatory bounded transport, verified SASL and SHA512 composition; record independent review findings and handoff with external limits retained. Validation: Fresh-cache pinned npm ci and browser build succeeded; all 112 tests passed. Verified 51 locked entries, 26 installed notices and 340 unchanged vendor files; six offer permutations and six adversarial XML checks passed; make check passed 72 tooling tests. No actual browser, independent full XMPP server/client, OMEMO or release readiness acceptance. Task: S00-003 Agent: auto-qa-d49749753ac6 Role: qa Action: review Status: done Task title: Проверить XMPP WSS/auth библиотеку
146 lines
9.5 KiB
Markdown
146 lines
9.5 KiB
Markdown
# ADR 0002: XMPP library and required browser integration seams
|
||
|
||
- Status: accepted for bounded S00-003 library selection; independent QA: `state/evidence/S00-003-review.md`.
|
||
- Date: 2026-10-15. Owner: auto-protocol-f474114f0168 (protocol).
|
||
- Reviewer: auto-qa-d49749753ac6 (qa), 2026-10-15.
|
||
- Requirements: ACC-004, NET-003, NET-004.
|
||
- Prerequisites: accepted scope/stack ADRs and bounded SASL, parser, SHA-512
|
||
experiments (S00-017/018/019); independently reviewed Linux environment S00-020.
|
||
|
||
## Question and decision
|
||
|
||
Select Stanza 12.22.1 (MIT), with the three reviewed public integration seams
|
||
mandatory before connect: bounded transport, fail-closed SASL feature, and the
|
||
SHA-512 mechanism composition. Stock Stanza alone is unsuitable for this profile.
|
||
Its stock SASL handler does not verify server-final, its browser hyphenated
|
||
SHA-512 HMAC is wrong, and its persistent parser has no finite resource budgets.
|
||
The accompanying spike proves the composed candidate; it creates no production
|
||
adapter, shared contract, crypto implementation or provider deployment.
|
||
|
||
| Option | Evidence and tradeoff |
|
||
| --- | --- |
|
||
| Stanza 12.22.1 plus reviewed extensions | Selected: actual browser bundle, public Client/Factory/Registry/Transport APIs, verified fixed SCRAM transcripts, loopback WSS and extension fixtures. JSON models and built-in MAM/MUC/Jingle/upload mappings fit the planned adapter boundary. Exact-version alias and replacement plugins require regression checks on upgrades. |
|
||
| Stock Stanza | Rejected: the accepted remediation experiments reproduce security/framing defects. Installing the package alone does not meet this decision. |
|
||
| xmpp.js | Viable alternative with browser WebSocket and modular packages; its primary README documents MIT and client/component modules. Not installed or executed here; no superiority/security finding or exact pin is claimed. It would require a separate equivalent integration experiment, rather than assuming its SASL/parser meet the profile. |
|
||
|
||
## One runnable selection experiment
|
||
|
||
`experiments/0002-xmpp-library/selection-spike` combines unchanged reviewed
|
||
bounded-ingress and SHA-512 alias source with the ordering guard extended to
|
||
non-PLUS SHA-512/256/1. Existing library crypto implements all hashes, HMAC,
|
||
SCRAM and SASLprep. No vendor file, private field or primitive is changed.
|
||
|
||
The real Client.connect, XML registry, feature dispatcher, queue and browser
|
||
SCRAM backend run against a synthetic loopback HTTPS/WebSocket peer. Its
|
||
self-signed certificate is generated temporarily by OpenSSL, trusted explicitly
|
||
by the test socket only, and hostname/certificate checks remain enabled. No
|
||
system trust store is changed. An uninjected native WebSocket rejects the same
|
||
untrusted certificate; a plaintext endpoint is rejected before a socket exists.
|
||
The trusted peer observes TLS plus the xmpp subprotocol, framing open, exact
|
||
proof and a second open only after a valid server-final. Forged/premature finals
|
||
never authenticate or restart. This is a real WSS handshake with a fixture peer,
|
||
not interoperability with a deployed independent XMPP server.
|
||
|
||
Mechanism policy filters PLUS because browser TLS binding is unavailable,
|
||
selects SHA-512 then SHA-256 then SHA-1 independent of offer order, and disables
|
||
all other fallbacks. NET-003 permits a configured protected fallback; this
|
||
selection enables none. PLUS-only/PLAIN-only/empty offers fail. Diagnostics
|
||
contain selected mechanism, `channelBinding: unavailable`, and disabled fallback;
|
||
no credential, nonce, proof or peer payload. Synthetic tlsUnique is rejected.
|
||
GS2 n,, and c=biws are verified. A future platform with real binding must add a
|
||
separately reviewed implementation before offering PLUS.
|
||
|
||
Parser experiment ceilings are preserved: 4096 UTF-8 bytes, depth 8, 32 elements,
|
||
16 attributes, 1024 aggregate attribute units, 128 name units and 256 attribute
|
||
value units. Standalone complete text XML is preflighted by saxes before JXT
|
||
import. Oversized and split XML fail on the actual WSS path. These numbers are
|
||
local experiment limits, not a production message/media-size contract.
|
||
|
||
Registry fixtures import/export MAM forwarded IDs, MUC join, Jingle terminate,
|
||
HTTP upload URLs and legacy opaque OMEMO bytes. An explicitly invented opaque
|
||
namespace demonstrates Client.use/Registry.define extension and namespace
|
||
isolation. It is not an OMEMO2 implementation or encrypted messaging claim.
|
||
Imported messages expose both selected `body` and `alternateLanguageBodies`;
|
||
exporting both concatenates text in this version. A regression records it;
|
||
the MAM fixture exports only the language collection. Future adapters must
|
||
construct deliberate outbound shapes rather than echo imported objects.
|
||
|
||
## Reproduction, versions and licenses
|
||
|
||
Follow the experiment README. Exact Node 24.21.0/npm 11.19.0 and Vite 8.3.4 remain
|
||
from accepted ADR 0001. Stanza 12.22.1, saxes 6.0.0, events 3.3.0 and test peer
|
||
ws 8.22.0 have exact direct pins; lock v3 includes all optional hosts. These are
|
||
already reviewed package families, not a new stack. MIT/ISC runtime notices,
|
||
Stanza bundled ancestry, and build MIT/ISC/BSD/Apache/MPL notices are preserved
|
||
in inventory/notices; saxes' omitted package license is preserved from the
|
||
reviewed versioned upstream copy. MPL build code is unmodified. Dependency
|
||
monitoring, provenance and advisory clearance remain continuing release work.
|
||
|
||
Browser syntax floors are the accepted Chrome/Edge 111, Firefox 114, Safari 16.4
|
||
build targets, not a product support certification. Bundle graph excludes Node
|
||
platform/crypto and unresolved builtins; events is explicitly bundled. Native
|
||
WebSocket, secure RNG, URL and TextEncoder are required. Server/test tooling
|
||
Node crypto is only an independent oracle; it does not replace browser crypto.
|
||
|
||
## Primary sources inspected on 2026-10-15
|
||
|
||
- [RFC 7395](https://www.rfc-editor.org/rfc/rfc7395.html), sections 3.1–3.4,
|
||
3.7 and 3.9: subprotocol, complete text XML, framing, restart and TLS.
|
||
- [RFC 5802](https://www.rfc-editor.org/rfc/rfc5802.html#section-5) and
|
||
[RFC 7677](https://www.rfc-editor.org/rfc/rfc7677.html#section-3): fixed SHA-1/256
|
||
exchange vectors and server verification. SHA-512 independent Scramp fixtures
|
||
and RFC 4231 primitive vectors retain their accepted S00-019 provenance.
|
||
- [Stanza upstream](https://github.com/legastero/stanza) and
|
||
[xmpp.js upstream](https://github.com/xmppjs/xmpp.js): candidate APIs, browser
|
||
positioning and licenses. Exact installed Stanza 12.22.1 Client.d.ts/.js,
|
||
lib/sasl, plugins/features, jxt/Registry and protocol modules are authoritative
|
||
for shipped extension behavior; all 340 files match the independently installed
|
||
S00-020 vendor graph. Upstream branches do not establish version guarantees.
|
||
- [XEP-0313](https://xmpp.org/extensions/xep-0313.html),
|
||
[XEP-0045](https://xmpp.org/extensions/xep-0045.html),
|
||
[XEP-0166](https://xmpp.org/extensions/xep-0166.html),
|
||
[XEP-0363](https://xmpp.org/extensions/xep-0363.html): fixture namespaces and
|
||
envelope/extension shapes. Shipped protocol comments identify older revisions;
|
||
a passing simple fixture does not establish complete current-XEP coverage.
|
||
|
||
## Consequences, limits and review
|
||
|
||
The spike is sufficient input for bounded selection review. Production still
|
||
requires S01 contracts and its own implementations/tests. The minimal transport
|
||
omits complete stream sequencing, error/close negotiation, redirect and keepalive
|
||
policies. Queue/rate/network-allocation bounds, worker/CPU performance, timeout,
|
||
full SASL extensions/final-challenge compatibility and constant-time verifier
|
||
assurance are not established. Library verifier uses string equality. Strict
|
||
success-only final layout and conservative send-race rejection reduce availability.
|
||
|
||
No Chrome/Firefox/Safari runtime execution, independent XMPP server/client,
|
||
real account, OMEMO encryption, production feature semantics, full browser matrix
|
||
or release readiness was verified. Browser-built code runs in Node with host web
|
||
APIs; socket injection adds fixture CA trust, not a browser channel-binding API.
|
||
Old accepted experiment source is unchanged; shared interfaces/specs/stack and
|
||
network/TLS/CORS policies remain unchanged. Any API incompatibility on upgrade
|
||
requires a new bounded decision, not a private patch or silent downgrade.
|
||
|
||
QA should reproduce clean install/build/tests and dependency checks, inspect the
|
||
stock defect controls, explicit extension projection and scope, then record an
|
||
independent decision. Evidence: `state/evidence/S00-003-auto-protocol-f474114f0168.md`.
|
||
Coordinator owns transition commits; independent acceptance is recorded below.
|
||
|
||
|
||
## Independent acceptance
|
||
|
||
QA reviewer auto-qa-d49749753ac6 accepts this exact-version library selection
|
||
with all three integration seams mandatory. Fresh-cache locked installation,
|
||
browser bundle and all 112 tests passed on reviewed Linux Node 24.21.0/npm
|
||
11.19.0; 51 locked entries, 26 installed package notices and 340 unchanged vendor
|
||
files verified. Lock, guard and bundle hashes match executor evidence. Additional
|
||
six offer permutations selected SHA-512; six adversarial XML documents rejected
|
||
before registry access and a valid body imported. make check passed 72 tooling
|
||
tests. Public shipped APIs, composed guard diff, fixture trust boundary and
|
||
extension projection were inspected. Report: `state/evidence/S00-003-review.md`.
|
||
Acceptance covers the bounded combined spike and selection only. All native
|
||
browser, independent server/client, OMEMO, aggregate resource, lifecycle,
|
||
timeout/timing and release limitations above remain. Stock Stanza without the
|
||
required seams is not accepted. Coordinator must commit the review transition
|
||
before any subsequent fresh task session.
|