inspector/core/auth
Repository files (latest commit first)
Filename Latest commit message Latest commit date
cliffhall 04dbc36544 feat(auth): give the secrets file a real cross-process lock (#2082)
#1950 shipped FileSecretStore without cross-process mutual exclusion, by
decision: an earlier revision hand-rolled a `mkdir` election with an owner
stamp, a heartbeat and a stale-takeover, and three consecutive review rounds
found a real race in it. The last one is not closable with what Node exposes
— claiming a stale lock atomically needs compare-and-swap on a directory
entry (`renameat2(RENAME_EXCHANGE)`) — so it was replaced with optimistic
verify-and-retry and the residual documented.

#2082 settles that as "borrow, don't hand-roll". `proper-lockfile` is what
npm itself locks with, and stale-takeover is precisely the problem it has
already solved: it re-stats the lock directory after claiming it and gives
the lock up when the mtime is not the one it wrote, so the loser of a
takeover race releases instead of proceeding.

- core/auth/node/file-lock.ts: `withSecretFileLock`. `realpath: false` so a
  file can be locked into existence (the very first `set` has no
  `secrets.json`, and the library's default resolves through `fs.realpath`);
  a warning in place of the library's `onCompromised`, which throws from a
  timer and would take the session down; and a degrade-with-one-warning path
  rather than a throw when no lock can be taken — this store exists for boxes
  missing the usual mechanism (#1848, #1905) and must not gain a new way to
  be unavailable.
- FileSecretStore.mutate holds it across the whole read-modify-write. The
  optimistic verify stays underneath and is not redundant: a lock is advisory
  between the processes that take it, so the verify covers a writer outside
  this codebase and covers the degrade path. The in-process queue stays too,
  and gains a second job — proper-lockfile is not reentrant, so serializing
  per path keeps ELOCKED meaning "another process".
- absorbFileSecretsIntoKeyring takes the same lock around orphan adoption and
  the atomic claim, behind a lock-free `readdir` fast path so the common
  startup (keychain available, no file ever written) neither creates a lock
  directory nor warns about one it could not create.

proper-lockfile is a root `dependency` per the placement rule, and is named
in all three bundler `external` lists: tsup externalizes what the *client's*
manifest declares, so a root-only CJS package was being inlined into the ESM
bundles, leaving esbuild's `Dynamic require of "path" is not supported` shim
that killed `--cli` at import time. That rule was undocumented; it is now in
AGENTS.md beside the placement rule that creates it, and mirrored into
.github/copilot-instructions.md.

Tests: 7 new in file-lock.test.ts driving a real second process (the existing
suite structurally cannot — `serialize` orders in-process callers before the
lock sees them), plus two for the migration fast path.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JTHVxSu8AUgHRLvo1ntZ8H
Signed-off-by: cliffhall <cliff@futurescale.com>
2026-08-23 09:32:41 -04:00
..
browser Removed Zustand storage, cleanup up auth storage IO interfaces, implementations, and usage. 2026-07-04 21:56:45 -07:00
ema feat: per-server custom OAuth authorization-request parameters (#2018) 2026-08-15 19:31:41 -04:00
node feat(auth): give the secrets file a real cross-process lock (#2082) 2026-08-23 09:32:41 -04:00
remote Removed Zustand storage, cleanup up auth storage IO interfaces, implementations, and usage. 2026-07-04 21:56:45 -07:00
authorizationParams.ts feat: per-server custom OAuth authorization-request parameters (#2018) 2026-08-15 19:31:41 -04:00
challenge.ts fix(core): start OAuth on a modern/auto-era connect (#1805) (#1809) 2026-07-27 15:06:01 -04:00
cimd.ts Address @claude review: format core/, typed output-validation error, document progress heuristic 2026-07-15 11:08:54 -04:00
connection-state.ts Address @claude review: format core/, typed output-validation error, document progress heuristic 2026-07-15 11:08:54 -04:00
discovery.ts chore(deps): migrate to eslint 10 to clear the brace-expansion DoS advisory (#1900) 2026-08-01 20:13:30 -04:00
endpointOverrides.ts perf(auth): gate the override wrapper on the discovery request, and guard disk values 2026-08-16 22:11:16 -04:00
index.ts feat(auth): per-server authorization and token URL overrides 2026-08-16 20:36:24 -04:00
issuerBinding.ts fix(auth): explicit re-authorize when the OAuth callback state was lost (#1808) (#1810) 2026-07-27 18:08:31 -04:00
mcpAuth.ts OAuth: re-key store to (server, issuer) + SEP-837/2350/2352 auth UX (#1694) 2026-07-16 16:52:53 -04:00
oauth-persist.ts fix(auth): keep oauth-persist browser-safe (move Node file backend out) 2026-07-08 16:20:31 -04:00
oauth-storage.ts OAuth: re-key store to (server, issuer) + SEP-837/2350/2352 auth UX (#1694) 2026-07-16 16:52:53 -04:00
oauthUx.ts fix(auth): explicit re-authorize when the OAuth callback state was lost (#1808) (#1810) 2026-07-27 18:08:31 -04:00
providers.ts feat: per-server custom OAuth authorization-request parameters (#2018) 2026-08-15 19:31:41 -04:00
scopes.ts Auth hardening CI gaps + SDK consolidation: EMA leg 2 / scopes (#1527) (#1725) 2026-07-19 22:36:21 -04:00
secret-fields.ts feat(web,core): enterprise-managed authorization (EMA) (#1509) (#1512) 2026-06-24 22:15:12 -04:00
secret-storage-info.ts fix(auth): stop a config-only PUT deleting stored secrets (#2084) 2026-08-22 23:30:17 -04:00
storage.ts OAuth: re-key store to (server, issuer) + SEP-837/2350/2352 auth UX (#1694) 2026-07-16 16:52:53 -04:00
store.ts OAuth: re-key store to (server, issuer) + SEP-837/2350/2352 auth UX (#1694) 2026-07-16 16:52:53 -04:00
types.ts OAuth: re-key store to (server, issuer) + SEP-837/2350/2352 auth UX (#1694) 2026-07-16 16:52:53 -04:00
utils.ts chore(deps): migrate to eslint 10 to clear the brace-expansion DoS advisory (#1900) 2026-08-01 20:13:30 -04:00