Skip to content

harden(account): packaged builds ignore development Clerk config#851

Merged
arul28 merged 7 commits into
mainfrom
harden/packaged-clerk-overrides
Jul 17, 2026
Merged

harden(account): packaged builds ignore development Clerk config#851
arul28 merged 7 commits into
mainfrom
harden/packaged-clerk-overrides

Conversation

@arul28

@arul28 arul28 commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Why

A developer's ADE project that sets CLERK_ISSUER / CLERK_JWKS_URL / CLERK_OAUTH_CLIENT_ID (or ADE_ACCOUNT_DIRECTORY_URL) to ADE's development Clerk instance (*.clerk.accounts.dev) leaked into the packaged production desktop app's brain. The app then authenticated against dev Clerk, got a dev token, and the production account directory returned HTTP 401: invalid token — the Mac couldn't publish to the account directory ("Your Macs" empty). Normal users never hit this (no overrides → production defaults); it's a developer-machine footgun.

What

Packaged builds set ADE_RUNTIME_PACKAGED=1 (ade-cli bootstrap.ts via a directory-based source-checkout check; desktop main.ts via app.isPackaged). When set, the account resolvers discard any Clerk override that resolves to a development instance (*.clerk.accounts.dev, incl. trailing-dot aliases, or the dev account-directory host) and atomically snap issuer + JWKS + client + directory back to the built-in production defaults — never a hybrid — logging one warning. The machine publisher's directory override and the directory service's raw-env fallback are guarded the same way.

  • Source-checkout/dev builds are unchanged — they still honor dev Clerk.
  • ADE_ALLOW_DEVELOPMENT_CLERK=1 is a deliberate escape hatch.
  • Non-development custom issuer overrides are still honored (only dev instances are rejected).

Tests

New/extended coverage in sharedAccountAuthService.test.ts, accountBridge.trust.test.ts, accountMachinePublisherService.test.ts, accountMachineDirectoryService.test.ts, bootstrap.test.ts: packaged+dev→prod (atomic), not-packaged+dev→dev, escape hatch, custom-prod-issuer honored, dev-JWKS-behind-prod-issuer→prod, dev-directory-override→prod, and packaged-detection classification for dev bundles vs ADE.app resources.

Independently reviewed (found + fixed a fail-closed packaged-detection regression before push). Desktop/ade-cli only — no iOS surface.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Packaged CLI and desktop builds now default to official hosted account/auth/attestation settings, ignoring development Clerk and development account-directory overrides unless explicitly allowed.
    • Added safeguards to prevent development directory/auth material from being used in packaged runtimes, including rejection of development-credential tokens and safer session invalidation.
    • Desktop and CLI runtime now consistently enforce packaged mode behavior at startup.
  • Tests

    • Expanded packaged-vs-non-packaged test coverage for directory routing, OAuth/attestation precedence, account publishing behavior, and authentication/session policies.

Greptile Summary

This PR hardens packaged account configuration so development Clerk and account-directory overrides do not leak into production desktop or CLI builds. The main changes are:

  • Packaged CLI and desktop runtimes set ADE_RUNTIME_PACKAGED at startup.
  • Account OAuth, JWKS, device-login, stored-session, and ADE_ACCOUNT_TOKEN paths reject development Clerk material unless ADE_ALLOW_DEVELOPMENT_CLERK=1 is set.
  • Machine directory listing, deletion, and publisher requests fall back to the production account directory when packaged builds see development directory overrides.
  • Shared tests cover packaged fallback, source-checkout behavior, escape hatch behavior, custom production issuers, and atomic production defaults.

Confidence Score: 5/5

Safe to merge with low risk.

The changed paths are focused on packaged account configuration and include tests for fallback, escape hatch, custom issuer, session invalidation, and directory routing behavior. No current functional or security bugs were identified.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • The CLI proof artifact was produced, showing the command, working directory, full Vitest output, pass and skipped counts, and EXIT_CODE: 0.
  • The Desktop proof artifact was produced, showing the command, working directory, full Vitest output, pass counts, a packaged-development directory override warning, and EXIT_CODE: 0.
  • The targeted tests were evaluated against the PR objectives, confirming coverage of packaged runtimes snapping development Clerk/account-directory overrides to production defaults, non-packaged and escape-hatch behavior, custom production issuer handling, development JWKS/directory hardening, and packaged detection classification.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
