Skip to content

auth: lock screen names the real sign-in failure; Add passkey excludes the account's own passkeys (#338) - #378

Open
irzhywau wants to merge 2 commits into
fix/rustls-0.23.46-advisoriesfrom
fix/338-account-error-hardening
Open

irzhywau wants to merge 2 commits into
fix/rustls-0.23.46-advisoriesfrom
fix/338-account-error-hardening

Conversation

@irzhywau

Copy link
Copy Markdown
Collaborator

Review follow-up to c359800 and 8e8ba68 (#338, shipped in the 0.8.0 train #372).

What changes

  • Sign-in reasons. Sign-in begin/complete answer with a typed reason instead of server text: removed_passkey, unknown_passkey, expired, refused, busy or home_error. The lock face gives each reason its own next step. Before this change, a removed passkey, an expired sign-in and a Home error all showed "Home did not accept this passkey". Home tells a passkey it removed from one it never knew. Without a reason, the lock face keeps the current stage rule.
  • Add passkey uses another authenticator. Home sends the account's own active passkeys as excludeCredentials, so the browser asks for another device or security key instead of a second passkey on the same keychain. Other accounts' passkeys stay private.
  • A busy Home keeps the fresh approval. Add begin creates the challenge first and then consumes the approval. A refused approval cancels its challenge.
  • The identity crate returns typed UnknownCredential and AuthenticationChallengeUnavailable errors with the same text as before.

Checks

  • cargo test -p elastos-identity: 61 passed. The Account: lock screen shows no errors, and an owner cannot add a second passkey #338 tests in elastos-server all pass (9; 4 new: sign-in reasons through the real handler, the classifier, the exclude list, approval order).
  • cargo clippy -p elastos-identity -p elastos-server --all-targets -- -D warnings: clean.
  • node --test capsules/home/browser/shell-auth.test.mjs scripts/system-passkey-add.test.mjs scripts/system-hosted-save.test.mjs: 42 passed. The new System test covers the owner-only button and the Home round trip (result, error, wrong sender, timeout).
  • The full elastos-server run on a Mac with 2 GB free disk was not conclusive: the model-preparation tests refuse on low space, and the custody journeys need the test binaries from the test script. CI gives the full result.

Remaining

Installed acceptance on a Home built from this branch: each lock-face failure, Add passkey on the same device (refused) and then on a phone or security key, and sign-in with the new passkey as admin.

@irzhywau irzhywau self-assigned this Oct 14, 2026
@irzhywau irzhywau linked an issue Oct 14, 2026 that may be closed by this pull request
2 tasks done
@andersalm

Copy link
Copy Markdown
Contributor

Review (Claude) PASS on 5479f9e: no P1/P2; the concurrent-removal guarantee from 8e8ba68 holds and the new reasons leak nothing beyond removed-vs-unknown for a caller who already holds the credential ID. P3: signature failures and detected clones now show 'Try again in a moment' (home_error).
Not in 0.8.0 (the RC is already built and under test); merge right after 0.8.0 publishes, once CI is green and Add passkey's exclude list is tried on a real device.

irzhywau added a commit that referenced this pull request Oct 14, 2026
… plain sentences (#338)

Review finding on #378: reportUnlockError showed error.message as is, so
the lock face could show "request failed: 403 Forbidden guest passkey
registration is disabled" or a browser DOMException text. The flows' own
sentences still pass through; browser errors, status codes and server
text become one plain sentence with one next step, as System's
publicSystemError does. Test drives the guest create flow through each
case.
…s the account's own passkeys (#338)

Review follow-up to c359800 and 8e8ba68:
- Sign-in begin/complete answer with a typed reason instead of server
  text: removed_passkey, unknown_passkey, expired, refused, busy or
  home_error. The identity crate returns typed UnknownCredential and
  AuthenticationChallengeUnavailable errors (same text), and Home tells a
  passkey it removed from one it never knew. The lock face words each
  reason with its own next step; without a reason it keeps the stage rule.
- Add passkey sends the account's own active credentials as
  excludeCredentials, so the browser asks for another device or security
  key. Other accounts' credentials stay private.
- Add begin creates the challenge before it consumes the fresh approval,
  so a busy Home keeps the approval; a refused approval cancels the
  challenge.
- Tests: sign-in reasons through the real handler, the classifier, the
  exclude list, approval order; lock-face copy for every reason,
  SecurityError, open and start; System's Add passkey button and Home
  round trip.
… plain sentences (#338)

Review finding on #378: reportUnlockError showed error.message as is, so
the lock face could show "request failed: 403 Forbidden guest passkey
registration is disabled" or a browser DOMException text. The flows' own
sentences still pass through; browser errors, status codes and server
text become one plain sentence with one next step, as System's
publicSystemError does. Test drives the guest create flow through each
case.
@irzhywau
irzhywau force-pushed the fix/338-account-error-hardening branch from efc11d9 to 66ba57b Compare October 14, 2026 13:59
@irzhywau
irzhywau changed the base branch from develop to fix/rustls-0.23.46-advisories October 14, 2026 13:59
@irzhywau

Copy link
Copy Markdown
Collaborator Author

Hardens #338: the lock face names the real sign-in failure, Add passkey excludes the account's own passkeys, and the add approval is used only after the challenge exists; 66ba57b fixes OMP review finding 1 (setup, guest and recovery failures are plain sentences).
Checks: the 9 #338 Rust tests, the behaviour suite (1630/1630) and the installed UI checks on an isolated Home pass.
Stacked on #380 (rustls 0.23.46; cargo-audit fails on every branch since RUSTSEC-2026-0346..0349 today); the test-capsules failure is the flaky journal lock in #381, re-run in progress.

@andersalm

Copy link
Copy Markdown
Contributor

Review (Codex, checked by OMP) at 66ba57b: request changes, for after 0.8.0.

  • P2 security: auth_gateway.rs:3719 maps UnknownCredential to removed_passkey_or(raw_id) before any signature check, so an unauthenticated caller with a credential ID learns whether this Home removed it; the test expects removed_passkey with an empty signature (auth_gateway.rs:10714). Require proof of possession first; unsigned requests get the generic refusal.
  • P2: refusals are classified by error-text fragments (auth_gateway.rs:690); a bad signature or missing user verification falls to a 500 and the lock screen says retry (shell-auth.js:996). Use typed errors and test them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants