Skip to content

engine: a saved session is used only by the edge and client that issued it - #1390

Draft
alexandre-vl wants to merge 1 commit into
zeronsh:zeron/zgxfrom
alexandre-vl:engine-session-issuer
Draft

alexandre-vl wants to merge 1 commit into
zeronsh:zeron/zgxfrom
alexandre-vl:engine-session-issuer

Conversation

@alexandre-vl

@alexandre-vl alexandre-vl commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • An engine loaded session.json whatever edge it was started with, and on its first refresh handed the session's refresh token to that edge.
    • Another edge can only turn it down, and a definitive refusal signs out, deleting the file.
    • So a single start with another ZERON_EDGE_URL lost a session that still worked where it came from.
    • Zeron 0.3.0's app started the engine with production's edge whatever the environment said, so it signed a self-hosting user out this way each time it started the engine on ~/.zeron. The app side is zgx: the app starts its engine against the edge ZERON_EDGE_URL names #1389.
  • A session now records the edge and WorkOS client that issued it.
    • An engine of another edge or client starts signed out, in local scope, and leaves the file as it is, logging a warning.
    • An engine of the issuing edge uses it, with or without a trailing slash on the URL.
    • A session from before carries no issuer and is taken as this engine's, as before, until its first successful refresh records the edge that took it.
  • Compatibility: the new fields edgeUrl and workosClientId are optional (#[serde(default)], skipped when unset), and no persisted key is renamed.
    • Old files load.
    • Older engines ignore the fields. If an older engine rewrites the file it drops them, and the next refresh here records them again.
  • Changed on purpose:
    • Starting with a different edge or client no longer presents the saved refresh token to it.
    • Signing in there still replaces the file, and zeron logout still removes it.
  • Credentials (please review closely): this narrows where a refresh token goes, to the edge that issued it, for every session signed in or refreshed after this change.

Test plan

  • cargo test --locked -p zeron-engine --test auth: 24 passed, three of them new:
    • a_session_another_edge_issued_is_left_as_it_is: another edge, and another client. The session is seeded with a refresh token this edge revokes. The test asserts the engine starts signed out, sends no /auth/refresh, and leaves the file byte-identical.
    • a_session_says_which_edge_and_client_issued_it: a headless sign-in records both, and an engine of that edge with a trailing slash in its URL loads the session.
    • a_session_from_before_learns_its_issuer_on_its_first_refresh.
    • All three fail against the engine without this change.
  • --test local_first (11), --test misc local_profiles (6), --lib auth:: (4): pass. They seed sessions without the new fields.
  • cargo clippy --locked -p zeron-engine --all-targets: nothing new. The two warnings in auth.rs and tests/auth.rs were already there.
  • Not run: the crates/ui tests that seed session.json (state.rs, shell.rs). Their sessions carry no issuer, which load as before.

…ed it

An engine loaded session.json whatever edge it was started with, and on
its first refresh handed the session's refresh token to that edge. One
another edge issued can only be turned down there, and a definitive
refusal signs out, deleting the file: a session that still worked where
it came from was lost to a single start with another ZERON_EDGE_URL.
Zeron 0.3.0's app, which started the engine with production's edge
whatever the environment said, signed a self-hosting user out that way
each time it started the engine on ~/.zeron.

A session now keeps the edge and WorkOS client that issued it (edgeUrl
and workosClientId, both optional: files from before still load, and
older engines ignore them). An engine of another edge or client starts
signed out and leaves the file as it is, saying why in its log; an
engine of that edge uses it, its URL written with a trailing slash or
not. A session from before says nothing and is taken as this engine's,
as before, until its first successful refresh records the edge that
took it. Signing in still replaces the file, and `zeron logout` still
removes it.

a_session_another_edge_issued_is_left_as_it_is,
a_session_says_which_edge_and_client_issued_it and
a_session_from_before_learns_its_issuer_on_its_first_refresh fail
without it.
@alexandre-vl

alexandre-vl commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor Author

The red checks come from zeron/zgx itself. This change touches only crates/engine/src/auth.rs and crates/engine/tests/auth.rs.

This branch has not been deployed

No deployments
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.

1 participant