Priority: P3 (Low) · Security audit finding · area: docs/trust-model
Finding
SECURITY.md and the actual code disagree on the WebAuthn RP ID, and the doc describes a wider (weaker) trust boundary than the code enforces. For a project whose README says of SECURITY.md "that document is not an afterthought, it is the project", a stale claim about the owner-key trust root is worth correcting.
SECURITY.md § Live deployment operations currently says:
Keep the WebAuthn RP ID boundary small and intentional. The browser code currently uses sourceful-labs.net as the RP ID so passkeys work across subdomains. That means any trusted web origin under sourceful-labs.net capable of running Miranda client code is inside the owner-key trust boundary.
The code does the opposite, and correctly so. web/src/rp.js:
export const PRODUCTION_RP_ID = 'term.sourceful-labs.net';
export function resolveRPID(hostname) {
return hostname === 'localhost' ? 'localhost' : PRODUCTION_RP_ID;
}
web/src/identity.js uses resolveRPID(location.hostname) for both register and signIn, with the comment "Do not use the parent domain as the RP trust root."
So the production RP ID is scoped to the exact app host term.sourceful-labs.net, not the registrable parent sourceful-labs.net. A passkey bound to term.sourceful-labs.net cannot be exercised by any sibling subdomain. That is the stronger, correct posture, and the doc undersells it.
This is also internally inconsistent inside SECURITY.md: the What you have to trust section already names "the browser JavaScript served by term.sourceful-labs.net" as the trust root, while the RP-ID bullet contradicts it with sourceful-labs.net.
Why it matters
The RP-ID claim isn't cosmetic. As written, the doc tells a reader/operator that hosting Miranda client code on any *.sourceful-labs.net subdomain puts it inside the owner-key trust boundary. That would be true under a parent-domain RP ID, but it is not how the code is configured, so the guidance is both wrong and risk-inflating. Someone trusting the doc might also "fix" the code to match (widen the RP ID), which would be a real regression.
Suggested fix
Update the § Live deployment operations RP-ID bullet to describe the host-scoped RP ID actually in use:
- RP ID =
term.sourceful-labs.net (the exact app host), so passkeys are bound to that single origin and sibling subdomains are outside the owner-key trust boundary.
- Keep the operational guidance ("do not host untrusted JS that runs Miranda client code on this origin"), now scoped to the one host rather than the whole registrable domain.
No code change required: the code is already correct. This is a doc-vs-code correction so the falsifiable model in SECURITY.md matches the binary.
Context
Re-audit of the productified srcfl/miranda (was frahlg/terminal-relay). The three transport-layer findings from the prior pass (#1 cleartext-http trust root, #2 missing CSP, #3 timeouts/rate-limit) are all resolved here: HTTPS-on-origin support, nonce-based CSP + locally-vendored crypto, ReadHeaderTimeout + capacity caps. Crypto core (Noise KK, pinned keys, P2P data plane) is unchanged and sound; go test ./... is green and -race clean; govulncheck finds nothing reachable. This RP-ID doc drift is the one item not already covered by the open security PRs (#11-#18) and issues (#19-#21).
Priority: P3 (Low) · Security audit finding · area: docs/trust-model
Finding
SECURITY.mdand the actual code disagree on the WebAuthn RP ID, and the doc describes a wider (weaker) trust boundary than the code enforces. For a project whose README says ofSECURITY.md"that document is not an afterthought, it is the project", a stale claim about the owner-key trust root is worth correcting.SECURITY.md§ Live deployment operations currently says:The code does the opposite, and correctly so.
web/src/rp.js:web/src/identity.jsusesresolveRPID(location.hostname)for bothregisterandsignIn, with the comment "Do not use the parent domain as the RP trust root."So the production RP ID is scoped to the exact app host
term.sourceful-labs.net, not the registrable parentsourceful-labs.net. A passkey bound toterm.sourceful-labs.netcannot be exercised by any sibling subdomain. That is the stronger, correct posture, and the doc undersells it.This is also internally inconsistent inside
SECURITY.md: the What you have to trust section already names "the browser JavaScript served byterm.sourceful-labs.net" as the trust root, while the RP-ID bullet contradicts it withsourceful-labs.net.Why it matters
The RP-ID claim isn't cosmetic. As written, the doc tells a reader/operator that hosting Miranda client code on any
*.sourceful-labs.netsubdomain puts it inside the owner-key trust boundary. That would be true under a parent-domain RP ID, but it is not how the code is configured, so the guidance is both wrong and risk-inflating. Someone trusting the doc might also "fix" the code to match (widen the RP ID), which would be a real regression.Suggested fix
Update the § Live deployment operations RP-ID bullet to describe the host-scoped RP ID actually in use:
term.sourceful-labs.net(the exact app host), so passkeys are bound to that single origin and sibling subdomains are outside the owner-key trust boundary.No code change required: the code is already correct. This is a doc-vs-code correction so the falsifiable model in
SECURITY.mdmatches the binary.Context
Re-audit of the productified
srcfl/miranda(wasfrahlg/terminal-relay). The three transport-layer findings from the prior pass (#1 cleartext-http trust root, #2 missing CSP, #3 timeouts/rate-limit) are all resolved here: HTTPS-on-origin support, nonce-based CSP + locally-vendored crypto,ReadHeaderTimeout+ capacity caps. Crypto core (Noise KK, pinned keys, P2P data plane) is unchanged and sound;go test ./...is green and-raceclean;govulncheckfinds nothing reachable. This RP-ID doc drift is the one item not already covered by the open security PRs (#11-#18) and issues (#19-#21).