Files
LumaWeb/docs/decisions/0002-xmpp-library.md
T
wt 8f918bc040 S00-003: Approve bounded XMPP selection after independent WSS and SCRAM checks
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 библиотеку
2026-10-15 18:26:01 +07:00

146 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.