Skip to content

feat(nexus): remove personal API keys, sign in with OAuth only - #7

Open
MotherSphere wants to merge 2 commits into
mainfrom
feat/nexus-oauth-only
Open

feat(nexus): remove personal API keys, sign in with OAuth only#7
MotherSphere wants to merge 2 commits into
mainfrom
feat/nexus-oauth-only

Conversation

@MotherSphere

Copy link
Copy Markdown
Member

For Nexus review. Not to be merged until a client_id is issued - see below.

Nexus's API team requires all personal-API-key usage removed from the client before issuing a client_id, including as a fallback, and asked to see a build without it.

What was removed

  • Credential is a single variant. There is no APIKEY header path.
  • choose_credential is Bearer / refresh / nothing. A lapsed session that cannot be renewed now reports itself instead of falling back to a key.
  • NexusCreds has no api_key field; nexus.ini no longer writes one.
  • The eidos nexus key CLI command is gone.
  • The Settings dialog has no field to type a key into.
  • The token endpoint may still return api_key beside the tokens. It is no longer parsed - a key kept "just in case" is exactly what the requirement rules out.

An api_key= line left in a user's nexus.ini by an older version is passed through untouched rather than rewritten away. Not reading it is the requirement; deleting someone's file is not.

What was added

The OAuth flow existed as a library and had never been wired to a user action, because there was no client_id to test it with. Removing the key without wiring it would have produced a build with no way to authenticate at all, which demonstrates nothing.

Settings -> Nexus now runs the whole flow: PKCE S256 challenge, browser hand-off, loopback listener on 127.0.0.1 only, code exchange, session stored in nexus.ini. Sign out sits beside it.

The consequence, stated plainly

Eidos ships no default client_id and will not fall back to identifying itself as another application. With personal keys gone and no client_id issued, this build has no Nexus access at all. That is the intended state rather than an oversight, and the error messages say so.

The moment a client_id is issued, this becomes the shipped version.

615 tests green, clippy clean under CI's exact command.

Nexus's API team will not issue a client_id while the client can use a personal
API key, even as a fallback: those keys are documented on their side as being for
testing and personal use, not for a distributed application. They asked to see a
build without any such usage.

So it is gone, not disabled. `Credential` is one variant. `choose_credential` is
Bearer, or refresh, or nothing - a lapsed session with no renewable token now
reports itself instead of reaching for a key. `NexusCreds` has no `api_key`
field, `nexus.ini` no longer writes one, the `eidos nexus key` command is gone,
and the Settings dialog has no field to type one into. The token endpoint may
still return `api_key` alongside the tokens; it is no longer parsed, because a
key kept "just in case" is exactly what the requirement rules out.

The OAuth flow existed as a library and had never been wired to a user action -
there was no client_id to test it with, so nothing called it. Removing the key
without wiring it would have produced a build with no way to authenticate at all,
which demonstrates nothing. Settings -> Nexus now runs the whole dance: PKCE S256
challenge, browser hand-off, loopback listener on 127.0.0.1, code exchange, session
stored. Sign out is beside it.

An `api_key=` line left in someone's nexus.ini by an older version is passed
through untouched rather than rewritten away - not reading it is the requirement,
deleting a user's file is not.

Eidos therefore has no Nexus access at all until Nexus issues a client_id. That is
the intended state, and the error messages say so rather than failing vaguely.

615 tests green, clippy clean.
The request path no longer sends one; the comment beside it still said it did.
MotherSphere added a commit that referenced this pull request Aug 4, 2026
main.rs was 2493 lines - every subcommand, the whole launch pipeline and the
profile staging in one file. Pure moves, routed by item name:

  main.rs      274   dispatch, usage, and the Nexus commands
  launch.rs    481   eidos play: extender swap, mount, run, capture
  prepare.rs   470   staging the profile into the prefix, and reading it back
  tools.rs     281   eidos tool
  tests.rs     275   the unit tests, file-backed
  prereqs.rs   218   eidos prereqs
  nxm.rs       157   the nxm:// handler
  sort.rs      148   eidos sort (LOOT)
  install.rs   134   eidos install / import
  export.rs    123   eidos export
  games.rs      50   eidos games / init

The Nexus trio (cmd_nexus, nexus_client, nexus_key_path) deliberately stays in
main.rs: PR #7 rewrites exactly those functions, and moving them now would turn
a pending review branch into a wall-to-wall conflict. They move once #7 lands.

Verified as the fuse split was: item inventory identical (the nine additions are
the test module's own fns and its Tmp helper surfacing to file level), workspace
suite green, and the split binary smoke-run against the real machine.
MotherSphere added a commit that referenced this pull request Aug 4, 2026
…od (#12)

profile.rs was one 800-line impl Profile plus its satellites. The unit of the
move is the METHOD here - Rust allows inherent impls across files, so each
concern gets its own impl Profile block beside the free items it owns:

  profile.rs    91   Profile and SaveEntry themselves, the path roots
  modlist.rs   385   modlist.txt round-trip, ListTrust, lifecycle
  plugins.rs   350   plugins.txt, the locked order, snapshot + loss guard
  inis.rs      327   seeding, deploy, capture, the reversible tweaks
  saves.rs     236   enumeration, co-saves, crash-artifact detection
  tests.rs     889   the unit tests, file-backed

settings.rs deliberately untouched: PR #7 and PR #8 both edit it, and a move
now would conflict with both.

Verified at the level the cut happened: 89 functions before, 89 after, none
lost and none invented. Workspace suite green, clippy clean.
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