Skip to content

Release 2.0.0 (source 7bc3704b5, package run 41375420248) - #375

Merged
andersalm merged 2162 commits into
mainfrom
develop
Nov 2, 2026
Merged

andersalm merged 2162 commits into
mainfrom
develop

Conversation

@andersalm

@andersalm andersalm commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

2.0.0 release PR from develop: source 7bc3704, the same commit as the 2.0.0-rc.2 RC, packaged by release-package.yml run 41375420248 (install_version=2.0.0-rc.2, update_version=2.0.0); 2.0.0 is signed from that run. Tag v2.0.0 goes on the source commit, not on the merge commit (release-publish.sh checked_tag: tag names the source, the source is on main, main's tree equals the source tree). Publication: #93.

@andersalm andersalm changed the title Release 0.8.0 Release 0.8.0 (source 75dcb4f8d, package run 38826038799) Oct 16, 2026
@andersalm andersalm added this to the 0.8.0 milestone Oct 16, 2026
@andersalm

Copy link
Copy Markdown
Contributor Author

Release review: the title and description still identify the earlier candidate, while this PR has advanced and a newer matching package run exists.
Refresh the single accepted source/build record before approval. Also reconcile the tag instructions: AGENTS names the merge commit, while VERSIONING and the publication gate require the source commit with an identical main tree.

@andersalm andersalm changed the title Release 0.8.0 (source 75dcb4f8d, package run 38826038799) Release 0.8.0 Oct 17, 2026

Copy link
Copy Markdown
Contributor

Independent pre-release review of #375 (head f346147), a second-reviewer pass against PRINCIPLES.md and AGENTS.md. These findings haven't been verified against the code yet, so please treat them as things to check, not confirmed bugs.

Sign-in after upgrade (C+)

  • Passkey sign-in now sends an empty allow-list, so non-discoverable passkeys enrolled before 0.8 (for example hardware keys) may be locked out after the upgrade. There's no migration, no fallback and no test.
  • A few IPs can fill the Home-wide sign-in, sign-up and owner-recovery challenge pools, and behind a proxy every caller shares one quota bucket.

Installer trust (C+)

  • install.sh uses sudo to copy the user-writable DATA_DIR/scripts/browser-vm-linux-network.py into a root location and runs it as root, with no hash check against the signed components.json.
  • The release provenance step runs the candidate Runtime binary on the same account that holds the signing key.

Docs (C-, one Critical)

  • After the key rotation, the re-trust instructions are curl | bash over the same channel, checked only against a maintainer DID that the script itself prints. The out-of-band --maintainer-did instructions were removed, and the old key isn't revoked.
  • AGENTS.md now allows security, installer and signing PRs to merge before human review.

Update and rollback (B-)

  • A normal rollback restores only the five journalled files, not the support binaries or migrated principal roots.
  • A crash between claim_start and record_started leaves a permanent "operator repair" state, and there's no repair tool.

Setup and process control (C+)

  • Shutdown doesn't stop runtime process groups it didn't spawn directly.
  • Legacy lstart records leave an upgrade dead end.
  • A fresh source-home setup fails.

Community membership on by default is intentional (Sash's 16 Oct decision), not a defect.

Posted at Sash's request.

@andersalm

Copy link
Copy Markdown
Contributor Author

@irzhywau, could you review this release PR when you have time this weekend? Anders asked for one human review before main moves (16 Oct).

The head is now the frozen 0.8.0 source, 63f57e341. The record is in #93 (comment 6230314205). The only code change since the last pushed train is the Community presence repair in d8ae49bf6..63f57e341 (#410). Claude and Codex reviews both passed on it. The rest of develop → main is the 0.8.0 train you have seen in its parts.

Merging still waits on the alpha.23 package, the installed checks and Anders's approval. Your review does not merge anything.

@andersalm

Copy link
Copy Markdown
Contributor Author

Dispositions for Sasha's pre-release review (comment 6230061841), checked against the current candidate source (release/train-0.8.0-rc8, not yet qualified). Items that wait until after 0.8.0 are collected in #434.

Sign-in after upgrade

  • Passkey empty allow-list: confirmed in code. No device test yet.
    • v0.7.1 registered with resident_key: "preferred" (elastos-identity/src/webauthn.rs:424) and signed in with an allow-list of the Home's credential IDs (:638).
    • The candidate signs in with an empty list (:672) and has no migration. The change is 0ead0bcc6 (1 Oct), which removed the anonymous credential-ID list.
    • A credential that a hardware security key stored as non-discoverable on 0.7.1 is never offered at the lock screen. Platform passkeys (iCloud Keychain, Google Password Manager, Windows Hello) are discoverable and unaffected.
    • Owners can register a new passkey with the Recovery Kit. Guests have no way back in.
    • Release decision pending (Anders, today): either block and add an account-named fallback that lists only that account's legacy credential, with Irzhy deciding the account-enumeration tradeoff; or ship a known-issue line and fix it in 0.8.1 (Follow-ups from Sasha's 0.8.0 pre-release review (#375) #434).
  • Challenge pools / shared proxy bucket: unverified; local-only exposure in 0.8.0. Moved to Follow-ups from Sasha's 0.8.0 pre-release review (#375) #434.

Installer trust

Docs

Update and rollback

  • Legacy lstart records: a live record from an older Runtime is kept rather than signalled (runtime_control/gateway_children.rs:356). Before the tag, OMP adds a 0.7.1 → alpha.23 re-install to the Linux installed checks to exercise this path.
  • Rollback scope, the claim/record crash window, shutdown process groups, fresh source-home setup: moved to Follow-ups from Sasha's 0.8.0 pre-release review (#375) #434, to be checked against the Undo journeys that passed.

Noted: Community membership on by default is Sasha's 16 Oct decision.

@andersalm

Copy link
Copy Markdown
Contributor Author

Passkey upgrade lockout: the recommendation is reversed. The devil's-advocate check returned MODIFY: shipping the lockout is not defensible. My earlier "known issue" recommendation was wrong.

What changed:

  • Google documents that Android Password Manager can create non-discoverable credentials, so this is not only hardware keys.
  • Owner recovery depends on conditions: it needs a matching admin root and a kit with a signed Profile (auth.rs:1492, shell-auth.js:661).
  • StoredCredential (store.rs:25) records neither registration time nor discoverability, so legacy credentials cannot be singled out.

Prepared, unpushed and not yet decided: branch fix/080-passkey-named-fallback, base cd620ab5a.

  1. The anonymous lock-screen sign-in keeps its empty allow-list.
  2. A secondary "sign in with your account name" action asks the server for a challenge that lists only that account's stored credential IDs. Finish verifies that the credential belongs to the named account.
  3. An unknown name gets deterministic decoy IDs from a per-Home HMAC secret, with the same response shape and the same rate limits. Callers cannot tell which accounts exist without an actual authenticator ceremony.
  4. After a fallback sign-in, a one-time prompt offers to add a discoverable passkey.

Decisions needed:

@andersalm

andersalm commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor Author

The prepared named fallback remains subject to the disclosure policy in W3C username-enumeration guidance and credential-ID privacy. Narrow independent source review at c9cfb60 / tree 73e462878de8b035038202d1ef9cfcad85961e26 confirms the completed owner-commissioned Codex FAIL: decoys use 16/20/32/64-byte IDs, registration accepts 1–1024 bytes, real IDs are sorted and decoys retain generation order. The claim that account existence becomes visible only after a completed ceremony exceeds this implementation.
Use the same ordering policy for both responses, define and test count/decoded-length/transport and ineligible-account behavior, and state residual ID disclosure for the required security decision. Preserve one-use ceremony binding to the resolved principal set, eligible IDs and RP/origin before session grant. A named assertion may omit userHandle; a supplied value must match its credential owner. Keep private key material within the existing protected derivation and define restart/restore behavior.
The owner now reports a remote Rust gate on f1b197f and a virtual non-discoverable credential that fails anonymous sign-in and succeeds by name; these are scoped owner results. The System Add passkey offer failed to appear, and add-discoverable→anonymous sign-in, physical-device compatibility and exact installed upgrade acceptance remain open. Claude review, irzhywau's security disposition and Anders's release-inclusion decision are still required; this comment is a narrow source qualification rather than a full implementation verdict.

@andersalm

Copy link
Copy Markdown
Contributor Author

Passkey fallback prepared (unpushed): branch fix/080-passkey-named-fallback, commits 724935881, be62e112e, a2bfe804c, f1b197f65, c9cfb605b on cd620ab5a.

  • Remote gate (linux/amd64) on f1b197f65: fmt, workspace check, clippy and tests pass (elastos-server 2984 passed, elastos-identity 66 passed).
  • Virtual-authenticator smoke: a credential registered the v0.7.1 way is stored as non-discoverable, and the anonymous lock screen cannot find it; this reproduces the lockout. An unknown name gets stable decoys. The account name signs in with exactly that one credential.
  • Not shown: the one-time System "Add passkey" offer did not appear in the minimal test Home. No real security key, Android, Safari or Firefox was tested. Guests cannot add a passkey (admin-only, Account: lock screen shows no errors, and an owner cannot add a second passkey #338), so a guest with an old non-discoverable passkey uses the fallback every time.
  • What a caller can still learn: a known name returns that account's real credential IDs; an account with 3 or more passkeys differs from a decoy (decoys have 1–2 IDs). The anonymous ID leak stays closed.
  • Next: Codex and Claude reviews are running. Then @irzhywau decides on the enumeration tradeoff, and Anders decides whether this ships in the 0.8.0 batch with Chat and app web links require Home confirmation of the exact destination (0.8.0 F1 gate) #430.

@andersalm

Copy link
Copy Markdown
Contributor Author

Reviews of the passkey fallback (c9cfb605b): Codex and Claude both FAIL; the fixes are in progress on the same branch.

  • Codex: decoys can be told apart. Real IDs come back sorted and decoys do not, and decoy lengths are limited to 16, 20, 32 or 64 bytes while real IDs can be 1 to 1024 bytes. So the code's claim that existence is learned only through a real ceremony is false.
  • Claude B1: the anonymous complete step answers an unknown credential and a known one with different statuses and bodies. That turns any named-begin answer into an account-existence check without an authenticator. Fix: one identical failure for every non-capacity error.
  • Claude B2: a named sign-in switched the person's saved shell to Desktop. Fix: no shell change; show the offer only to admins already on Desktop.
  • Disclosure, for @irzhywau: after these fixes, a caller who guesses an account name learns whether it has passkeys and receives their credential IDs, as every caller did in 0.7.1. Decoys only stop casual enumeration of unknown names. Is that acceptable for 0.8.0?
  • Link flow (Chat and app web links require Home confirmation of the exact destination (0.8.0 F1 gate) #430): fix/080-link-confirm at fdb9d6302 passed both reviews (Codex and Claude) and is ready to integrate.

andersalm added a commit that referenced this pull request Oct 17, 2026
…s the browser cannot discover sign in by account name; one uniform sign-in failure) (#375, #434)
@andersalm

Copy link
Copy Markdown
Contributor Author

Decision (Anders asked OMP to decide without waiting for Irzhy, checked by devil's advocate): the account-named passkey fallback ships in 0.8.0, on three conditions.

The devil's-advocate verdict was MODIFY. It rejects shipping only a known-issue line, and prefers holding the release over publishing an unqualified authentication change.

Why ship it:

  • Without the fallback, some 0.7.1 users cannot sign in after the upgrade. That includes non-discoverable credentials on some hardware security keys and, per Google, Android Password Manager. Owner recovery depends on conditions, and guests have none.
  • Shipping a known lockout breaks "nothing broken ships".
  • The fallback is Runtime-owned. It keeps the anonymous sign-in empty, gives one uniform failure, and passed review (Codex).

Conditions:

  1. Installed proof before 0.8.0. On installed alpha.23:
    • a 0.7.1 Home whose passkey is non-discoverable (virtual authenticator with hasResidentKey:false, on Linux) is re-installed to alpha.23;
    • the anonymous lock screen does not offer it;
    • "Use a security key or another device" plus the account name signs in, and an unknown name fails the same way as a missing passkey.
    • A physical security key is tested too, if one is available.
      If this fails, 0.8.0 waits.
  2. Accepted 0.8.0 disclosure limit:
    • What a caller learns: anyone who can reach Home's sign-in route and guesses an account name learns whether that account has passkeys, and receives their credential IDs. They also get timing and count hints (decoys stop at 2).
    • Who can reach the route:
      • by default, only callers on the same machine: Home binds 127.0.0.1:8090, and sign-in routes refuse other websites' Origin;
      • other OS users on the same machine can forge an Origin;
      • operators who set gateway_allowed_hosts or put a proxy in front of Home expose the route further.
    • Credential IDs are identifiers, not secrets. Signing in still requires the passkey.
    • 0.7.1 disclosed every ID to every caller.
  3. Re-evaluate before any remote, LAN or HTTPS Home access ships (Follow-ups from Sasha's 0.8.0 pre-release review (#375) #434). Options then: account-first sign-in with stronger rate limits, or removing the fallback once 0.7.1 credentials are migrated.

Release notes already tell 0.7.1 users how to sign in by account name.

@andersalm

Copy link
Copy Markdown
Contributor Author

Superseded: the account-named passkey fallback does NOT ship in 0.8.0. This replaces decision comment 6241283502.

That decision rested on "some 0.7.1 users would be locked out". Anders: ElastOS has not gone public; the only 0.7.1 accounts are his own test users. So the premise was wrong. Without real users the fallback is unused migration code. It adds an unauthenticated route, lock-screen and System UI, a key derived from device.key, and a disclosure limit. "Subtract before you add" removes it. The devil's-advocate check returned MODIFY: remove it, keep the branch, and state plainly what happens to test accounts.

Done:

Test accounts: if a 0.7.1 test account's passkey is not offered after the upgrade, the owner re-registers a passkey with the Recovery Kit, or the test Home is re-created. If an identity must be kept and cannot be recovered, Anders decides.

The CI and package runs on 8ea4aac96 are cancelled as superseded. A new gated push, musl precheck and a23-qualify.sh (which stops before any seed step) are running on d495a8058.

@andersalm

Copy link
Copy Markdown
Contributor Author

For 0.8.0, Anders took over Irzhy's review (relayed by grook at 13:28 COT, 17 Oct; Irzhy is unavailable over his weekend night). With the passkey fallback out of 0.8.0 (comment 6241518094), the decoy and enumeration question does not arise for this release. Irzhy's review is not a 0.8.0 gate. Sasha remains the final go, and signing and merge to main stay with Anders.

andersalm added a commit that referenced this pull request Oct 18, 2026
… passkeys the browser cannot discover sign in by account name; one uniform sign-in failure) (#375, #434)"

This reverts commit 31c3c62, reversing
changes made to 6eb69b2.
@andersalm

Copy link
Copy Markdown
Contributor Author

Anders's review of #375 for alpha.23 / bfefe92f619f48468b117dad957659862917e166, relayed by grook from Anders's chat at 10:06 COT, 18 Oct: "i dont want to click. can codex or omp handle it?" His decision is that his recorded takeover of Irzhy's review for 0.8.0 (comment 6242353258) is his review of #375 for alpha.23 / bfefe92f6, and he approves it. He does not want to click Approve or post on GitHub himself.

On GitHub mechanics: this PR is opened under Anders's account, and GitHub does not let a PR author approve their own PR. A formal approving review therefore has to come from another account, or an admin decides the protection rule, when #375 is merged into main for 0.8.0. That is later; it does not affect alpha.23 canary.

…ed profiles alone, reap terminal test children; quote the channel hint
…rofiles untouched, terminal test cleanup, quoted channel hint
…ys as in rc.1; below DATA sticky is still refused
… and a same-folder rename, so a link swapped in after admission is replaced, never followed
…e it only through its descriptor; no open or chmod by name in the profile flow
… of this user's single-name regular file; never replace it
…a short write; uninstall never edits a profile and names the line to delete
…e profile may end in part of the line and how to fix it
… checked file, never replaced; uninstall names the line to delete
… as uncertain, with the exact last line to check
… it owned and not writable by others, not exactly 0600
…rson's umask; private records stay exactly 0600
…out admitting the gateway's lock as an offline upgrade lock
… worker (stored gzip, not the host's deflate)

macOS 15 runners (Apple libz) and Linux (zlib 1.3) compress the same tar
differently; release prepare refuses differing universal assets
(conflicting universal asset: artifacts/archive-manager.tar.gz on
package run 41360883298, 33 archives, inner tars identical). The gzip
member is now written with stored deflate blocks. About 9 MB more per
setup download. Test pins the digest; it matches on macOS and Linux.
…coding (stored gzip from rc.2, host deflate before) and keep the one its signed descriptor names
@andersalm andersalm changed the title Release 0.8.0 Release 2.0.0 (source 7bc3704b5, package run 41375420248) Nov 2, 2026
@andersalm
andersalm merged commit 0d53e56 into main Nov 2, 2026
53 of 61 checks passed
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