apps/ade-cli/src/bootstrap.ts Sets ADE_RUNTIME_PACKAGED for non-source-checkout CLI runtimes using the shared packaging classifier.
apps/ade-cli/src/services/account/accountAuthService.ts Rejects development Clerk session material and directory overrides in packaged account auth flows while preserving production and custom configurations.
apps/ade-cli/src/services/account/accountMachineDirectoryService.ts Guards account machine list and delete directory overrides so packaged builds do not send tokens to the development directory.
apps/ade-cli/src/services/account/accountMachinePublisherService.ts Routes packaged machine registration publishing through production when explicit or resolved directory inputs point at development.
apps/ade-cli/src/services/account/sharedAccountAuthService.ts Centralizes packaged-mode enforcement for OAuth, attestation, and account-directory configuration resolution.
apps/desktop/src/main/main.ts Marks packaged Electron main processes with ADE_RUNTIME_PACKAGED before account services initialize.
apps/desktop/src/main/services/account/accountBridge.ts Reflects packaged development-config rejection in desktop login configuration and directory base URL resolution.
apps/desktop/src/shared/accountDirectory.ts Adds shared defaults and predicates for detecting development Clerk issuers, client IDs, and directory hosts.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Runtime as Packaged CLI/Desktop
participant Env as Env/Project Secrets
participant Resolver as Account Config Resolvers
participant Auth as Account Auth Service
participant Directory as Account Directory

Runtime->>Env: "set ADE_RUNTIME_PACKAGED=1"
Env->>Resolver: "provide CLERK_* / ADE_ACCOUNT_DIRECTORY_URL"
Resolver->>Resolver: detect development Clerk or dev directory
alt development config and no escape hatch
    Resolver-->>Auth: production issuer, JWKS, client, directory
    Auth->>Auth: reject stored/env development session material
    Auth->>Directory: use production directory with production token
else "source checkout or ADE_ALLOW_DEVELOPMENT_CLERK=1"
    Resolver-->>Auth: honor configured development/custom values
    Auth->>Directory: use configured trusted directory
end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Runtime as Packaged CLI/Desktop
participant Env as Env/Project Secrets
participant Resolver as Account Config Resolvers
participant Auth as Account Auth Service
participant Directory as Account Directory

Runtime->>Env: "set ADE_RUNTIME_PACKAGED=1"
Env->>Resolver: "provide CLERK_* / ADE_ACCOUNT_DIRECTORY_URL"
Resolver->>Resolver: detect development Clerk or dev directory
alt development config and no escape hatch
    Resolver-->>Auth: production issuer, JWKS, client, directory
    Auth->>Auth: reject stored/env development session material
    Auth->>Directory: use production directory with production token
else "source checkout or ADE_ALLOW_DEVELOPMENT_CLERK=1"
    Resolver-->>Auth: honor configured development/custom values
    Auth->>Directory: use configured trusted directory
end
Loading

Reviews (6): Last reviewed commit: "harden(account): unblock re-auth and hon..." | Re-trigger Greptile

arul28 and others added 2 commits July 17, 2026 16:41
A developer project that sets CLERK_ISSUER/CLERK_JWKS_URL/
CLERK_OAUTH_CLIENT_ID (or ADE_ACCOUNT_DIRECTORY_URL) to ADE's
development Clerk instance leaked into the packaged production app's
brain, which then authenticated against dev Clerk and got a 401
"invalid token" from the production account directory.

Packaged builds now set ADE_RUNTIME_PACKAGED=1 (bootstrap.ts via the
existing source-checkout check; desktop main.ts via app.isPackaged).
When set, the account resolvers discard any Clerk override that
resolves to a development instance (*.clerk.accounts.dev, incl.
trailing-dot aliases) or the development account directory — atomically
snapping issuer, JWKS, client, and directory back to the built-in
production defaults (never a hybrid) and logging one warning. The
machine publisher's directory override is guarded the same way.

