Skip to content

Harden secret store and resolve catalog overrides#1891

Merged
juliusmarminge merged 2 commits intomainfrom
t3code/secret-redaction-fix
Apr 10, 2026
Merged

Harden secret store and resolve catalog overrides#1891
juliusmarminge merged 2 commits intomainfrom
t3code/secret-redaction-fix

Conversation

@juliusmarminge
Copy link
Copy Markdown
Member

@juliusmarminge juliusmarminge commented Apr 10, 2026

Closes #1887

Summary

  • harden server secret store error handling so missing files and already-existing secrets are handled explicitly
  • resolve root-level catalog overrides into the published server package metadata
  • remove redundant instanceof checks from the non-Claude typed error paths touched by this PR

Testing

  • bun fmt
  • bun lint
  • bun typecheck
  • bun run test

Note

Medium Risk
Touches secret storage and several error-mapping paths; while mostly defensive/error-message changes, regressions could affect secret reads/writes and provider/bootstrap resiliency.

Overview
Publishing now includes workspace overrides. The server publish CLI writes a temporary package.json that resolves both dependencies and root-level overrides from the workspace catalog, with tighter typing around the generated metadata.

Error handling is standardized and more informative. The server secret store tightens concurrent/missing-file handling using tagged PlatformError detection; several layers (GitHubCli, GitCore, CodexAdapter/CodexProvider, terminal manager, workspace entries, websocket bootstrap logging) simplify instanceof branches and improve propagated error detail/log payloads. On the web side, BootstrapHttpError becomes an effect Data.TaggedError and transient-retry detection switches to tag-based predicates.

Dependency/catalog typing is tightened. resolveCatalogDependencies (and callers like desktop artifact build) now operate on Record<string, string> instead of unknown.

Reviewed by Cursor Bugbot for commit 83abc76. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Harden secret store error handling and resolve catalog overrides in publish flow

  • Fixes ServerSecretStore error handling to branch on cause.reason._tag directly instead of using removed isMissingSecretFileError/isAlreadyExistsSecretFileError helpers, using Predicate.isTagged for PlatformError detection.
  • Extends the publishCmd handler in cli.ts to write a resolved overrides field (from the root workspace catalog) alongside dependencies in the temporary package.json used for npm publish.
  • Replaces instanceof-based BootstrapHttpError with a Data.TaggedError and Predicate.isTagged guard across auth.ts and context.ts.
  • Standardizes error detail construction across multiple adapters and layers to use error.message directly rather than String(error) fallbacks.
  • Tightens resolveCatalogDependencies parameter and return types from Record<string, unknown> to Record<string, string>.

Macroscope summarized 83abc76.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1cd199fe-490f-49a6-96ad-e205d1c3bf25

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t3code/secret-redaction-fix

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

@github-actions github-actions bot added size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Apr 10, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Missing type guard in get causes unsafe property access
    • Added the missing isPlatformError(cause) guard before accessing cause.reason._tag in the get method, consistent with the guards used in remove and getOrCreateRandom.

Create PR

Or push these changes by commenting:

