Skip to content

[codex] align server auth Effect services#3180

Merged
juliusmarminge merged 6 commits into
mainfrom
codex/effect-service-server-auth
Jun 20, 2026
Merged

[codex] align server auth Effect services#3180
juliusmarminge merged 6 commits into
mainfrom
codex/effect-service-server-auth

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Jun 20, 2026

Copy link
Copy Markdown
Member

What changed

  • Migrated EnvironmentAuth, EnvironmentAuthPolicy, PairingGrantStore, ServerSecretStore, and SessionStore to the standard single-file Effect service layout.
  • Inlined each service contract into its Context.Service tag and replaced standalone shape references with Service["Service"].
  • Split discriminator-driven auth and persistence failures into concrete Schema.TaggedErrorClass variants; each variant retains useful reason, operation, resource, and cause attributes with a derived message.
  • Exported aggregate Schema.Union(...) schemas, TypeScript unions, and predicates for boundaries that handle a family of related failures.
  • Kept namespace imports scoped to service modules and preserved named imports for contracts, helpers, and layer-only modules.
  • Exported canonical base layer values while keeping persistence/runtime composition explicit.

Why

This aligns server authentication infrastructure with the Effect service conventions used by the relay stack while keeping materially different failures visible in the Effect error channel. Consumers can catch concrete tags or use the exported aggregate predicates without relying on a hidden reason or operation switch.

Impact

Authentication behavior, HTTP mappings, and user-facing error messages are preserved. Error tags are now specific to the actual failure mode; aggregate schemas retain shared validation and predicate surfaces for existing category-level boundaries.

Checks

  • vp test apps/server (149 files: 1,224 passed, 7 skipped)
  • focused auth/cloud/relay tests (9 files, 53 passed)
  • vp check
  • vp run typecheck
  • static audits: no switch-based message getters, no orchestration diff, no new test declarations, no removed comments/docs

Note

Replace generic auth error classes with granular Schema.TaggedErrorClass types across server auth services

  • Replaces single generic error classes (SecretStoreError, SessionCredentialInvalidError, BootstrapCredentialInvalidError, ServerAuthInternalError, etc.) with specific Schema.TaggedErrorClass subtypes in SessionStore, ServerSecretStore, PairingGrantStore, and EnvironmentAuth.
  • Error unions and Schema.is-based type guards replace tag-string catchTags calls throughout HTTP handlers, WebSocket routes, and cloud endpoints.
  • Each service factory is rewritten from Effect.fn to Effect.gen and returns a typed Service.of({...}) instance; layers now pass the factory directly instead of invoking it.
  • Tests updated to assert specific error _tag values (e.g. UnknownBootstrapCredentialError, SecretStorePersistError, MalformedSessionTokenError) rather than generic ones.
  • Behavioral Change: callers that previously matched on a single error tag must now use the exported type guards or match against the union member tags.

Macroscope summarized daba9c6.


Note

High Risk
Large refactor across authentication, sessions, bootstrap pairing, DPoP, secrets, and cloud relay paths; behavior is intended to be preserved but any missed catchIf/tag mapping could change HTTP status or messages.

Overview
Refactors server authentication and secret/session persistence to match the relay-style Effect service layout: contracts live on each Context.Service tag, factories use Effect.gen and Service.of, and layers pass make without invoking it.

Error model: Replaces broad Data.TaggedError types (and reason / message strings) with many Schema.TaggedErrorClass variants in EnvironmentAuth, PairingGrantStore, SessionStore, and ServerSecretStore, plus Schema.Union aggregates and is* predicates. HTTP, WebSocket, DPoP, and cloud handlers switch from catchTags to catchIf with helpers like serverAuthCredentialReason and serverAuthInvalidRequestReason so outward auth reasons stay the same while internal _tag values become specific.

Call-site cleanup: ServerConfig and ServerSecretStore move to namespace imports (ServerConfig.ServerConfig, etc.); desktop uses NodeOS.homedir(). Cloud code uses dedicated internal error classes for link/health/mint JWT failures and setCliDesiredCloudLink instead of a CliState namespace import.

Tests are updated for new error tags (e.g. UnknownBootstrapCredentialError, ServerAuthScopeNotGrantedError, granular secret-store failures).

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

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

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: 0707a8a2-1fef-4e7f-a05b-f63bee7900bb

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 codex/effect-service-server-auth

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

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jun 20, 2026
@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

🚀 Expo continuous deployment is ready!

  • Project → t3-code
  • Platforms → android, ios
  • Scheme → t3code-preview
  🤖 Android 🍎 iOS
Fingerprint fe5a51f2e189da69dfc4c2cd458e6cfb5fdff2ea ae3bd597809dfd7771d0898f735d172973d4c1c8
Build Details Build Permalink
DetailsDistribution: INTERNAL
Build profile: preview:dev
Runtime version: fe5a51f2e189da69dfc4c2cd458e6cfb5fdff2ea
App version: 0.1.0
Git commit: f30c72047f910d3c63edf84887f4c6392d72a650
Build Permalink
DetailsDistribution: INTERNAL
Build profile: preview:dev
Runtime version: ae3bd597809dfd7771d0898f735d172973d4c1c8
App version: 0.1.0
Git commit: b4706aa685da92ae179e34c97839c2a0e9840f09
Update Details Update Permalink
DetailsBranch: pr-3180
Runtime version: fe5a51f2e189da69dfc4c2cd458e6cfb5fdff2ea
Git commit: af9c6aacd6e5ea91a828e1ff071ec2e15865ab4d
Update Permalink
DetailsBranch: pr-3180
Runtime version: ae3bd597809dfd7771d0898f735d172973d4c1c8
Git commit: af9c6aacd6e5ea91a828e1ff071ec2e15865ab4d
Update QR