Source-checkout/dev builds are unchanged; ADE_ALLOW_DEVELOPMENT_CLERK=1
is a deliberate escape hatch. Non-development custom issuer overrides
are still honored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Independent review findings:
- Packaged detection keyed off the module filename (bootstrap.cjs), but
  bootstrap is bundled into main.cjs/cli.cjs, so dev builds running built
  bundles misidentified as packaged and would auth against production
  Clerk. Extract isSourceCheckoutRuntimeModule to runtimePackaging.ts and
  make it directory-based (matches an apps/{ade-cli,desktop}/{src,dist}/
  path segment) — packaged resources have no such segment.
- Route accountMachineDirectoryService's raw ADE_ACCOUNT_DIRECTORY_URL env
  fallback through the dev-directory guard (was a latent bypass).
- Match the development account directory by host, so a dev-host URL with
  an extra path/subdomain is also caught.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Jul 17, 2026 11:24pm

@arul28

arul28 commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@copilot review but do not make fixes

Account-auth hardening: packaged builds ignore development Clerk overrides (*.clerk.accounts.dev) and snap to production defaults atomically. Please probe for hybrid dev/prod configs, any unguarded reader of CLERK_ISSUER/JWKS/CLIENT_ID/ADE_ACCOUNT_DIRECTORY_URL, and packaged-detection edge cases.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change detects packaged runtimes and centralizes development Clerk and account-directory checks. Packaged CLI and desktop flows now use production account services, while non-packaged overrides remain supported. Tests cover runtime detection, configuration precedence, URL trust, authentication, publishing, and machine lifecycle behavior.

Changes

Packaged account configuration