@cursor push a0aa6a4824
Preview (a0aa6a4824)
diff --git a/apps/server/src/auth/Layers/ServerSecretStore.ts b/apps/server/src/auth/Layers/ServerSecretStore.ts
--- a/apps/server/src/auth/Layers/ServerSecretStore.ts
+++ b/apps/server/src/auth/Layers/ServerSecretStore.ts
@@ -35,7 +35,7 @@
     fileSystem.readFile(resolveSecretPath(name)).pipe(
       Effect.map((bytes) => Uint8Array.from(bytes)),
       Effect.catch((cause) =>
-        cause.reason._tag === "NotFound"
+        isPlatformError(cause) && cause.reason._tag === "NotFound"
           ? Effect.succeed(null)
           : Effect.fail(
               new SecretStoreError({

You can send follow-ups to the cloud agent here.

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 10, 2026

Approvability

Verdict: Approved

This is a type-hardening and refactoring PR that improves type safety (narrowing unknown to string, using Effect's Predicate utilities) and standardizes error class definitions across multiple files. The changes are mechanical with no runtime behavioral changes, and the author wrote the original code being modified.

You can customize Macroscope's approvability policy. Learn more.

@github-actions github-actions bot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Apr 10, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Potentially incorrect isPlatformError tag check breaks race handling
    • Replaced Predicate.isTagged(u, "PlatformError") (which checks _tag === "PlatformError" — a value neither BadArgument nor SystemError carries) with instanceof PlatformError.PlatformError, consistent with the existing check in the remove function.

Create PR

Or push these changes by commenting:

@cursor push e2bb5af8e5
Preview (e2bb5af8e5)
diff --git a/apps/server/src/auth/Layers/ServerSecretStore.ts b/apps/server/src/auth/Layers/ServerSecretStore.ts
--- a/apps/server/src/auth/Layers/ServerSecretStore.ts
+++ b/apps/server/src/auth/Layers/ServerSecretStore.ts
@@ -1,6 +1,6 @@
 import * as Crypto from "node:crypto";
 
-import { Effect, FileSystem, Layer, Path, Predicate } from "effect";
+import { Effect, FileSystem, Layer, Path } from "effect";
 import * as PlatformError from "effect/PlatformError";
 
 import { ServerConfig } from "../../config.ts";
@@ -28,9 +28,6 @@
 
   const resolveSecretPath = (name: string) => path.join(serverConfig.secretsDir, `${name}.bin`);
 
-  const isPlatformError = (u: unknown): u is PlatformError.PlatformError =>
-    Predicate.isTagged(u, "PlatformError");
-
   const get: ServerSecretStoreShape["get"] = (name) =>
     fileSystem.readFile(resolveSecretPath(name)).pipe(
       Effect.map((bytes) => Uint8Array.from(bytes)),
@@ -105,7 +102,8 @@
         return create(name, generated).pipe(
           Effect.as(Uint8Array.from(generated)),
           Effect.catchTag("SecretStoreError", (error) =>
-            isPlatformError(error.cause) && error.cause.reason._tag === "AlreadyExists"
+            error.cause instanceof PlatformError.PlatformError &&
+            error.cause.reason._tag === "AlreadyExists"
               ? get(name).pipe(
                   Effect.flatMap((created) =>
                     created !== null

You can send follow-ups to the cloud agent here.

Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Inconsistent instanceof check in remove vs rest of file
    • Replaced cause instanceof PlatformError.PlatformError with isPlatformError(cause) in the remove method to match the pattern used in getOrCreateRandom and avoid instanceof fragility across module boundaries.

Create PR

Or push these changes by commenting:

@cursor push d9c794b0ad
Preview (d9c794b0ad)
diff --git a/apps/server/src/auth/Layers/ServerSecretStore.ts b/apps/server/src/auth/Layers/ServerSecretStore.ts
--- a/apps/server/src/auth/Layers/ServerSecretStore.ts
+++ b/apps/server/src/auth/Layers/ServerSecretStore.ts
@@ -126,7 +126,7 @@
   const remove: ServerSecretStoreShape["remove"] = (name) =>
     fileSystem.remove(resolveSecretPath(name)).pipe(
       Effect.catch((cause) =>
-        cause instanceof PlatformError.PlatformError && cause.reason._tag === "NotFound"
+        isPlatformError(cause) && cause.reason._tag === "NotFound"
           ? Effect.void
           : Effect.fail(
               new SecretStoreError({

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit e016fe7. Configure here.

- harden server secret store file handling and publish-time catalog resolution
- tighten desktop artifact typing
- remove redundant instanceof checks from shared provider and runtime paths

Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge juliusmarminge enabled auto-merge (squash) April 10, 2026 20:07
@juliusmarminge juliusmarminge disabled auto-merge April 10, 2026 20:09
@juliusmarminge juliusmarminge merged commit e3004ae into main Apr 10, 2026
12 checks passed
@juliusmarminge juliusmarminge deleted the t3code/secret-redaction-fix branch April 10, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: SecretStoreError: Failed to read secret server-signing-key (username should be redacted)

1 participant