@juliusmarminge juliusmarminge marked this pull request as ready for review June 20, 2026 02:06
@macroscopeapp

macroscopeapp Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Evaluating daba9c6

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jun 20, 2026
@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch from 23fdab1 to c41882b Compare June 20, 2026 02:30
@macroscopeapp macroscopeapp Bot dismissed their stale review June 20, 2026 02:30

Dismissing prior approval to re-evaluate c41882b

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jun 20, 2026
@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch from c41882b to 427e570 Compare June 20, 2026 03:04
@macroscopeapp macroscopeapp Bot dismissed their stale review June 20, 2026 03:04

Dismissing prior approval to re-evaluate 427e570

@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch from 427e570 to ae3fc49 Compare June 20, 2026 03:22
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jun 20, 2026
@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch from ae3fc49 to eb61976 Compare June 20, 2026 03:50
@macroscopeapp macroscopeapp Bot dismissed their stale review June 20, 2026 03:50

Dismissing prior approval to re-evaluate eb61976

@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jun 20, 2026
@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch 7 times, most recently from bccc051 to 87fac8a Compare June 20, 2026 06:35

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

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 using high effort and found 1 potential issue.

Fix All in Cursor

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

  • ✅ Fixed: Cloud 500 messages regressed
    • Restored operation-specific user-facing messages in ServerAuthOperationError via a lookup table keyed by operation discriminant, so cloud HTTP handlers that pass error.message into 500 response bodies now return the original strings (e.g. 'Could not verify the linked cloud account.') instead of the generic template.

Create PR

Or push these changes by commenting:

@cursor push ccfda8eba9
Preview (ccfda8eba9)
diff --git a/apps/server/src/auth/EnvironmentAuth.ts b/apps/server/src/auth/EnvironmentAuth.ts
--- a/apps/server/src/auth/EnvironmentAuth.ts
+++ b/apps/server/src/auth/EnvironmentAuth.ts
@@ -90,6 +90,28 @@
 ]);
 type ServerAuthInternalOperation = typeof ServerAuthInternalOperation.Type;
 
+const serverAuthOperationMessages: Record<ServerAuthInternalOperation, string> = {
+  validate_bootstrap_credential: "Failed to validate bootstrap credential.",
+  validate_session_credential: "Failed to validate session credential.",
+  issue_authenticated_session: "Failed to issue authenticated session.",
+  issue_authenticated_access_token: "Failed to issue authenticated access token.",
+  create_pairing_link: "Failed to create pairing link.",
+  list_pairing_links: "Failed to list pairing links.",
+  revoke_pairing_link: "Failed to revoke pairing link.",
+  issue_session_token: "Failed to issue session token.",
+  list_sessions: "Failed to list sessions.",
+  revoke_session: "Failed to revoke session.",
+  revoke_other_sessions: "Failed to revoke other sessions.",
+  issue_websocket_token: "Failed to issue websocket token.",
+  record_dpop_replay_state: "Failed to record DPoP proof replay state.",
+  calculate_dpop_replay_key: "Failed to calculate DPoP replay key.",
+  verify_linked_cloud_account: "Could not verify the linked cloud account.",
+  read_linked_cloud_account: "Could not read the linked cloud account.",
+  sign_cloud_link_jwt: "Failed to sign cloud link JWT.",
+  sign_cloud_health_jwt: "Failed to sign cloud health JWT.",
+  sign_cloud_mint_jwt: "Failed to sign cloud mint JWT.",
+};
+
 export class ServerAuthOperationError extends Schema.TaggedErrorClass<ServerAuthOperationError>()(
   "ServerAuthOperationError",
   {
@@ -98,7 +120,7 @@
   },
 ) {
   override get message(): string {
-    return `Server authentication operation '${this.operation}' failed.`;
+    return serverAuthOperationMessages[this.operation];
   }
 }

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

Reviewed by Cursor Bugbot for commit 87fac8a. Configure here.

Comment thread apps/server/src/cloud/http.ts
@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch 4 times, most recently from 39fd49a to 896dfbe Compare June 20, 2026 07:11
@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch from 896dfbe to d898014 Compare June 20, 2026 07:19
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jun 20, 2026
@macroscopeapp macroscopeapp Bot dismissed their stale review June 20, 2026 07:27

Dismissing prior approval to re-evaluate 7a0aa36

@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch 2 times, most recently from 3a2857e to 763ecaa Compare June 20, 2026 07:45
juliusmarminge and others added 6 commits June 20, 2026 01:30
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge juliusmarminge force-pushed the codex/effect-service-server-auth branch from 763ecaa to daba9c6 Compare June 20, 2026 08:31
@juliusmarminge juliusmarminge merged commit 97e5cd3 into main Jun 20, 2026
16 checks passed
@juliusmarminge juliusmarminge deleted the codex/effect-service-server-auth branch June 20, 2026 08:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ 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.

1 participant