Layer / File(s) Summary
Runtime packaging detection
apps/ade-cli/src/bootstrap.ts, apps/ade-cli/src/runtimePackaging.ts, apps/desktop/src/main/main.ts, apps/ade-cli/src/bootstrap.test.ts
Shared source-checkout detection and startup guards set ADE_RUNTIME_PACKAGED for packaged runtimes.
Shared account configuration enforcement
apps/desktop/src/shared/accountDirectory.ts, apps/ade-cli/src/services/account/sharedAccountAuthService.ts, apps/ade-cli/src/services/account/sharedAccountAuthService.test.ts
Development Clerk identities and directory URLs are detected, warned about, and replaced with production defaults when packaged; non-packaged overrides and escape-hatch behavior are tested.
CLI authentication enforcement
apps/ade-cli/src/services/account/accountAuthService.ts, apps/ade-cli/src/services/account/accountAuthService.test.ts
Packaged authentication rejects development credentials and sessions, normalizes OAuth configuration, protects concurrent session invalidation, and reports device-login failures explicitly.
CLI directory and publisher routing
apps/ade-cli/src/services/account/accountMachineDirectoryService.ts, apps/ade-cli/src/services/account/accountMachinePublisherService.ts, apps/ade-cli/src/services/account/*test.ts
Machine operations and publishing use official hosted directory endpoints when development overrides are ignored, with the publisher snapshot contract updated.
Desktop directory trust integration
apps/desktop/src/main/services/account/accountBridge.ts, apps/desktop/src/main/services/account/accountBridge.trust.test.ts
The desktop bridge uses shared OAuth resolution and ignores packaged development directory overrides while validating trusted issuer and URL forms.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • arul28/ADE#538: Both changes adjust packaged-runtime detection in bootstrap.ts.
  • arul28/ADE#815: Both changes modify CLI account authentication and shared account configuration flows.
  • arul28/ADE#819: Both changes extend account-bridge handling of ADE_ACCOUNT_DIRECTORY_URL.

Suggested labels: desktop, docs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the main change: hardened account handling so packaged builds ignore development Clerk config.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch harden/packaged-clerk-overrides

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
apps/desktop/src/main/services/account/accountBridge.ts (1)

105-118: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove duplicated fallback resolution.

You can eliminate the duplicated multi-line call to resolveOfficialAccountDirectoryBaseUrl by inverting the shouldIgnoreDevelopmentAccountDirectoryUrl condition and falling through to the default return at the bottom of the function.

♻️ Proposed refactor
-  if (machineOverride?.trim()) {
-    if (shouldIgnoreDevelopmentAccountDirectoryUrl(machineOverride, process.env)) {
-      warnDevelopmentClerkIgnored();
-      return resolveOfficialAccountDirectoryBaseUrl({
-        env: process.env,
-        projectRoots: projectRoot ? [projectRoot] : [],
-      });
-    }
-    return parseTrustedAccountDirectoryBaseUrl(machineOverride);
-  }
+  if (machineOverride?.trim()) {
+    if (!shouldIgnoreDevelopmentAccountDirectoryUrl(machineOverride, process.env)) {
+      return parseTrustedAccountDirectoryBaseUrl(machineOverride);
+    }
+    warnDevelopmentClerkIgnored();
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/main/services/account/accountBridge.ts` around lines 105 -
118, Refactor the account directory URL selection around
shouldIgnoreDevelopmentAccountDirectoryUrl so the ignored-development case does
not return an inline resolveOfficialAccountDirectoryBaseUrl call. Invert the
condition to return parseTrustedAccountDirectoryBaseUrl only when the override
is allowed, then let the existing default return handle ignored or missing
overrides without duplicating fallback resolution.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ade-cli/src/bootstrap.ts`:
- Around line 314-319: Make packaged-runtime detection authoritative: in
apps/ade-cli/src/bootstrap.ts, update the logic around
isSourceCheckoutRuntimeModule so ADE_RUNTIME_PACKAGED is set to "1" whenever the
module is classified as packaged, regardless of its existing environment value;
in apps/desktop/src/main/main.ts, set it to "1" whenever app.isPackaged is true.
Preserve ADE_ALLOW_DEVELOPMENT_CLERK=1 as the sole documented override.

In `@apps/ade-cli/src/services/account/sharedAccountAuthService.ts`:
- Around line 79-89: Update the configuration validation around
isClerkDevelopmentIssuer so development OAuth client IDs are rejected
independently of the issuer or JWKS host. When config.clientId is the
development client ID, replace the entire issuer/clientId tuple with the default
ADE values; otherwise preserve the existing configuration and handling for
non-development settings.
- Around line 79-108: Update both enforcement functions in
apps/ade-cli/src/services/account/sharedAccountAuthService.ts (lines 79-108) to
treat DEVELOPMENT_ADE_CLERK_OAUTH_CLIENT_ID as an independent development
configuration, alongside development issuer/JWKS checks. Add packaged OAuth
coverage in apps/ade-cli/src/services/account/sharedAccountAuthService.test.ts
(lines 188-218) using a custom issuer with the development client ID, and
packaged attestation coverage in lines 290-327 using custom issuer/JWKS values
with the development client ID; both cases must enforce packaged defaults.

---

Nitpick comments:
In `@apps/desktop/src/main/services/account/accountBridge.ts`:
- Around line 105-118: Refactor the account directory URL selection around
shouldIgnoreDevelopmentAccountDirectoryUrl so the ignored-development case does
not return an inline resolveOfficialAccountDirectoryBaseUrl call. Invert the
condition to return parseTrustedAccountDirectoryBaseUrl only when the override
is allowed, then let the existing default return handle ignored or missing
overrides without duplicating fallback resolution.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0f2409ce-5c6d-4adc-ac87-624c80b2a457

📥 Commits

Reviewing files that changed from the base of the PR and between 3dbab90 and fc8edb1.

⛔ Files ignored due to path filters (2)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/README.md is excluded by !docs/**
📒 Files selected for processing (13)
  • apps/ade-cli/src/bootstrap.test.ts
  • apps/ade-cli/src/bootstrap.ts
  • apps/ade-cli/src/runtimePackaging.ts
  • apps/ade-cli/src/services/account/accountMachineDirectoryService.test.ts
  • apps/ade-cli/src/services/account/accountMachineDirectoryService.ts
  • apps/ade-cli/src/services/account/accountMachinePublisherService.test.ts
  • apps/ade-cli/src/services/account/accountMachinePublisherService.ts
  • apps/ade-cli/src/services/account/sharedAccountAuthService.test.ts
  • apps/ade-cli/src/services/account/sharedAccountAuthService.ts
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/account/accountBridge.trust.test.ts
  • apps/desktop/src/main/services/account/accountBridge.ts
  • apps/desktop/src/shared/accountDirectory.ts

Comment thread apps/ade-cli/src/bootstrap.ts
Comment thread apps/ade-cli/src/services/account/sharedAccountAuthService.ts
Comment thread apps/ade-cli/src/services/account/sharedAccountAuthService.ts
The packaged-build enforcement discarded dev issuers and dev JWKS hosts
but not the development OAuth client id, so a custom issuer paired with
DEVELOPMENT_ADE_CLERK_OAUTH_CLIENT_ID survived. Treat the dev client id
as an independent development-instance marker in both enforcement
functions, replacing the whole tuple with production defaults. Tests
cover a dev client id behind a custom issuer/JWKS for OAuth and
attestation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@arul28

arul28 commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Pushed f3b37039d: also reject the development OAuth client id (DEVELOPMENT_ADE_CLERK_OAUTH_CLIENT_ID) as an independent development-instance marker in both enforcement functions, so a custom issuer + dev client id can't survive in a packaged build. Tests added for OAuth + attestation. Declined the ADE_RUNTIME_PACKAGED authoritative-detection thread with rationale (the === undefined guard intentionally lets the desktop's app.isPackaged propagate to the child brain; the env-set bypass is within the trust boundary).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3b37039d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/services/account/sharedAccountAuthService.ts
isLoginConfigured() read the raw CLERK_* values, so in a packaged build a
stale partial development secret (issuer or client id only) reported
configured=false and disabled the Account-page sign-in — even though the
hardened resolver would fall back to production and log in fine. Derive
it from the same resolveAccountOAuthConfig() the login flow uses (which
applies the packaged development-Clerk-ignore policy), and drop the now
dead readProjectSecret helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@arul28

arul28 commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Pushed b124efac6: good catch. isLoginConfigured() now derives sign-in availability from the same resolveAccountOAuthConfig() the login flow uses, so the packaged development-Clerk-ignore policy is reflected consistently — a stale partial dev secret no longer disables the sign-in UI when login would succeed against production defaults. Removed the now-dead readProjectSecret helper + unused imports. Desktop typecheck + accountBridge.trust.test.ts (22) green.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b124efac68

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/services/account/sharedAccountAuthService.ts
The config resolvers were hardened, but a stored account.session.v1
created against dev Clerk bypassed them: getAccessToken() returned the
stored dev access token directly and refreshed against the stored dev
oauthConfig, so a packaged build with a pre-existing dev session kept
hitting the production directory with a dev token (401) until manual
sign-out.

In packaged mode (and equally for ADE_ACCOUNT_TOKEN credentials), reject
any session whose stored oauthConfig issuer/client is a development
instance or whose access-token `iss` claim is a dev host, before token
return, refresh, userinfo, or directory use. A persisted dev session is
compare-and-deleted from the shared credential store (only when the
stored value still matches what we read) so status flips to signed-out
without erasing a newer peer-written session, and the user re-signs-in
against production. ADE_ALLOW_DEVELOPMENT_CLERK=1 still keeps dev working;
source checkouts are unchanged. Swept the whole account surface
(getAccessToken, refresh, status, userinfo, env-token, publisher,
directory) for equivalent bypasses.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@arul28

arul28 commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Pushed 48ddd8ee5: closes the stored-session gap and sweeps the whole class. In packaged mode, any session whose stored oauthConfig issuer/client is a dev instance — or whose access-token iss claim is a dev host — is rejected before token return, refresh, userinfo, or directory use, and compare-and-deleted from the shared credential store (only when the stored value still matches what we read, so a newer peer-written session is never clobbered) → status flips to signed-out and the user re-auths against production. Same rejection applied to ADE_ACCOUNT_TOKEN credentials. Escape hatch + source-checkout behavior unchanged. 116 account tests + 22 desktop green; docs updated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ade-cli/src/services/account/accountAuthService.ts`:
- Around line 793-805: The invalidateStoredSessionIfCurrent function must not
use the non-atomic getSync/deleteSync fallback. Require updateSync/CAS for
conditional invalidation; when updateSync is unavailable, reject the session
without deleting any credential. Add coverage for a credential store lacking
updateSync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 55828851-0c67-4c69-9a4a-ee8b11706069

📥 Commits

Reviewing files that changed from the base of the PR and between fc8edb1 and 48ddd8e.

⛔ Files ignored due to path filters (2)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/README.md is excluded by !docs/**
📒 Files selected for processing (11)
  • apps/ade-cli/src/services/account/accountAuthService.test.ts
  • apps/ade-cli/src/services/account/accountAuthService.ts
  • apps/ade-cli/src/services/account/accountMachineDirectoryService.test.ts
  • apps/ade-cli/src/services/account/accountMachineDirectoryService.ts
  • apps/ade-cli/src/services/account/accountMachinePublisherService.test.ts
  • apps/ade-cli/src/services/account/accountMachinePublisherService.ts
  • apps/ade-cli/src/services/account/sharedAccountAuthService.test.ts
  • apps/ade-cli/src/services/account/sharedAccountAuthService.ts
  • apps/desktop/src/main/services/account/accountBridge.trust.test.ts
  • apps/desktop/src/main/services/account/accountBridge.ts
  • apps/desktop/src/shared/accountDirectory.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/ade-cli/src/services/account/accountMachineDirectoryService.test.ts
  • apps/ade-cli/src/services/account/accountMachineDirectoryService.ts
  • apps/ade-cli/src/services/account/accountMachinePublisherService.test.ts
  • apps/ade-cli/src/services/account/sharedAccountAuthService.test.ts
  • apps/desktop/src/shared/accountDirectory.ts
  • apps/desktop/src/main/services/account/accountBridge.trust.test.ts
  • apps/ade-cli/src/services/account/sharedAccountAuthService.ts

Comment thread apps/ade-cli/src/services/account/accountAuthService.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48ddd8ee55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/services/account/accountAuthService.ts Outdated
Two review findings on the stored-session rejection:
- The updateSync-less fallback in invalidateStoredSessionIfCurrent did a
  non-atomic getSync-then-deleteSync, which could delete a production
  credential a peer wrote between the two calls. Drop the non-atomic
  delete: use atomic compare-and-delete when available, otherwise leave
  the value in place and reject the development session on every read.
- A rejected development ADE_ACCOUNT_TOKEN reported source: "env-token"
  with signedIn: false, so downstream treated it as an active env
  credential and blocked production re-auth. Report a fully signed-out
  status (source: null) instead.

Adds coverage for a store without atomic compare-and-delete (rejected,
not clobbered).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@arul28

arul28 commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Pushed ba272fc81 — both valid:

  • invalidateStoredSessionIfCurrent no longer falls back to a non-atomic getSync-then-deleteSync (which could clobber a production credential a peer wrote between the two calls). It uses atomic compare-and-delete when available, otherwise leaves the value in place and rejects the dev session on every read. Added coverage for a store lacking atomic CAS.
  • A rejected development ADE_ACCOUNT_TOKEN now reports a fully signed-out status (source: null, not "env-token") so downstream runs signed-out handling and re-auths against production.
    117 account tests + desktop tsc green.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ba272fc812

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/services/account/accountAuthService.ts Outdated
Comment thread apps/ade-cli/src/services/account/accountAuthService.ts Outdated
Two final review findings on the packaged dev-Clerk policy:
- startLogin()/startDeviceLogin()/createToken() blocked whenever a raw
  ADE_ACCOUNT_TOKEN was present, so after a rejected development token
  correctly reported signed-out, Sign In threw "already providing"
  instead of starting production login. Route every login-gating path
  through readAcceptedEnvCredential(), which treats a rejected
  development credential as absent, so production login proceeds.
- readSession() returned null right after invalidating a development
  session, ignoring the promised retry: when the atomic compare-and-delete
  saw a peer had already replaced it with a production session, that
  record stayed but the read still reported signed-out. Re-read once and
  return the peer-written production session in the same call; only a
  still-rejectable or absent session yields signed-out. Retry at most once.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@arul28

arul28 commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Pushed d6c061a82 — both valid, fixed with a class sweep:

  • Re-auth unblock: startLogin/startDeviceLogin/createToken now gate through readAcceptedEnvCredential() (which treats a rejected dev ADE_ACCOUNT_TOKEN as absent), so production login proceeds instead of throwing 'already providing'. Swept every login-gating site.
  • Post-invalidation retry: readSession() re-reads once after invalidating a dev session and returns a peer-written production session in the same call; a still-rejectable or absent session yields signed-out. Retries at most once (no loop, handles the no-CAS case).
    118 account tests + desktop tsc + webclient build green.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d6c061a826

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/services/account/accountAuthService.ts
@arul28
arul28 merged commit 2cc83ee into main Jul 17, 2026
35 checks passed
@arul28
arul28 deleted the harden/packaged-clerk-overrides branch July 17, 2026 23:44
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